import React, { useEffect, useRef, useState, useCallback } from "react";
import { useDualCamera } from "./useDualCamera";
import { useWebRTCBroadcast } from "./useWebRTCBroadcast";
import { useAuth } from "../../auth/AuthContext";
import { CREATE_CATEGORY_MAP } from "../Map/mapConfig";
import "./Live.css";

const MAIN_CATEGORIES = ["News", "Events", "Friends", "Market"];

/**
 * LiveBroadcastModal - Host UI for live streaming
 *
 * Features:
 * - Dual camera preview (main + self PiP)
 * - Go Live / End Stream controls
 * - Title input
 * - Viewer count
 * - Join request management
 * - Participant grid
 */
export default function LiveBroadcastModal({ coords, onClose, onStreamCreated }) {
  const { username, token } = useAuth();
  const userID = username || `anon_${Date.now()}`;

  // Generate stream ID
  const [streamID] = useState(() => `live_${userID}_${Date.now()}`);

  // Form state
  const [title, setTitle] = useState("");
  const [category, setCategory] = useState("News");
  const [subCategory, setSubCategory] = useState(CREATE_CATEGORY_MAP.News[0]);
  const [showEndConfirm, setShowEndConfirm] = useState(false);
  const [saveAsPost, setSaveAsPost] = useState(true);

  // Video refs
  const mainVideoRef = useRef(null);
  const selfVideoRef = useRef(null);
  const participantRefs = useRef({});

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

  const {
    isLive,
    isConnecting,
    error: broadcastError,
    viewerCount,
    participants,
    joinRequests,
    startBroadcast,
    stopBroadcast,
    setStreamMeta,
    approveJoinRequest,
    denyJoinRequest,
    kickParticipant,
  } = useWebRTCBroadcast({ streamID, userID, username, token });

  const [audioMuted, setAudioMuted] = useState(false);

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

  // Attach main stream to video element
  useEffect(() => {
    if (mainVideoRef.current && mainStream) {
      mainVideoRef.current.srcObject = mainStream;
    }
  }, [mainStream]);

  // Attach self stream to PiP video element
  useEffect(() => {
    if (selfVideoRef.current && selfStream) {
      selfVideoRef.current.srcObject = selfStream;
    }
  }, [selfStream]);

  // Attach participant streams
  useEffect(() => {
    participants.forEach((p) => {
      const ref = participantRefs.current[p.userID];
      if (ref && p.stream) {
        ref.srcObject = p.stream;
      }
    });
  }, [participants]);

  const handleGoLive = useCallback(async () => {
    console.log("[LiveBroadcast] handleGoLive clicked, title:", title, "mainStream:", !!mainStream);

    // Remote log for debugging
    fetch('/api/debug-log', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        level: 'log',
        msg: `[LiveBroadcast] handleGoLive: title="${title}" hasMainStream=${!!mainStream} hasSelfStream=${!!selfStream}`,
        ts: new Date().toISOString(),
        src: 'broadcast'
      })
    }).catch(() => {});

    if (!title.trim()) {
      alert("Please enter a title for your live stream");
      return;
    }

    const meta = {
      title: title.trim(),
      lat: coords?.[1],
      lon: coords?.[0],
      category: category === "Events" ? "EVENT" : category.toUpperCase(),
      sub_category: subCategory,
    };

    // Store metadata for post creation when stream ends
    setStreamMeta(meta);

    console.log("[LiveBroadcast] Calling startBroadcast with meta:", meta);
    await startBroadcast(mainStream, selfStream, meta);

    if (onStreamCreated) {
      onStreamCreated({ streamID, title: title.trim(), coords, category, subCategory });
    }
  }, [title, category, subCategory, mainStream, selfStream, coords, startBroadcast, setStreamMeta, streamID, onStreamCreated]);

  const handleEndStream = useCallback(() => {
    setShowEndConfirm(true);
  }, []);

  const confirmEndStream = useCallback(async () => {
    await stopBroadcast(saveAsPost);
    stopCameras();
    onClose?.();
  }, [saveAsPost, stopBroadcast, stopCameras, onClose]);

  const handleToggleAudio = useCallback(() => {
    const newMuted = !audioMuted;
    setAudioMuted(newMuted);
    toggleAudio(newMuted);
  }, [audioMuted, toggleAudio]);

  const handleBackdropClick = (e) => {
    if (e.target === e.currentTarget && !isLive) {
      stopCameras();
      onClose?.();
    }
  };

  const error = cameraError || broadcastError;

  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>
          <button
            type="button"
            className="sw-broadcast-close"
            onClick={() => {
              if (isLive) {
                handleEndStream();
              } else {
                stopCameras();
                onClose?.();
              }
            }}
            aria-label="Close"
          >
            <i className="fa-solid fa-times" />
          </button>
        </div>

        {/* Main content */}
        <div className="sw-broadcast-content">
          {/* Video preview area */}
          <div className="sw-broadcast-video-area">
            {/* Main video (fullscreen) */}
            <div className="sw-broadcast-main-video">
              {mainStream ? (
                <>
                  <video
                    ref={mainVideoRef}
                    autoPlay
                    playsInline
                    muted
                    className="sw-broadcast-video"
                  />
                  {/* Camera label for debug */}
                  <div className="sw-broadcast-camera-label">
                    <i className="fa-solid fa-video" />
                    <span>{isSwapped ? "Back" : "Front"} cam</span>
                  </div>
                </>
              ) : (
                <div className="sw-broadcast-video-placeholder">
                  {cameraStarting ? (
                    <>
                      <i className="fa-solid fa-spinner fa-spin" />
                      <span>Starting camera...</span>
                    </>
                  ) : (
                    <>
                      <i className="fa-solid fa-video-slash" />
                      <span>Camera not available</span>
                    </>
                  )}
                </div>
              )}

              {/* Self PiP (draggable corner) - show if we have dual cameras */}
              {selfStream && (
                <div className="sw-broadcast-pip">
                  <video
                    ref={selfVideoRef}
                    autoPlay
                    playsInline
                    muted
                    className="sw-broadcast-pip-video"
                  />
                  <div className="sw-broadcast-pip-label">{isSwapped ? "Front" : "Back"}</div>
                </div>
              )}

              {/* No dual camera indicator */}
              {!selfStream && mainStream && !hasDualCameras && (
                <div className="sw-broadcast-no-pip">
                  <i className="fa-solid fa-camera" />
                  <span>Single camera</span>
                </div>
              )}

              {/* Participant strip (when live with participants) */}
              {isLive && participants.length > 0 && (
                <div className="sw-broadcast-participants-strip">
                  {participants.map((p) => (
                    <div key={p.userID} className="sw-broadcast-participant">
                      <video
                        ref={(el) => {
                          participantRefs.current[p.userID] = el;
                        }}
                        autoPlay
                        playsInline
                        className="sw-broadcast-participant-video"
                      />
                      <div className="sw-broadcast-participant-name">{p.username}</div>
                      <button
                        type="button"
                        className="sw-broadcast-kick-btn"
                        onClick={() => kickParticipant(p.userID)}
                        title="Remove"
                      >
                        <i className="fa-solid fa-times" />
                      </button>
                    </div>
                  ))}
                </div>
              )}

              {/* Camera controls overlay */}
              <div className="sw-broadcast-controls-overlay">
                <button
                  type="button"
                  className={`sw-broadcast-control-btn ${!hasDualCameras ? "is-disabled" : ""} ${isSwapping ? "is-swapping" : ""}`}
                  onClick={hasDualCameras && !isSwapping ? swapCameras : undefined}
                  title={hasDualCameras ? (isSwapping ? "Switching..." : "Swap cameras") : "Single camera only"}
                  disabled={!hasDualCameras || isSwapping}
                >
                  <i className={`fa-solid ${isSwapping ? "fa-spinner fa-spin" : "fa-camera-rotate"}`} />
                </button>
                <button
                  type="button"
                  className={`sw-broadcast-control-btn ${audioMuted ? "is-muted" : ""}`}
                  onClick={handleToggleAudio}
                  title={audioMuted ? "Unmute" : "Mute"}
                >
                  <i className={`fa-solid ${audioMuted ? "fa-microphone-slash" : "fa-microphone"}`} />
                </button>
              </div>
            </div>
          </div>

          {/* Side panel */}
          <div className="sw-broadcast-side">
            {/* Title input (before going live) */}
            {!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-category-row">
                  <div className="sw-broadcast-field">
                    <label className="sw-broadcast-label">Category</label>
                    <select
                      className="sw-broadcast-select"
                      value={category}
                      onChange={(e) => {
                        const cat = e.target.value;
                        setCategory(cat);
                        setSubCategory((CREATE_CATEGORY_MAP[cat] || CREATE_CATEGORY_MAP.News)[0]);
                      }}
                    >
                      {MAIN_CATEGORIES.map((cat) => (
                        <option key={cat} value={cat}>{cat}</option>
                      ))}
                    </select>
                  </div>
                  <div className="sw-broadcast-field">
                    <label className="sw-broadcast-label">Sub-category</label>
                    <select
                      className="sw-broadcast-select"
                      value={subCategory}
                      onChange={(e) => setSubCategory(e.target.value)}
                    >
                      {(CREATE_CATEGORY_MAP[category] || CREATE_CATEGORY_MAP.News).map((sub) => (
                        <option key={sub} value={sub}>{sub}</option>
                      ))}
                    </select>
                  </div>
                </div>

                <div className="sw-broadcast-hint">
                  Location: {coords ? `${coords[1].toFixed(4)}, ${coords[0].toFixed(4)}` : "Unknown"}
                </div>
              </div>
            )}

            {/* Live info */}
            {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-users" /> {participants.length} participants</span>
                </div>
              </div>
            )}

            {/* Join requests (when live) */}
            {isLive && joinRequests.length > 0 && (
              <div className="sw-broadcast-requests">
                <h4>Join Requests</h4>
                {joinRequests.map((req) => (
                  <div key={req.userID} className="sw-broadcast-request">
                    <span className="sw-broadcast-request-name">{req.username}</span>
                    <div className="sw-broadcast-request-actions">
                      <button
                        type="button"
                        className="sw-broadcast-request-btn approve"
                        onClick={() => approveJoinRequest(req.userID)}
                      >
                        <i className="fa-solid fa-check" />
                      </button>
                      <button
                        type="button"
                        className="sw-broadcast-request-btn deny"
                        onClick={() => denyJoinRequest(req.userID)}
                      >
                        <i className="fa-solid fa-times" />
                      </button>
                    </div>
                  </div>
                ))}
              </div>
            )}

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

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

        {/* End stream confirmation modal */}
        {showEndConfirm && (
          <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>

              <label className="sw-broadcast-checkbox">
                <input
                  type="checkbox"
                  checked={saveAsPost}
                  onChange={(e) => setSaveAsPost(e.target.checked)}
                />
                <span>Save as post on the map</span>
              </label>

              <div className="sw-broadcast-confirm-actions">
                <button
                  type="button"
                  className="sw-broadcast-btn secondary"
                  onClick={() => setShowEndConfirm(false)}
                >
                  Cancel
                </button>
                <button
                  type="button"
                  className="sw-broadcast-btn danger"
                  onClick={confirmEndStream}
                >
                  End Stream
                </button>
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
