"use client";
import {
  useState,
  useEffect,
  useRef,
  useCallback,
} from "react";
import { useRouter } from "next/navigation";
import {
  StreamVideoClient,
  StreamVideo,
  StreamCall,
  useCallStateHooks,
  useCall,
} from "@stream-io/video-react-sdk";
import {
  Mic,
  MicOff,
  Video,
  VideoOff,
  RotateCcw,
  X,
  Send,
  Heart,
  Eye,
  Gift,
  Loader2,
} from "lucide-react";
import { AnimatePresence, motion } from "framer-motion";
import { useAppSelector } from "@/store/hooks";
import { useGeneralSettings } from "@/lib/GeneralSettingsContext";
import { useTranslation } from "@/i18n";
import { GiftSheet } from "./GiftSheet";
import type { ChatMessage, FloatingHeart, GiftAnimation, Gift as GiftType } from "@/types/live";

/* ── helpers ──────────────────────────────────────────────────────────────── */

function kFormat(n: number): string {
  if (n >= 1_000_000) return (n / 1_000_000).toFixed(1) + "M";
  if (n >= 1_000) return (n / 1_000).toFixed(1) + "K";
  return String(n);
}

/* ── Video renderer — renders a MediaStream into a <video> ────────────────── */
function VideoRenderer({ isHost }: { isHost: boolean }) {
  const videoRef = useRef<HTMLVideoElement>(null);
  const audioRef = useRef<HTMLAudioElement>(null);
  const { useParticipants, useLocalParticipant } = useCallStateHooks();
  const participants = useParticipants();
  const localParticipant = useLocalParticipant();

  const target = isHost
    ? localParticipant
    : participants.find((p) => !p.isLocalParticipant);

  useEffect(() => {
    if (!videoRef.current) return;
    const stream = target?.videoStream ?? null;
    videoRef.current.srcObject = stream;
    if (stream) videoRef.current.play().catch(() => {});
  }, [target?.videoStream]);

  useEffect(() => {
    if (!audioRef.current || !target?.audioStream) return;
    audioRef.current.srcObject = target.audioStream;
    audioRef.current.play().catch(() => {});
  }, [target?.audioStream]);

  if (!target) {
    return (
      <div className="absolute inset-0 flex items-center justify-center" style={{ background: "#0a0a0a" }}>
        <div className="flex flex-col items-center gap-3">
          <Loader2 size={32} className="animate-spin" style={{ color: "rgba(255,255,255,0.4)" }} />
          <p className="text-sm font-medium" style={{ color: "rgba(255,255,255,0.5)" }}>
            Waiting for stream…
          </p>
        </div>
      </div>
    );
  }

  return (
    <>
      <video
        ref={videoRef}
        autoPlay
        playsInline
        muted={isHost}
        className="absolute inset-0 w-full h-full object-cover"
      />
      {!isHost && (
        <audio ref={audioRef} autoPlay playsInline />
      )}
    </>
  );
}

/* ── Inner UI — mounted inside StreamCall context ─────────────────────────── */
interface InnerProps {
  isHost: boolean;
  hostChannelId: string;
  onExit: () => void;
}

