"use client";

import { useSession } from "next-auth/react";
import { useParams, useRouter } from "next/navigation";
import { useState, useEffect, useRef, useCallback } from "react";
import { LowBalancePopup } from "@/components/shared/low-balance-popup";
import { useToastStore } from "@/lib/stores/toast-store";
import TipAnimation from "@/components/shared/tip-animation";
import {
  useStreamOverlays,
  StreamOverlayLayer,
  StreamOverlayControls,
} from "@/components/livecam/stream-overlays";

interface SessionData {
  session_id: number;
  mode: string;
  free_max_minutes: number;
  group_rate: number;
  private_rate: number;
  username: string;
  viewer_count: number;
}

export default function WatchRoomPage() {
  const { data: session, status } = useSession();
  const params = useParams();
  const router = useRouter();
  const broadcasterId = params.id as string;

  const [loading, setLoading] = useState(true);
  const [sessionData, setSessionData] = useState<SessionData | null>(null);
  const [viewerMode, setViewerMode] = useState<"free" | "group" | "private">("free");
  const [downgradedNotice, setDowngradedNotice] = useState<string | null>(null);
  const [freeCountdown, setFreeCountdown] = useState(0);
  const [creditBalance, setCreditBalance] = useState(0);
  const [messages, setMessages] = useState<{ user: string; text: string }[]>([]);
  const [chatInput, setChatInput] = useState("");
  const [error, setError] = useState("");
  const [joined, setJoined] = useState(false);
  const [tipTrigger, setTipTrigger] = useState(false);
  const [tipAmount, setTipAmount] = useState(0);

  const countdownRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const debitRef = useRef<ReturnType<typeof setInterval> | null>(null);

  // Stream overlays (tip goals, polls, timers)
  const {
    activeOverlays,
    userId: overlayUserId,
    handleVote,
    fetchOverlays: refreshOverlays,
  } = useStreamOverlays(sessionData?.session_id);

  // Load session data
  const loadSession = useCallback(async () => {
    try {
      const res = await fetch(`/api/livecam/settings`);
      // We need to fetch the broadcaster's settings - use a different approach
      // Fetch from the browse data
      const browseRes = await fetch(`/api/livecam/session?broadcaster_id=${broadcasterId}`);
      if (browseRes.ok) {
        const json = await browseRes.json();
        if (json.data) {
          setSessionData(json.data);
          setFreeCountdown(json.data.free_max_minutes * 60);
        }
      }
    } catch {
      setError("Failed to load stream data");
    } finally {
      setLoading(false);
    }
  }, [broadcasterId]);

  // Load credits
  const loadCredits = useCallback(async () => {
    try {
      const res = await fetch("/api/credits");
      if (res.ok) {
        const json = await res.json();
        setCreditBalance(json.credits || 0);
      }
    } catch {
      // Ignore
    }
  }, []);

  useEffect(() => {
    loadSession();
    if (status === "authenticated") {
      loadCredits();
    }
  }, [loadSession, loadCredits, status]);

  // Free countdown timer
  useEffect(() => {
    if (joined && viewerMode === "free" && freeCountdown > 0) {
      countdownRef.current = setInterval(() => {
        setFreeCountdown((prev) => {
          if (prev <= 1) {
            if (countdownRef.current) clearInterval(countdownRef.current);
            return 0;
          }
          return prev - 1;
        });
      }, 1000);
    }
    return () => {
      if (countdownRef.current) clearInterval(countdownRef.current);
    };
  }, [joined, viewerMode, freeCountdown]);

  // Debit timer for paid modes
  useEffect(() => {
    if (joined && viewerMode !== "free" && sessionData) {
      debitRef.current = setInterval(async () => {
        try {
          // viewer_id intentionally omitted — server derives from session
          // (Round-7 hotfix closed the cross-user-debit hole).
          const res = await fetch("/api/livecam/debit", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              session_id: sessionData.session_id,
            }),
          });
          const json = await res.json();
          if (json.remaining_credits !== undefined) {
            setCreditBalance(json.remaining_credits);
          }
          if (!json.success) {
            // Surface the auto-downgrade to the user instead of silently
            // moving them to free mode without explanation.
            setDowngradedNotice("You've been moved to free mode — buy credits to continue paid viewing.");
            setViewerMode("free");
          }
        } catch {
          // Ignore
        }
      }, 60000);
    }
    return () => {
      if (debitRef.current) clearInterval(debitRef.current);
    };
  }, [joined, viewerMode, sessionData, session]);

  const joinSession = async () => {
    if (!session) {
      router.push("/login");
      return;
    }
    if (!sessionData) return;

    try {
      const res = await fetch("/api/livecam/join", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ session_id: sessionData.session_id }),
      });
      if (res.ok) {
        setJoined(true);
      } else {
        const json = await res.json();
        setError(json.error || "Failed to join");
      }
    } catch {
      setError("Failed to join session");
    }
  };

  const handleUpgrade = async (newMode: "group" | "private") => {
    if (!session) {
      router.push("/login");
      return;
    }
    if (!sessionData) return;

    try {
      const res = await fetch("/api/livecam/upgrade", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ session_id: sessionData.session_id, mode: newMode }),
      });
      const json = await res.json();
      if (res.ok) {
        setViewerMode(newMode);
      } else {
        // R17 C.4: native alert sometimes hangs the stream on Android
        // and looks broken on iOS. Toast stays out of the way.
        useToastStore.getState().addToast("error", json.error || "Upgrade failed");
      }
    } catch {
      useToastStore.getState().addToast("error", "Upgrade failed");
    }
  };

  const sendTip = async (amount: number) => {
    if (!session || !sessionData) return;
    try {
      const res = await fetch("/api/tips", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ receiver_id: broadcasterId, amount }),
      });
      if (res.ok) {
        setTipAmount(amount);
        setTipTrigger(true);
        setTimeout(() => setTipTrigger(false), 100);
        setCreditBalance((prev) => prev - amount);
        setMessages((prev) => [
          ...prev,
          { user: "System", text: `${session.user?.name || "You"} tipped ${amount} credits!` },
        ]);
      } else {
        const json = await res.json();
        useToastStore.getState().addToast("error", json.error || "Failed to send tip");
      }
    } catch {
      useToastStore.getState().addToast("error", "Failed to send tip");
    }
  };

  const sendChat = () => {
    if (!chatInput.trim()) return;
    setMessages((prev) => [
      ...prev,
      { user: session?.user?.name || "You", text: chatInput.trim() },
    ]);
    setChatInput("");
  };

  const formatTime = (seconds: number) => {
    const m = Math.floor(seconds / 60);
    const s = seconds % 60;
    return `${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center min-h-[60vh]">
        <div className="w-8 h-8 border-2 border-gold border-t-transparent rounded-full animate-spin" />
      </div>
    );
  }

  if (error && !sessionData) {
    return (
      <div className="text-center py-20">
        <p className="text-lg text-text-muted">{error}</p>
        <button
          onClick={() => router.push("/livecam")}
          className="mt-4 text-gold hover:text-gold-light transition-colors"
        >
          Back to LiveCams
        </button>
      </div>
    );
  }

  const currentMode = sessionData?.mode || "free";
  const isHost = session?.user?.id === broadcasterId;

  return (
    <div className="max-w-6xl mx-auto space-y-6">
      <TipAnimation amount={tipAmount} trigger={tipTrigger} />
      <LowBalancePopup threshold={100} />
      {downgradedNotice && (
        <div className="bg-amber-500/10 border border-amber-500/40 text-amber-300 rounded-lg p-3 flex items-center justify-between">
          <span className="text-sm">{downgradedNotice}</span>
          <button
            onClick={() => setDowngradedNotice(null)}
            className="text-amber-300/70 hover:text-amber-300 text-sm"
            aria-label="Dismiss"
          >
            ✕
          </button>
        </div>
      )}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <h1 className="text-xl font-bold text-white">
            {sessionData?.username || "Performer"}
          </h1>
          <span className="w-2.5 h-2.5 bg-red-500 rounded-full animate-pulse" />
          <span
            className={`text-white text-xs font-bold px-2 py-0.5 rounded uppercase ${
              currentMode === "private"
                ? "bg-purple-600"
                : currentMode === "group"
                ? "bg-blue-600"
                : "bg-green-600"
            }`}
          >
            {currentMode}
          </span>
        </div>
        {session && (
          <div className="text-sm text-text-muted">
            Credits: <span className="text-gold font-bold">{creditBalance}</span>
          </div>
        )}
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
        {/* Video Area */}
        <div className="lg:col-span-2 space-y-4">
          <div className="relative bg-black rounded-xl aspect-video">
            <div className="absolute inset-0 flex items-center justify-center overflow-hidden rounded-xl">
              {/* Placeholder for WebRTC playback */}
              <div className="text-center text-text-muted space-y-3">
                <svg className="w-16 h-16 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" />
                </svg>
                {!joined ? (
                  <button
                    onClick={joinSession}
                    className="bg-gold hover:bg-gold-light text-black font-bold px-8 py-3 rounded-lg transition-all shadow-glow"
                  >
                    Watch Stream
                  </button>
                ) : (
                  <p className="text-sm">Stream connected via WebRTC</p>
                )}
              </div>
            </div>

            {/* Timer overlay */}
            {joined && viewerMode === "free" && freeCountdown > 0 && (
              <div className="absolute top-3 right-3 z-20 bg-black/70 text-white text-sm font-mono px-3 py-1 rounded">
                Free: {formatTime(freeCountdown)}
              </div>
            )}
            {joined && viewerMode === "free" && freeCountdown === 0 && (
              <div className="absolute inset-0 z-20 bg-black/80 flex items-center justify-center rounded-xl">
                <div className="text-center space-y-4">
                  <p className="text-white text-lg font-semibold">Free preview ended</p>
                  <p className="text-text-muted text-sm">Upgrade to continue watching</p>
                  <div className="flex gap-3 justify-center">
                    <button
                      onClick={() => handleUpgrade("group")}
                      className="bg-blue-600 hover:bg-blue-700 text-white font-bold px-6 py-2 rounded-lg transition-all"
                    >
                      Group <span className="text-gold">{sessionData?.group_rate} cr/min</span>
                    </button>
                    <button
                      onClick={() => handleUpgrade("private")}
                      className="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded-lg transition-all"
                    >
                      Private <span className="text-gold">{sessionData?.private_rate} cr/min</span>
                    </button>
                  </div>
                </div>
              </div>
            )}

            {/* Stream Overlays — visual layer over video */}
            {joined && sessionData && (
              <StreamOverlayLayer
                overlays={activeOverlays}
                isHost={isHost}
                userId={overlayUserId}
                onVote={handleVote}
              />
            )}
          </div>

          {/* Host overlay controls (below video) */}
          {joined && isHost && sessionData && (
            <StreamOverlayControls
              overlays={activeOverlays}
              sessionId={sessionData.session_id}
              onRefresh={refreshOverlays}
            />
          )}

          {/* Upgrade Buttons */}
          {joined && viewerMode === "free" && freeCountdown > 0 && (
            <div className="flex gap-3">
              <button
                onClick={() => handleUpgrade("group")}
                className="flex-1 bg-blue-600/20 hover:bg-blue-600/30 border border-blue-600/50 text-white font-semibold px-4 py-3 rounded-lg transition-all text-center"
              >
                Go Group <span className="text-gold">{sessionData?.group_rate} cr/min</span>
              </button>
              <button
                onClick={() => handleUpgrade("private")}
                className="flex-1 bg-purple-600/20 hover:bg-purple-600/30 border border-purple-600/50 text-white font-semibold px-4 py-3 rounded-lg transition-all text-center"
              >
                Go Private <span className="text-gold">{sessionData?.private_rate} cr/min</span>
              </button>
            </div>
          )}

          {/* Paid mode info */}
          {joined && viewerMode !== "free" && (
            <div className={`rounded-lg p-3 text-center text-sm ${
              viewerMode === "group" ? "bg-blue-600/20 border border-blue-600/30" : "bg-purple-600/20 border border-purple-600/30"
            }`}>
              <span className="text-white">
                {viewerMode === "group" ? "Group" : "Private"} show —{" "}
                <span className="text-gold font-bold">
                  {viewerMode === "group" ? sessionData?.group_rate : sessionData?.private_rate} credits/min
                </span>
              </span>
            </div>
          )}
        </div>

        {/* Chat */}
        <div className="bg-surface rounded-xl border border-white/5 p-4 flex flex-col h-[20rem] lg:h-[28rem]">
          <h3 className="text-sm font-semibold text-white mb-3 flex items-center justify-between">
            <span>Chat</span>
            <span className="text-text-muted text-xs flex items-center gap-1">
              <svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
                <path d="M10 12a2 2 0 100-4 2 2 0 000 4z" />
                <path fillRule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clipRule="evenodd" />
              </svg>
              {sessionData?.viewer_count || 0}
            </span>
          </h3>
          <div className="flex-1 overflow-y-auto space-y-2 mb-3">
            {messages.length === 0 ? (
              <p className="text-text-muted text-sm">No messages yet — say hello!</p>
            ) : (
              messages.map((m, i) => (
                <div key={i} className="text-sm">
                  <span className="text-gold font-medium">{m.user}: </span>
                  <span className="text-white">{m.text}</span>
                </div>
              ))
            )}
          </div>
          {/* Tip buttons */}
          {session && joined && (
            <div className="grid grid-cols-2 lg:grid-cols-4 gap-1.5 mb-2">
              {[5, 10, 25, 50].map((amt) => (
                <button
                  key={amt}
                  onClick={() => sendTip(amt)}
                  className="flex-1 bg-gold/20 hover:bg-gold/30 border border-gold/30 text-gold text-xs font-bold py-1.5 rounded-lg transition-all"
                >
                  {amt}
                </button>
              ))}
            </div>
          )}

          {session ? (
            <div className="flex gap-2">
              <input
                type="text"
                value={chatInput}
                onChange={(e) => setChatInput(e.target.value)}
                onKeyDown={(e) => e.key === "Enter" && sendChat()}
                placeholder="Type a message..."
                className="flex-1 bg-surface-light border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-text-muted focus:outline-none focus:ring-1 focus:ring-gold/50"
              />
              <button
                onClick={sendChat}
                className="bg-gold hover:bg-gold-light text-black font-semibold px-4 py-2 rounded-lg text-sm transition-all"
              >
                Send
              </button>
            </div>
          ) : (
            <p className="text-text-muted text-sm text-center">
              <a href="/login" className="text-gold hover:text-gold-light">Log in</a> to chat
            </p>
          )}
        </div>
      </div>
    </div>
  );
}
