import { useState, useRef, useEffect, useCallback } from "react";
import { useLiveKit } from "./useLiveKit";
import { useDualCamera } from "./useDualCamera";
import { useAuth } from "../../auth/AuthContext";
import { fetchPostComments, createPostComment, fetchProfile } from "../../api/client";
import { CREATE_CATEGORY_MAP, FILTER_MAIN_CATEGORIES } from "../Map/mapConfig";

const API_BASE = (import.meta?.env?.VITE_API_BASE_URL || "").replace(/\/+$/, "");
const LIVEKIT_API = "https://stream.sociowire.com";

/**
 * LiveKit-based broadcast component - Redesigned fullscreen experience
 */
export default function LiveKitBroadcast({ coords, onClose, onStreamCreated, initialTitle, initialCategory, initialSubCategory }) {
  const { username, token: authToken } = useAuth();
  const userID = username || `anon_${Date.now()}`;

  const [roomName] = useState(() => `live_${userID}_${Date.now()}`);
  const [title, setTitle] = useState(initialTitle || "");
  const [showConfirm, setShowConfirm] = useState(false);
  const [showSettings, setShowSettings] = useState(!initialTitle); // Show settings if no title provided
  const [livePostId, setLivePostId] = useState(null);
  const liveCategoryOptions = FILTER_MAIN_CATEGORIES.filter((c) => c !== "All");
  const [liveCategory, setLiveCategory] = useState(initialCategory || "Events");
  const [liveSubCategory, setLiveSubCategory] = useState(initialSubCategory || "Live");

  // Timer state
  const [liveStartTime, setLiveStartTime] = useState(null);
  const [elapsedTime, setElapsedTime] = useState(0);

  // Comments state
  const [comments, setComments] = useState([]);
  const [commentInput, setCommentInput] = useState("");
  const [showComments, setShowComments] = useState(true);
  const [commenterAvatars, setCommenterAvatars] = useState({});
  const commentsEndRef = useRef(null);

  const [liveCoords] = useState(() => {
    if (coords && typeof coords === "object") {
      if (Array.isArray(coords) && coords.length >= 2) {
        return { lon: coords[0], lat: coords[1] };
      }
      const lat = coords.lat ?? coords.latitude;
      const lon = coords.lon ?? coords.lng ?? coords.longitude;
      if (Number.isFinite(lat) && Number.isFinite(lon)) {
        return { lat, lon };
      }
    }
    return { lat: null, lon: null };
  });

  const videoRef = useRef(null);

  // Camera hook
  const {
    mainStream,
    isSwapped,
    error: cameraError,
    isStarting: cameraStarting,
    isSwapping,
    hasDualCameras,
    startCameras,
    swapCameras,
    stopCameras,
  } = useDualCamera();

  // Handle real-time comments via WebSocket
  const handleDataReceived = useCallback((data, participant) => {
    if (data?.type === "comment" && data?.comment) {
      setComments(prev => {
        if (prev.some(c => c.id === data.comment.id)) return prev;
        return [...prev, data.comment];
      });
    }
  }, []);

  const {
    isLive,
    isConnecting,
    error: liveKitError,
    viewerCount,
    startBroadcast,
    stopBroadcast,
    replaceVideoTrack,
    sendData,
  } = useLiveKit({
    roomName,
    userID,
    username,
    token: authToken,
    onDataReceived: handleDataReceived,
  });

  const error = cameraError || liveKitError;

  const subCategoryOptions = (() => {
    const options = Array.isArray(CREATE_CATEGORY_MAP[liveCategory])
      ? CREATE_CATEGORY_MAP[liveCategory]
      : [];
    const withLive = ["Live", ...options];
    const deduped = [];
    const seen = new Set();
    for (const item of withLive) {
      const label = (item || "").toString().trim();
      if (!label || seen.has(label)) continue;
      seen.add(label);
      deduped.push(label);
    }
    return deduped;
  })();

  useEffect(() => {
    if (!subCategoryOptions.length) return;
    if (!subCategoryOptions.includes(liveSubCategory)) {
      setLiveSubCategory(subCategoryOptions[0]);
    }
  }, [liveCategory]);

  // Start camera on mount
  useEffect(() => {
    startCameras();
    return () => stopCameras();
  }, []);

  // Update video element
  useEffect(() => {
    const el = videoRef.current;
    if (!el || !mainStream) return;
    el.srcObject = mainStream;
    el.muted = true;
    el.play().catch(() => {});
  }, [mainStream]);

  // Timer
  useEffect(() => {
    if (!isLive || !liveStartTime) return;
    const interval = setInterval(() => {
      setElapsedTime(Math.floor((Date.now() - liveStartTime) / 1000));
    }, 1000);
    return () => clearInterval(interval);
  }, [isLive, liveStartTime]);

  // Auto-scroll comments
  useEffect(() => {
    commentsEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [comments]);

  // Fetch commenter avatars
  useEffect(() => {
    if (!comments.length) return;
    const usernames = [...new Set(comments.map(c => c.username).filter(Boolean))];
    const toFetch = usernames.filter(u => !commenterAvatars[u]);
    if (!toFetch.length) return;
    toFetch.forEach(uname => {
      fetchProfile(uname).then(res => {
        if (res?.avatar_url) {
          setCommenterAvatars(prev => ({ ...prev, [uname]: res.avatar_url }));
        }
      });
    });
  }, [comments]);

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

  const switchCamera = useCallback(async () => {
    if (isSwapping || !hasDualCameras) return;
    await swapCameras();
  }, [isSwapping, hasDualCameras, swapCameras]);

  // Update LiveKit track when stream changes
  useEffect(() => {
    if (isLive && mainStream) {
      const newVideoTrack = mainStream.getVideoTracks()[0];
      if (newVideoTrack) replaceVideoTrack(newVideoTrack);
    }
  }, [mainStream, isLive, replaceVideoTrack]);

  const refreshComments = useCallback(async () => {
    if (!livePostId) return;
    const items = await fetchPostComments(livePostId, 50);
    if (Array.isArray(items)) {
      setComments(prev => {
        const serverIds = new Set(items.map(c => String(c.id)));
        const serverBodies = new Set(items.map(c => c.body?.toLowerCase().trim()));
        const localOnly = prev.filter(c => {
          const id = String(c.id);
          const isLocal = id.includes('_');
          const isPending = c._pending || c._failed;
          const bodyMatch = serverBodies.has(c.body?.toLowerCase().trim());
          return isLocal && (isPending || !bodyMatch);
        });
        return [...items, ...localOnly];
      });
    }
  }, [livePostId]);

  useEffect(() => {
    if (!isLive || !livePostId) return;
    let active = true;
    refreshComments();
    const timer = setInterval(() => {
      if (active) refreshComments();
    }, 15000);
    return () => { active = false; clearInterval(timer); };
  }, [isLive, livePostId, refreshComments]);

  const handleAddComment = useCallback(async () => {
    const body = commentInput.trim();
    if (!body || !livePostId) return;
    setCommentInput("");

    const commentId = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
    const newComment = {
      id: commentId,
      body,
      username: username || "You",
      created_at: new Date().toISOString(),
      _pending: true,
    };

    setComments(prev => [...prev, newComment]);
    if (sendData) sendData({ type: "comment", comment: newComment });

    let saved = false;
    for (let attempt = 0; attempt < 3 && !saved; attempt++) {
      if (attempt > 0) await new Promise(r => setTimeout(r, 1000 * attempt));
      const res = await createPostComment(livePostId, body);
      if (res?.ok) {
        saved = true;
        setComments(prev => prev.map(c => c.id === commentId ? { ...c, _pending: false } : c));
      }
    }
    if (!saved) {
      setComments(prev => prev.map(c => c.id === commentId ? { ...c, _failed: true } : c));
    }
  }, [commentInput, livePostId, username, sendData]);

  const handleGoLive = useCallback(async () => {
    if (isConnecting || isLive || livePostId) return;
    if (!authToken) { alert("Please log in to start a live stream."); return; }
    if (!title.trim()) { alert("Please enter a title"); setShowSettings(true); return; }
    if (!mainStream) { alert("Camera not ready"); return; }

    const videoTrack = mainStream.getVideoTracks()[0];
    await startBroadcast(videoTrack, true);
    setLiveStartTime(Date.now());
    setElapsedTime(0);

    if (onStreamCreated) {
      onStreamCreated({ roomName, title: title.trim(), coords: liveCoords });
    }

    try {
      const res = await fetch(`${API_BASE}/api/post`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          ...(authToken ? { Authorization: `Bearer ${authToken}` } : {}),
        },
        body: JSON.stringify({
          title: title.trim(),
          snippet: `Live now${liveSubCategory ? ` · ${liveSubCategory}` : ""}`,
          category: liveCategory === "Events" ? "EVENT" : liveCategory.toUpperCase(),
          sub_category: liveSubCategory || "Live",
          lat: liveCoords?.lat,
          lon: liveCoords?.lon,
          author: username,
          source: "sociowire",
          visibility: "public",
          content_type: "live",
          embed_url: `livekit://${roomName}`,
        }),
      });
      if (res.ok) {
        const post = await res.json();
        setLivePostId(post?.id || null);
        window.dispatchEvent(new CustomEvent("live-post-created", { detail: post }));
      }
    } catch (err) {
      console.error("[LiveKit] Failed to create live post:", err);
    }
  }, [title, mainStream, startBroadcast, roomName, liveCoords, onStreamCreated, authToken, username, liveCategory, liveSubCategory, isConnecting, isLive, livePostId]);

  const handleEndStream = useCallback(async (save) => {
    await stopBroadcast();
    stopCameras();

    let videoKey = "";
    let thumbnailKey = "";
    try {
      const egressRes = await fetch(`${LIVEKIT_API}/api/livekit/egress/stop`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ room: roomName, save: !!save }),
      });
      if (egressRes.ok) {
        const egressData = await egressRes.json();
        videoKey = egressData.key || "";
        thumbnailKey = egressData.thumbnail_key || "";
      }
    } catch (err) {
      console.warn("[LiveKit] Failed to stop egress:", err);
    }

    if (livePostId) {
      try {
        const res = await fetch(`${API_BASE}/api/live/finalize`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            ...(authToken ? { Authorization: `Bearer ${authToken}` } : {}),
          },
          body: JSON.stringify({
            post_id: livePostId,
            save: !!save,
            video_key: videoKey,
            thumbnail_key: thumbnailKey,
            comments: [],
          }),
        });
        // Always delete the live post marker first
        window.dispatchEvent(new CustomEvent("live-post-deleted", { detail: { post_id: livePostId } }));

        if (res.ok && save) {
          // If saved, add the video post back
          const post = await res.json();
          if (post?.id) {
            window.dispatchEvent(new CustomEvent("live-post-created", { detail: post }));
          }
        }
      } catch (err) {
        console.error("[LiveKit] Failed to finalize live post:", err);
      }
    }
    onClose?.();
  }, [stopBroadcast, stopCameras, onClose, livePostId, authToken, roomName]);

  return (
    <div className="fixed inset-0 z-[9999] bg-black">
      {/* Fullscreen Video */}
      <div className="absolute inset-0">
        {mainStream ? (
          <video
            ref={videoRef}
            autoPlay
            playsInline
            muted
            className="w-full h-full object-cover"
          />
        ) : (
          <div className="w-full h-full flex flex-col items-center justify-center text-white/60">
            {cameraStarting ? (
              <>
                <i className="fa-solid fa-spinner fa-spin text-5xl mb-4" />
                <span>Starting camera...</span>
              </>
            ) : (
              <>
                <i className="fa-solid fa-video-slash text-5xl mb-4 opacity-50" />
                <span>Camera unavailable</span>
              </>
            )}
          </div>
        )}
      </div>

      {/* Gradient overlays */}
      <div className="absolute inset-x-0 top-0 h-32 bg-gradient-to-b from-black/70 to-transparent pointer-events-none" />
      <div className="absolute inset-x-0 bottom-0 h-48 bg-gradient-to-t from-black/80 to-transparent pointer-events-none" />

      {/* Top bar */}
      <div className="absolute top-0 left-0 right-0 flex items-center justify-between p-4 z-10">
        <div className="flex items-center gap-3">
          {isLive ? (
            <>
              <div className="flex items-center gap-2 px-3 py-1.5 rounded-full bg-red-600 text-white text-sm font-bold shadow-lg shadow-red-600/50">
                <span className="w-2 h-2 rounded-full bg-white animate-pulse" />
                LIVE
              </div>
              <div className="flex items-center gap-2 px-3 py-1.5 rounded-full bg-black/50 backdrop-blur-sm text-white text-sm">
                <i className="fa-solid fa-eye" />
                <span>{viewerCount}</span>
              </div>
              <div className="flex items-center gap-2 px-3 py-1.5 rounded-full bg-black/50 backdrop-blur-sm text-white text-sm font-mono">
                <i className="fa-solid fa-clock" />
                <span>{formatTime(elapsedTime)}</span>
              </div>
            </>
          ) : (
            <div className="flex items-center gap-2 px-4 py-2 rounded-full bg-white/10 backdrop-blur-sm text-white font-semibold">
              <i className="fa-solid fa-broadcast-tower text-cyan-400" />
              <span>Go Live</span>
            </div>
          )}
        </div>

        <button
          className="w-10 h-10 rounded-full bg-black/50 backdrop-blur-sm text-white flex items-center justify-center hover:bg-red-500/50 transition-colors"
          onClick={() => isLive ? setShowConfirm(true) : (stopCameras(), onClose?.())}
        >
          <i className="fa-solid fa-times text-lg" />
        </button>
      </div>

      {/* Camera controls (right side) */}
      <div className="absolute right-4 top-1/2 -translate-y-1/2 flex flex-col gap-3 z-10">
        {hasDualCameras && (
          <button
            className="w-12 h-12 rounded-full bg-black/50 backdrop-blur-sm text-white flex items-center justify-center hover:bg-white/20 transition-colors"
            onClick={switchCamera}
            disabled={isSwapping}
          >
            {isSwapping ? (
              <i className="fa-solid fa-spinner fa-spin" />
            ) : (
              <i className="fa-solid fa-camera-rotate text-lg" />
            )}
          </button>
        )}
        {!isLive && (
          <button
            className="w-12 h-12 rounded-full bg-black/50 backdrop-blur-sm text-white flex items-center justify-center hover:bg-white/20 transition-colors"
            onClick={() => setShowSettings(!showSettings)}
          >
            <i className="fa-solid fa-gear text-lg" />
          </button>
        )}
        {isLive && (
          <button
            className={`w-12 h-12 rounded-full backdrop-blur-sm text-white flex items-center justify-center transition-colors ${showComments ? 'bg-cyan-500/50' : 'bg-black/50 hover:bg-white/20'}`}
            onClick={() => setShowComments(!showComments)}
          >
            <i className="fa-solid fa-comments text-lg" />
          </button>
        )}
      </div>

      {/* Pre-live: Settings panel */}
      {!isLive && showSettings && (
        <div className="absolute left-4 right-4 bottom-32 z-10">
          <div className="bg-black/70 backdrop-blur-xl rounded-2xl p-4 border border-white/10">
            <div className="flex items-center justify-between mb-3">
              <h3 className="text-white font-bold">Stream Settings</h3>
              <button
                className="text-white/60 hover:text-white"
                onClick={() => setShowSettings(false)}
              >
                <i className="fa-solid fa-chevron-down" />
              </button>
            </div>
            <input
              type="text"
              className="w-full px-4 py-3 mb-3 rounded-xl bg-white/10 border border-white/20 text-white placeholder:text-white/40 focus:outline-none focus:border-cyan-500"
              placeholder="Stream title..."
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              maxLength={100}
            />
            <div className="flex gap-2">
              <select
                className="flex-1 px-3 py-2 rounded-xl bg-white/10 border border-white/20 text-white focus:outline-none focus:border-cyan-500"
                value={liveCategory}
                onChange={(e) => setLiveCategory(e.target.value)}
              >
                {liveCategoryOptions.map((opt) => (
                  <option key={opt} value={opt} className="bg-gray-900">{opt}</option>
                ))}
              </select>
              <select
                className="flex-1 px-3 py-2 rounded-xl bg-white/10 border border-white/20 text-white focus:outline-none focus:border-cyan-500"
                value={liveSubCategory}
                onChange={(e) => setLiveSubCategory(e.target.value)}
              >
                {subCategoryOptions.map((opt) => (
                  <option key={opt} value={opt} className="bg-gray-900">{opt}</option>
                ))}
              </select>
            </div>
          </div>
        </div>
      )}

      {/* Pre-live: Title display (when settings hidden) */}
      {!isLive && !showSettings && title && (
        <div className="absolute left-4 right-4 bottom-32 z-10">
          <div className="bg-black/50 backdrop-blur-sm rounded-xl px-4 py-3 border border-white/10">
            <h3 className="text-white font-bold text-lg truncate">{title}</h3>
            <p className="text-white/60 text-sm">{liveCategory} · {liveSubCategory}</p>
          </div>
        </div>
      )}

      {/* Live: Comments section */}
      {isLive && showComments && (
        <div className="absolute left-4 right-20 bottom-32 max-h-[40vh] z-10 flex flex-col">
          <div className="flex-1 overflow-y-auto space-y-2 mb-3 scrollbar-hide">
            {comments.map((c, idx) => (
              <div
                key={c.id || idx}
                className={`flex items-start gap-2 px-3 py-2 rounded-xl bg-black/50 backdrop-blur-sm ${c._pending ? 'opacity-60' : ''}`}
              >
                <div className="w-8 h-8 rounded-full bg-gradient-to-br from-cyan-500 to-blue-500 flex items-center justify-center text-white text-xs font-bold flex-shrink-0 overflow-hidden">
                  {commenterAvatars[c.username] ? (
                    <img src={commenterAvatars[c.username]} alt="" className="w-full h-full object-cover" />
                  ) : (
                    (c.username || "?")[0]?.toUpperCase()
                  )}
                </div>
                <div className="min-w-0">
                  <span className="text-cyan-400 text-sm font-semibold">{c.username || "User"}</span>
                  <p className="text-white text-sm break-words">{c.body}</p>
                </div>
              </div>
            ))}
            <div ref={commentsEndRef} />
          </div>
          <div className="flex gap-2">
            <input
              type="text"
              className="flex-1 px-4 py-3 rounded-full bg-black/50 backdrop-blur-sm border border-white/20 text-white placeholder:text-white/40 focus:outline-none focus:border-cyan-500"
              placeholder={livePostId ? "Say something..." : "Connecting..."}
              value={commentInput}
              onChange={(e) => setCommentInput(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && handleAddComment()}
              disabled={!livePostId}
            />
            <button
              className="w-12 h-12 rounded-full bg-cyan-500 text-white flex items-center justify-center disabled:opacity-50"
              onClick={handleAddComment}
              disabled={!commentInput.trim() || !livePostId}
            >
              <i className="fa-solid fa-paper-plane" />
            </button>
          </div>
        </div>
      )}

      {/* Live: Title display */}
      {isLive && !showComments && (
        <div className="absolute left-4 right-20 bottom-32 z-10">
          <div className="bg-black/50 backdrop-blur-sm rounded-xl px-4 py-3">
            <h3 className="text-white font-bold text-lg truncate">{title}</h3>
            <p className="text-white/60 text-sm">{comments.length} comments</p>
          </div>
        </div>
      )}

      {/* Error display */}
      {error && (
        <div className="absolute left-4 right-4 bottom-24 z-10">
          <div className="bg-red-500/20 backdrop-blur-sm border border-red-500/50 rounded-xl px-4 py-3 text-red-300 text-sm">
            <i className="fa-solid fa-exclamation-triangle mr-2" />
            {error}
          </div>
        </div>
      )}

      {/* Bottom action button */}
      <div className="absolute bottom-6 left-4 right-4 z-10">
        {isLive ? (
          <button
            className="w-full py-4 rounded-2xl bg-gradient-to-r from-red-600 to-rose-600 text-white font-bold text-lg shadow-lg shadow-red-600/30 flex items-center justify-center gap-3 active:scale-[0.98] transition-transform"
            onClick={() => setShowConfirm(true)}
          >
            <i className="fa-solid fa-stop" />
            End Stream
          </button>
        ) : (
          <button
            className="w-full py-4 rounded-2xl bg-gradient-to-r from-red-600 to-rose-600 text-white font-bold text-lg shadow-lg shadow-red-600/30 flex items-center justify-center gap-3 disabled:opacity-50 active:scale-[0.98] transition-transform"
            onClick={handleGoLive}
            disabled={isConnecting || !mainStream}
          >
            {isConnecting ? (
              <>
                <i className="fa-solid fa-spinner fa-spin" />
                Connecting...
              </>
            ) : (
              <>
                <i className="fa-solid fa-broadcast-tower" />
                Go Live
              </>
            )}
          </button>
        )}
      </div>

      {/* End stream confirmation */}
      {showConfirm && (
        <div className="absolute inset-0 z-50 bg-black/80 backdrop-blur-sm flex items-center justify-center p-6">
          <div className="bg-surface-900 rounded-3xl p-6 max-w-sm w-full border border-white/10 shadow-2xl">
            <div className="w-16 h-16 rounded-full bg-red-500/20 flex items-center justify-center mx-auto mb-4">
              <i className="fa-solid fa-stop text-3xl text-red-400" />
            </div>
            <h3 className="text-xl font-bold text-white text-center mb-2">End Stream?</h3>
            <p className="text-surface-400 text-center mb-4">
              Your live stream will end for all {viewerCount} viewers.
            </p>
            {comments.length > 0 && (
              <p className="text-cyan-400 text-center text-sm mb-4">
                <i className="fa-solid fa-comments mr-2" />
                {comments.length} comments will be saved
              </p>
            )}
            <div className="flex flex-col gap-2">
              <button
                className="w-full py-3 rounded-xl bg-gradient-to-r from-emerald-600 to-green-600 text-white font-bold"
                onClick={() => handleEndStream(true)}
              >
                <i className="fa-solid fa-download mr-2" />
                Save & End
              </button>
              <button
                className="w-full py-3 rounded-xl bg-red-500/20 border border-red-500/50 text-red-400 font-bold"
                onClick={() => handleEndStream(false)}
              >
                <i className="fa-solid fa-trash mr-2" />
                Discard
              </button>
              <button
                className="w-full py-3 rounded-xl bg-white/10 text-white font-bold"
                onClick={() => setShowConfirm(false)}
              >
                Continue Streaming
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