function LiveRoomInner({ isHost, hostChannelId, onExit }: InnerProps) {
  const call = useCall();
  const { useParticipants, useLocalParticipant, useMicrophoneState, useCameraState } =
    useCallStateHooks();
  const participants = useParticipants();
  const localParticipant = useLocalParticipant();
  const { microphone } = useMicrophoneState();
  const { camera } = useCameraState();
  const isMicOn = localParticipant?.publishedTracks?.includes(1) ?? true;
  const isCamOn = localParticipant?.publishedTracks?.includes(2) ?? true;
  const viewerCount = isHost
    ? participants.filter((p) => !p.isLocalParticipant).length
    : participants.length - 1;

  const [chatMessages, setChatMessages] = useState<ChatMessage[]>([]);
  const [hearts, setHearts] = useState<FloatingHeart[]>([]);
  const [giftAnims, setGiftAnims] = useState<GiftAnimation[]>([]);
  const [chatInput, setChatInput] = useState("");
  const [showGiftSheet, setShowGiftSheet] = useState(false);
  const [showExitDialog, setShowExitDialog] = useState(false);
  const [isStreamEnded, setIsStreamEnded] = useState(false);
  const chatEndRef = useRef<HTMLDivElement>(null);
  const chatInputRef = useRef<HTMLInputElement>(null);
  const router = useRouter();
  const { t } = useTranslation();
  const user = useAppSelector((s) => s.auth.user);
  const idCounter = useRef(0);
  const nextId = () => String(++idCounter.current);

  /* ── Custom event listener ───────────────────────────────────────────────── */
  useEffect(() => {
    if (!call) return;

    const unsub = call.on("custom", (event: any) => {
      const data = event.custom ?? {};
      if (data.type === "heart") {
        addHeart();
      } else if (data.type === "chat") {
        const myName = user?.channel_name || user?.full_name || "";
        if (data.name !== myName && data.text) {
          addMessage(data.name, data.text);
        }
      } else if (data.type === "gift") {
        const myName = user?.channel_name || user?.full_name || "";
        if (data.senderName !== myName) {
          addGiftAnim(data.senderName, data.giftName, data.giftImg);
        }
      }
    });

    return () => unsub();
  }, [call, user]);

  /* ── Stream ended detection (viewer) ────────────────────────────────────── */
  useEffect(() => {
    if (!call || isHost) return;

    const unsub = call.on("call.ended", () => {
      if (!isStreamEnded) {
        setIsStreamEnded(true);
        setTimeout(() => router.replace("/live"), 100);
      }
    });

    return () => unsub();
  }, [call, isHost, isStreamEnded, router]);

  /* ── Chat scroll ──────────────────────────────────────────────────────── */
  useEffect(() => {
    chatEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [chatMessages]);

  /* ── Helpers ─────────────────────────────────────────────────────────── */
  const addMessage = useCallback((name: string, text: string) => {
    setChatMessages((prev) => {
      const updated = [{ id: nextId(), name, text }, ...prev];
      return updated.slice(0, 30);
    });
  }, []);

  const addHeart = useCallback(() => {
    const id = nextId();
    const x = Math.random() * 60 + 10;
    setHearts((prev) => [...prev, { id, x }]);
    setTimeout(() => setHearts((prev) => prev.filter((h) => h.id !== id)), 3200);
  }, []);

  const addGiftAnim = useCallback((senderName: string, giftName: string, giftImage: string) => {
    const id = nextId();
    setGiftAnims((prev) => [...prev, { id, senderName, giftName, giftImage }]);
    setTimeout(() => setGiftAnims((prev) => prev.filter((g) => g.id !== id)), 4500);
  }, []);

  /* ── Actions ──────────────────────────────────────────────────────────── */
  const sendMessage = useCallback(() => {
    const text = chatInput.trim();
    if (!text || !call) return;
    const name = user?.channel_name || user?.full_name || "User";
    call.sendCustomEvent({ type: "chat", text, name });
    addMessage(name, text);
    setChatInput("");
    chatInputRef.current?.blur();
  }, [chatInput, call, user, addMessage]);

  const sendHeart = useCallback(() => {
    call?.sendCustomEvent({ type: "heart" });
    addHeart();
  }, [call, addHeart]);

  const handleGiftSent = useCallback((gift: GiftType) => {
    const name = user?.channel_name || user?.full_name || "User";
    call?.sendCustomEvent({
      type: "gift",
      senderName: name,
      giftName: gift.name,
      giftImg: gift.image,
    });
    addGiftAnim(name, gift.name, gift.image);
    setShowGiftSheet(false);
  }, [call, user, addGiftAnim]);

  const handleExit = useCallback(() => {
    if (isHost) {
      setShowExitDialog(true);
    } else {
      call?.leave();
      onExit();
    }
  }, [isHost, call, onExit]);

  const handleStopStream = useCallback(async () => {
    if (call) {
      await call.endCall().catch(() => {});
      await call.leave().catch(() => {});
    }
    onExit();
  }, [call, onExit]);

  return (
    <div className="fixed inset-0 bg-black overflow-hidden" style={{ zIndex: 600 }}>
      {/* ── Full-screen video ─────────────────────────────────────────────── */}
      <VideoRenderer isHost={isHost} />

      {/* ── Subtle vignette overlay ──────────────────────────────────────── */}
      <div
        className="absolute inset-0 pointer-events-none"
        style={{
          background:
            "radial-gradient(ellipse at center, transparent 40%, rgba(0,0,0,0.65) 100%)",
        }}
      />

      {/* ── Top bar ──────────────────────────────────────────────────────── */}
      <div className="absolute top-0 left-0 right-0 flex items-start justify-between px-4 pt-safe-top pt-4 z-10">
        {/* Left: LIVE badge + viewer count */}
        <div className="flex items-center gap-2">
          <div
            className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg"
            style={{ background: "rgba(220,38,38,0.9)", backdropFilter: "blur(8px)" }}
          >
            <span
              className="inline-block w-1.5 h-1.5 rounded-full bg-white"
              style={{ animation: "livePulse 1.2s ease-in-out infinite" }}
            />
            <span className="text-white text-xs font-black uppercase tracking-widest">Live</span>
          </div>
          <div
            className="flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg"
            style={{ background: "rgba(0,0,0,0.6)", backdropFilter: "blur(8px)" }}
          >
            <Eye size={12} color="white" />
            <span className="text-white text-xs font-bold">{kFormat(Math.max(0, viewerCount))}</span>
          </div>
        </div>

        {/* Right: host controls + close */}
        <div className="flex flex-col items-end gap-2">
          {/* Close button */}
          <button
            onClick={handleExit}
            className="w-9 h-9 rounded-full flex items-center justify-center"
            style={{ background: "rgba(0,0,0,0.55)", backdropFilter: "blur(8px)" }}
          >
            <X size={18} color="white" />
          </button>

          {/* Host-only controls */}
          {isHost && (
            <div className="flex flex-col gap-2">
              <button
                onClick={() => microphone?.toggle()}
                className="w-9 h-9 rounded-full flex items-center justify-center"
                style={{
                  background: isMicOn ? "rgba(0,0,0,0.55)" : "rgba(220,38,38,0.8)",
                  backdropFilter: "blur(8px)",
                }}
              >
                {isMicOn ? <Mic size={16} color="white" /> : <MicOff size={16} color="white" />}
              </button>
              <button
                onClick={() => camera?.toggle()}
                className="w-9 h-9 rounded-full flex items-center justify-center"
                style={{
                  background: isCamOn ? "rgba(0,0,0,0.55)" : "rgba(220,38,38,0.8)",
                  backdropFilter: "blur(8px)",
                }}
              >
                {isCamOn ? <Video size={16} color="white" /> : <VideoOff size={16} color="white" />}
              </button>
              <button
                onClick={() => camera?.flip()}
                className="w-9 h-9 rounded-full flex items-center justify-center"
                style={{ background: "rgba(0,0,0,0.55)", backdropFilter: "blur(8px)" }}
              >
                <RotateCcw size={16} color="white" />
              </button>
            </div>
          )}
        </div>
      </div>

      {/* ── Floating hearts ──────────────────────────────────────────────── */}
      {hearts.map((h) => (
        <div
          key={h.id}
          className="absolute pointer-events-none"
          style={{
            right: `${h.x}px`,
            bottom: 110,
            animation: "heartFloat 3s ease-out forwards",
          }}
        >
          <Heart size={28} fill="#f43f5e" color="#f43f5e" />
        </div>
      ))}

      {/* ── Gift animations ──────────────────────────────────────────────── */}
      {giftAnims.map((g) => (
        <div
          key={g.id}
          className="absolute left-1/2 -translate-x-1/2 flex flex-col items-center gap-2 pointer-events-none"
          style={{
            top: "35%",
            animation: "giftFloat 4s ease-in-out forwards",
          }}
        >
          {/* eslint-disable-next-line @next/next/no-img-element */}
          <img src={g.giftImage} alt={g.giftName} className="w-24 h-24 object-contain drop-shadow-2xl" />
          <div
            className="px-3 py-1 rounded-full text-xs font-bold text-white"
            style={{ background: "rgba(0,0,0,0.7)", backdropFilter: "blur(8px)" }}
          >
            {g.senderName} sent {g.giftName}
          </div>
        </div>
      ))}

      {/* ── Bottom section: chat + controls ─────────────────────────────── */}
      <div className="absolute bottom-0 left-0 right-0 pb-safe-bottom pb-6 px-4 flex flex-col gap-3">
        {/* Chat messages — 75% width, fade gradient at top */}
        <div
          className="w-3/4 overflow-hidden"
          style={{ maxHeight: 180, maskImage: "linear-gradient(to bottom, transparent, black 25%)" }}
        >
          <div className="flex flex-col-reverse gap-1 max-h-[180px] overflow-hidden">
            {chatMessages.map((msg) => (
              <div key={msg.id} className="flex items-start gap-1.5 py-0.5">
                <span
                  className="text-xs font-bold whitespace-nowrap"
                  style={{ color: "var(--accent)", textShadow: "0 1px 4px rgba(0,0,0,0.8)" }}
                >
                  {msg.name}:
                </span>
                <span
                  className="text-xs flex-1 leading-tight"
                  style={{ color: "rgba(255,255,255,0.95)", textShadow: "0 1px 4px rgba(0,0,0,0.8)" }}
                >
                  {msg.text}
                </span>
              </div>
            ))}
            <div ref={chatEndRef} />
          </div>
        </div>

        {/* Input row */}
        <div className="flex items-center gap-3">
          {/* Comment input */}
          <div
            className="flex-1 flex items-center rounded-full overflow-hidden"
            style={{
              background: "rgba(0,0,0,0.55)",
              backdropFilter: "blur(12px)",
              border: "1px solid rgba(255,255,255,0.15)",
              height: 44,
            }}
          >
            <input
              ref={chatInputRef}
              value={chatInput}
              onChange={(e) => setChatInput(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && sendMessage()}
              placeholder={t("live_addComment")}
              className="flex-1 bg-transparent text-white text-sm px-4 outline-none placeholder:text-white/50"
            />
            <button
              onClick={sendMessage}
              disabled={!chatInput.trim()}
              className="w-10 h-10 flex items-center justify-center shrink-0 disabled:opacity-40"
            >
              <Send size={16} color="white" />
            </button>
          </div>

          {/* Heart button */}
          <button
            onClick={sendHeart}
            className="w-11 h-11 rounded-full flex items-center justify-center transition-transform active:scale-90"
            style={{
              background: "rgba(0,0,0,0.55)",
              backdropFilter: "blur(8px)",
              border: "1px solid rgba(255,255,255,0.15)",
            }}
          >
            <Heart size={20} color="white" />
          </button>

          {/* Gift button */}
          <button
            onClick={() => setShowGiftSheet(true)}
            className="w-11 h-11 rounded-full flex items-center justify-center transition-transform active:scale-90"
            style={{
              background: "rgba(var(--accent-rgb),0.85)",
              backdropFilter: "blur(8px)",
            }}
          >
            <Gift size={20} color="white" />
          </button>
        </div>
      </div>

      {/* ── Exit confirmation dialog ─────────────────────────────────────── */}
      <AnimatePresence>
        {showExitDialog && (
          <>
            <motion.div
              className="fixed inset-0 z-[700]"
              style={{ background: "rgba(0,0,0,0.7)", backdropFilter: "blur(8px)" }}
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
            />
            <motion.div
              className="fixed z-[701] left-1/2 top-1/2 w-[min(300px,85vw)] rounded-3xl p-6 flex flex-col items-center gap-4"
              style={{ background: "var(--card)", border: "1px solid var(--border)" }}
              initial={{ opacity: 0, scale: 0.85, y: 20, x: "-50%", translateY: "-50%" }}
              animate={{ opacity: 1, scale: 1, y: 0, x: "-50%", translateY: "-50%" }}
              exit={{ opacity: 0, scale: 0.92, y: 10, x: "-50%", translateY: "-50%" }}
              transition={{ type: "spring", stiffness: 380, damping: 28 }}
            >
              <div
                className="w-16 h-16 rounded-full flex items-center justify-center"
                style={{ background: "rgba(220,38,38,0.12)", border: "2px solid rgba(220,38,38,0.25)" }}
              >
                <Video size={28} color="#dc2626" />
              </div>
              <div className="text-center">
                <p className="text-base font-black mb-1" style={{ color: "var(--text-primary)" }}>
                  {t("live_stopLiveTitle")}
                </p>
                <p className="text-xs leading-relaxed" style={{ color: "var(--text-muted)" }}>
                  {t("live_stopLiveDesc")}
                </p>
              </div>
              <div className="w-full flex flex-col gap-2.5">
                <button
                  onClick={handleStopStream}
                  className="h-11 rounded-2xl text-sm font-black text-white transition-all active:scale-95"
                  style={{ background: "linear-gradient(135deg, #dc2626, #b91c1c)" }}
                >
                  {t("live_stopStream")}
                </button>
                <button
                  onClick={() => setShowExitDialog(false)}
                  className="h-11 rounded-2xl text-sm font-semibold transition-all active:scale-95"
                  style={{ background: "var(--deep)", color: "var(--text-muted)", border: "1px solid var(--border)" }}
                >
                  {t("live_cancel")}
                </button>
              </div>
            </motion.div>
          </>
        )}
      </AnimatePresence>

      {/* ── Gift sheet ───────────────────────────────────────────────────── */}
      <GiftSheet
        isOpen={showGiftSheet}
        onClose={() => setShowGiftSheet(false)}
        userId={user?.id ?? 0}
        walletBalance={user?.wallet_balance ?? 0}
        hostChannelId={hostChannelId}
        onGiftSent={handleGiftSent}
      />

      {/* ── CSS animations ──────────────────────────────────────────────── */}
      <style>{`
        @keyframes livePulse {
          0%, 100% { opacity: 1; transform: scale(1); }
          50% { opacity: 0.35; transform: scale(0.7); }
        }
        @keyframes heartFloat {
          0% { transform: translateY(0) scale(1); opacity: 1; }
          80% { opacity: 0.6; }
          100% { transform: translateY(-220px) scale(1.6); opacity: 0; }
        }
        @keyframes giftFloat {
          0% { transform: translateX(-50%) translateY(30px); opacity: 0; }
          15% { opacity: 1; }
          75% { opacity: 1; }
          100% { transform: translateX(-50%) translateY(-70px); opacity: 0; }
        }
      `}</style>
    </div>
  );
}

/* ── Outer component — manages Stream SDK lifecycle ───────────────────────── */
export interface LiveRoomPageProps {
  callId: string;
  isHost: boolean;
  hostChannelId?: string;
}

export function LiveRoomPage({ callId, isHost, hostChannelId = "" }: LiveRoomPageProps) {
  const [client, setClient] = useState<StreamVideoClient | null>(null);
  const [call, setCall] = useState<ReturnType<StreamVideoClient["call"]> | null>(null);
  const [isConnecting, setIsConnecting] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const router = useRouter();
  const { settings } = useGeneralSettings();
  const user = useAppSelector((s) => s.auth.user);
  const { t } = useTranslation();

  useEffect(() => {
    if (!settings?.streamApiKey || !user?.stream_token || !user?.id) {
      setError("Stream not configured. Please try again.");
      setIsConnecting(false);
      return;
    }

    let streamClient: StreamVideoClient | null = null;
    let streamCall: ReturnType<StreamVideoClient["call"]> | null = null;

    const setup = async () => {
      setIsConnecting(true);
      try {
        streamClient = new StreamVideoClient({
          apiKey: settings.streamApiKey,
          user: {
            id: String(user.id),
            name: user.channel_name || user.full_name,
            image: user.image,
          },
          token: user.stream_token,
        });

        streamCall = streamClient.call("livestream", callId);

        if (isHost) {
          await streamCall.getOrCreate();
          await streamCall.join({ create: true });
          await streamCall.goLive();
        } else {
          await streamCall.join();
        }

        setClient(streamClient);
        setCall(streamCall);
      } catch (err) {
        console.error("Failed to join stream", err);
        setError("Failed to connect to the live stream. Please try again.");
      } finally {
        setIsConnecting(false);
      }
    };

    setup();

    return () => {
      const cleanup = async () => {
        try {
          if (streamCall) {
            if (isHost) {
              await streamCall.endCall().catch(() => {});
            }
            await streamCall.leave().catch(() => {});
          }
          if (streamClient) {
            await streamClient.disconnectUser().catch(() => {});
          }
        } catch (e) {
          // ignore cleanup errors
        }
      };
      cleanup();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const handleExit = useCallback(() => {
    router.replace("/live");
  }, [router]);

  /* ── Loading screen ──────────────────────────────────────────────────── */
  if (isConnecting) {
    return (
      <div className="fixed inset-0 bg-black flex flex-col items-center justify-center gap-4" style={{ zIndex: 600 }}>
        <Loader2 size={36} className="animate-spin text-white/40" />
        <p className="text-white/50 text-sm font-medium">
          {isHost ? t("live_goingLive") : t("live_joining")}
        </p>
      </div>
    );
  }

  /* ── Error screen ────────────────────────────────────────────────────── */
  if (error || !client || !call) {
    return (
      <div className="fixed inset-0 bg-black flex flex-col items-center justify-center gap-5" style={{ zIndex: 600 }}>
        <div className="text-5xl">📡</div>
        <p className="text-white/60 text-sm text-center max-w-xs">
          {error ?? "Connection failed. Please try again."}
        </p>
        <button
          onClick={() => router.replace("/live")}
          className="px-5 py-2.5 rounded-xl text-sm font-bold text-white"
          style={{ background: "rgba(var(--accent-rgb),0.8)" }}
        >
          {t("live_backToLive")}
        </button>
      </div>
    );
  }

  return (
    <StreamVideo client={client}>
      <StreamCall call={call}>
        <LiveRoomInner isHost={isHost} hostChannelId={hostChannelId} onExit={handleExit} />
      </StreamCall>
    </StreamVideo>
  );
}
