import { useState, useRef, useEffect, useCallback } from "react";
import { useLiveKit } from "./useLiveKit";
import { useAuth } from "../../auth/AuthContext";
import "./Live.css";

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

/**
 * LiveKit-based broadcast component
 * Professional video streaming that works everywhere (5G, 4G, WiFi, firewalls)
 */
export default function LiveKitBroadcast({ coords, onClose, onStreamCreated }) {
  const { username, token: authToken } = useAuth();
  const userID = username || `anon_${Date.now()}`;

  const [roomName] = useState(() => `live_${userID}_${Date.now()}`);
  const [title, setTitle] = useState("");
  const [localStream, setLocalStream] = useState(null);
  const [showConfirm, setShowConfirm] = useState(false);
  const [livePostId, setLivePostId] = useState(null);
  const [facingMode, setFacingMode] = useState("user");
  const [isSwitchingCamera, setIsSwitchingCamera] = useState(false);

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

  // Comments state
  const [comments, setComments] = useState([]);
  const [commentInput, setCommentInput] = 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);

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

  // Start camera on mount
  useEffect(() => {
    const startCamera = async () => {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({
          video: { facingMode: "user", width: 1280, height: 720 },
          audio: true,
        });
        setLocalStream(stream);
        if (videoRef.current) {
          videoRef.current.srcObject = stream;
        }
      } catch (err) {
        console.error("[LiveKit] Camera error:", err);
      }
    };
    startCamera();

    return () => {
      if (localStream) {
        localStream.getTracks().forEach((t) => t.stop());
      }
    };
  }, []);

  // Update video element when stream changes
  useEffect(() => {
    if (videoRef.current && localStream) {
      videoRef.current.srcObject = localStream;
    }
  }, [localStream]);

  // Timer effect - update every second when live
  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]);

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

  // Switch between front and back camera
  const switchCamera = useCallback(async () => {
    if (isSwitchingCamera) return;
    setIsSwitchingCamera(true);

    try {
      const newFacingMode = facingMode === "user" ? "environment" : "user";

      // Get new stream with switched camera
      const newStream = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: newFacingMode, width: 1280, height: 720 },
        audio: true,
      });

      // Stop old video tracks only (keep audio reference for LiveKit)
      if (localStream) {
        localStream.getVideoTracks().forEach((t) => t.stop());
      }

      // If live, replace the video track in LiveKit
      if (isLive) {
        const newVideoTrack = newStream.getVideoTracks()[0];
        await replaceVideoTrack(newVideoTrack);
      }

      // Update state
      setLocalStream(newStream);
      setFacingMode(newFacingMode);

      // Update video element
      if (videoRef.current) {
        videoRef.current.srcObject = newStream;
      }

      console.log("[LiveKit] Switched to", newFacingMode, "camera");
    } catch (err) {
      console.error("[LiveKit] Failed to switch camera:", err);
    } finally {
      setIsSwitchingCamera(false);
    }
  }, [facingMode, localStream, isSwitchingCamera, isLive, replaceVideoTrack]);

  // Add a comment
  const handleAddComment = useCallback(() => {
    if (!commentInput.trim()) return;

    const newComment = {
      id: Date.now(),
      author: username || "Host",
      text: commentInput.trim(),
      timestamp: Date.now(),
    };

    setComments((prev) => [...prev, newComment]);
    setCommentInput("");
  }, [commentInput, username]);

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

    // Get video track from stream
    const videoTrack = localStream.getVideoTracks()[0];
    await startBroadcast(videoTrack, true);

    // Start timer
    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",
          category: "EVENT",
          sub_category: "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 }));
      } else {
        const errText = await res.text();
        console.error("[LiveKit] Failed to create live post:", res.status, errText);
        alert("Live started, but we couldn't create the live post.");
      }
    } catch (err) {
      console.error("[LiveKit] Failed to create live post:", err);
      alert("Live started, but we couldn't create the live post.");
    }
  }, [title, localStream, startBroadcast, roomName, liveCoords, onStreamCreated, authToken, username]);

  const handleEndStream = useCallback(async (save) => {
    await stopBroadcast();
    if (localStream) {
      localStream.getTracks().forEach((t) => t.stop());
    }

    // Stop egress recording and get video key
    let videoKey = "";
    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 || "";
        console.log("[LiveKit] Egress stopped, video key:", videoKey);
      }
    } catch (err) {
      console.warn("[LiveKit] Failed to stop egress:", err);
    }

    if (livePostId) {
      try {
        // Include comments in finalize request
        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,
            comments: save ? comments.map((c) => ({
              author: c.author,
              text: c.text,
              timestamp: c.timestamp,
            })) : [],
          }),
        });
        if (res.ok && save) {
          const post = await res.json();
          window.dispatchEvent(new CustomEvent("live-post-updated", { detail: post }));
        }
        if (res.ok && !save) {
          window.dispatchEvent(new CustomEvent("live-post-deleted", { detail: { post_id: livePostId } }));
        }
        if (!res.ok) {
          const errText = await res.text();
          console.error("[LiveKit] Finalize failed:", res.status, errText);
          alert("We couldn't save the live post. Please try again.");
        }
      } catch (err) {
        console.error("[LiveKit] Failed to finalize live post:", err);
        alert("We couldn't save the live post. Please try again.");
      }
    }
    onClose?.();
  }, [stopBroadcast, localStream, onClose, livePostId, authToken, roomName, comments]);

  const handleBackdropClick = (e) => {
    if (e.target === e.currentTarget && !isLive) {
      if (localStream) {
        localStream.getTracks().forEach((t) => t.stop());
      }
      onClose?.();
    }
  };

  return (
    <div className="sw-broadcast-modal" onClick={handleBackdropClick}>
      <div className="sw-broadcast-container">
        {/* Header */}
        <div className="sw-broadcast-header">
          <div className="sw-broadcast-header-left">
            <i className="fa-solid fa-broadcast-tower" />
            <span>{isLive ? "LIVE" : "Go Live"}</span>
            {isLive && (
              <>
                <div className="sw-broadcast-live-badge">
                  <span className="sw-broadcast-dot" />
                  <span>{viewerCount} watching</span>
                </div>
                <div className="sw-broadcast-timer">
                  <i className="fa-solid fa-clock" />
                  <span>{formatTime(elapsedTime)}</span>
                </div>
              </>
            )}
          </div>
          <button
            type="button"
            className="sw-broadcast-close"
            onClick={() => {
              if (isLive) {
                setShowConfirm(true);
              } else {
                if (localStream) {
                  localStream.getTracks().forEach((t) => t.stop());
                }
                onClose?.();
              }
            }}
          >
            <i className="fa-solid fa-times" />
          </button>
        </div>

        {/* Content */}
        <div className="sw-broadcast-content">
          {/* Video preview */}
          <div className="sw-broadcast-video-area">
            <div className="sw-broadcast-main-video">
              {localStream ? (
                <video
                  ref={videoRef}
                  autoPlay
                  playsInline
                  muted
                  className="sw-broadcast-video"
                />
              ) : (
                <div className="sw-broadcast-video-placeholder">
                  <i className="fa-solid fa-spinner fa-spin" />
                  <span>Starting camera...</span>
                </div>
              )}

              {isLive && (
                <div className="sw-broadcast-live-indicator">
                  <span className="sw-broadcast-dot" />
                  <span>LIVE</span>
                </div>
              )}

              {/* Camera controls overlay */}
              <div className="sw-broadcast-controls-overlay">
                <button
                  type="button"
                  className="sw-broadcast-control-btn"
                  onClick={switchCamera}
                  disabled={isSwitchingCamera}
                  title={facingMode === "user" ? "Switch to back camera" : "Switch to front camera"}
                >
                  {isSwitchingCamera ? (
                    <i className="fa-solid fa-spinner fa-spin" />
                  ) : (
                    <i className="fa-solid fa-camera-rotate" />
                  )}
                </button>
              </div>
            </div>
          </div>

          {/* Side panel */}
          <div className="sw-broadcast-side">
            {!isLive && (
              <div className="sw-broadcast-form">
                <label className="sw-broadcast-label">Stream Title</label>
                <input
                  type="text"
                  className="sw-broadcast-input"
                  placeholder="What's happening?"
                  value={title}
                  onChange={(e) => setTitle(e.target.value)}
                  maxLength={100}
                />
                <div className="sw-broadcast-hint">
                  Using LiveKit - works on 5G/4G/WiFi
                </div>
              </div>
            )}

            {isLive && (
              <>
                <div className="sw-broadcast-live-info">
                  <h3 className="sw-broadcast-title">{title}</h3>
                  <div className="sw-broadcast-stats">
                    <span>
                      <i className="fa-solid fa-eye" /> {viewerCount} viewers
                    </span>
                    <span>
                      <i className="fa-solid fa-clock" /> {formatTime(elapsedTime)}
                    </span>
                  </div>
                </div>

                {/* Comments section */}
                <div className="sw-broadcast-comments">
                  <div className="sw-broadcast-comments-header">
                    <i className="fa-solid fa-comments" />
                    <span>Comments ({comments.length})</span>
                  </div>
                  <div className="sw-broadcast-comments-list">
                    {comments.length === 0 ? (
                      <div className="sw-broadcast-no-comments">
                        No comments yet
                      </div>
                    ) : (
                      comments.map((c) => (
                        <div key={c.id} className="sw-broadcast-comment">
                          <span className="sw-broadcast-comment-author">{c.author}</span>
                          <span className="sw-broadcast-comment-text">{c.text}</span>
                        </div>
                      ))
                    )}
                    <div ref={commentsEndRef} />
                  </div>
                  <div className="sw-broadcast-comment-input-row">
                    <input
                      type="text"
                      className="sw-broadcast-comment-input"
                      placeholder="Add a comment..."
                      value={commentInput}
                      onChange={(e) => setCommentInput(e.target.value)}
                      onKeyDown={(e) => e.key === "Enter" && handleAddComment()}
                      maxLength={200}
                    />
                    <button
                      type="button"
                      className="sw-broadcast-comment-send"
                      onClick={handleAddComment}
                      disabled={!commentInput.trim()}
                    >
                      <i className="fa-solid fa-paper-plane" />
                    </button>
                  </div>
                </div>
              </>
            )}

            {error && (
              <div className="sw-broadcast-error">
                <i className="fa-solid fa-exclamation-triangle" />
                <span>{error}</span>
              </div>
            )}

            <div className="sw-broadcast-actions">
              {isLive ? (
                <button
                  type="button"
                  className="sw-broadcast-btn danger"
                  onClick={() => setShowConfirm(true)}
                >
                  <i className="fa-solid fa-stop" />
                  <span>End Stream</span>
                </button>
              ) : (
                <button
                  type="button"
                  className="sw-broadcast-btn primary"
                  onClick={handleGoLive}
                  disabled={isConnecting || !localStream}
                >
                  {isConnecting ? (
                    <>
                      <i className="fa-solid fa-spinner fa-spin" />
                      <span>Connecting...</span>
                    </>
                  ) : (
                    <>
                      <i className="fa-solid fa-broadcast-tower" />
                      <span>Go Live</span>
                    </>
                  )}
                </button>
              )}
            </div>
          </div>
        </div>

        {/* Confirm dialog */}
        {showConfirm && (
          <div className="sw-broadcast-confirm-overlay">
            <div className="sw-broadcast-confirm">
              <h3>End Stream?</h3>
              <p>Your live stream will end for all viewers.</p>
              {comments.length > 0 && (
                <p className="sw-broadcast-confirm-comments">
                  <i className="fa-solid fa-comments" /> {comments.length} comments will be saved
                </p>
              )}
              <div className="sw-broadcast-confirm-actions">
                <button
                  type="button"
                  className="sw-broadcast-btn secondary"
                  onClick={() => setShowConfirm(false)}
                >
                  Cancel
                </button>
                <button
                  type="button"
                  className="sw-broadcast-btn danger"
                  onClick={() => handleEndStream(false)}
                >
                  Discard
                </button>
                <button
                  type="button"
                  className="sw-broadcast-btn primary"
                  onClick={() => handleEndStream(true)}
                >
                  Save
                </button>
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
