// pages/CamerasPage.jsx

// ── LiveHlsPlayer ────────────────────────────────────────────────────────
// Player HLS reutilizável (desktop + mobile). Consome o proxy de portal
// /portal-cliente/api/cameras/:id/hls/index.m3u8 (autenticado por cookie de
// sessão do portal). Aplicado os mesmos aprendizados do player admin:
//   - prefere hls.js quando suportado (Chrome retorna canPlayType "maybe" mas
//     NÃO toca HLS nativo → vídeo preto). Native só como fallback iOS Safari.
//   - ordem: attachMedia → loadSource → startLoad(-1). Sem o startLoad(-1)
//     explícito o hls.js v1.6 fica em loop de playlist sem buscar segmento.
//   - retry em fragLoadError (câmera reconecta, ffmpeg reinicia numeração).
function LiveHlsPlayer({ cam, big }) {
  const videoRef = React.useRef(null);
  const [state, setState] = React.useState("loading"); // loading | playing | offline | error
  const [needTap, setNeedTap] = React.useState(false);

  React.useEffect(() => {
    if (!cam || !cam.hlsUrl) { setState("offline"); return; }
    // Câmera marcada offline pela lista → nem tenta abrir o stream.
    if (cam.online === false) { setState("offline"); return; }

    const video = videoRef.current;
    if (!video) return;
    const Hls = window.Hls;
    let destroyed = false;
    let hls = null;
    let recovery = 0;
    const MAX_RECOVERY = 4;

    const tryPlay = () => {
      const p = video.play();
      if (p && p.catch) p.catch(() => { setNeedTap(true); });
    };

    if (Hls && Hls.isSupported()) {
      hls = new Hls({
        backBufferLength: 10,
        maxBufferLength: 30,
        liveSyncDurationCount: 3,
        fragLoadingMaxRetry: 8,
        fragLoadingRetryDelay: 1000,
        manifestLoadingMaxRetry: 6,
        xhrSetup: (xhr) => { xhr.withCredentials = true; },
      });
      hls.on(Hls.Events.MANIFEST_PARSED, () => { if (!destroyed) { setState("playing"); tryPlay(); } });
      hls.on(Hls.Events.ERROR, (_e, data) => {
        if (destroyed) return;
        if (!data.fatal) {
          if (data.details === "fragLoadError" && data.response && data.response.code >= 400) {
            setTimeout(() => { if (!destroyed) { try { hls.stopLoad(); hls.startLoad(-1); } catch (e) {} } }, 1000);
          }
          return;
        }
        if (recovery < MAX_RECOVERY) {
          recovery += 1;
          try {
            if (data.type === Hls.ErrorTypes.NETWORK_ERROR) hls.startLoad();
            else if (data.type === Hls.ErrorTypes.MEDIA_ERROR) hls.recoverMediaError();
            else hls.startLoad();
            return;
          } catch (e) { /* fall through */ }
        }
        setState("offline");
      });
      hls.attachMedia(video);
      hls.loadSource(cam.hlsUrl);
      setTimeout(() => { if (!destroyed) { try { hls.startLoad(-1); } catch (e) {} } }, 100);
    } else if (video.canPlayType("application/vnd.apple.mpegurl")) {
      // iOS Safari — HLS nativo.
      video.src = cam.hlsUrl;
      video.addEventListener("loadedmetadata", () => { if (!destroyed) { setState("playing"); tryPlay(); } });
      video.addEventListener("error", () => { if (!destroyed) setState("offline"); });
    } else {
      setState("error");
    }

    return () => {
      destroyed = true;
      if (hls) { try { hls.destroy(); } catch (e) {} }
      try { video.removeAttribute("src"); video.load(); } catch (e) {}
    };
  }, [cam && cam.camId, cam && cam.online]);

  return (
    <div className="cam" style={big ? { aspectRatio: "16/9" } : {}}>
      <video
        ref={videoRef}
        muted
        playsInline
        autoPlay
        style={{ width: "100%", height: "100%", objectFit: "cover", display: state === "playing" ? "block" : "none", background: "#000" }}
        onClick={() => { const v = videoRef.current; if (v) { v.play().then(() => setNeedTap(false)).catch(() => {}); } }}
      />
      {state !== "playing" && (
        <React.Fragment>
          <div className="cam-stripes" />
          <div className="cam-label-center">
            {state === "loading" ? "conectando ao vivo…" :
             state === "offline" ? "câmera offline no momento" :
             "stream indisponível"}
          </div>
        </React.Fragment>
      )}
      {needTap && state === "playing" && (
        <div className="cam-label-center" style={{ cursor: "pointer" }}
             onClick={() => { const v = videoRef.current; if (v) { v.play().then(() => setNeedTap(false)).catch(() => {}); } }}>
          ▶ toque para reproduzir
        </div>
      )}
      <div className="cam-overlay">
        <div className="cam-top">
          <div className="cam-tag">
            <span className="status-dot live" style={{ background: state === "playing" ? "#16a34a" : "#ff5e5e" }} />
            <span className="cam-live">{state === "playing" ? "LIVE" : "OFF"}</span>
          </div>
          <div className="cam-tag">{cam.id}</div>
        </div>
        <div>
          <div className="cam-name">{cam.name}</div>
          <div className="cam-bot">
            <span>{cam.zone}</span>
            <span>{new Date().toLocaleTimeString("pt-BR")}</span>
          </div>
        </div>
      </div>
    </div>
  );
}
window.LiveHlsPlayer = LiveHlsPlayer;

function CamerasPage() {
  const [focus, setFocus] = React.useState(null);

  const Cam = ({ cam, big }) => (
    <div onClick={() => setFocus(cam)} style={{ cursor: "pointer" }}>
      <LiveHlsPlayer cam={cam} big={big} />
    </div>
  );

  if (CAMERAS.length === 0) {
    return (
      <div className="page">
        <div className="page-header">
          <div>
            <h1 className="page-title">Cameras ao vivo</h1>
            <div className="page-sub">Transmissao da obra</div>
          </div>
        </div>
        <div className="card" style={{ padding: 40, textAlign: "center", color: "#999" }}>
          Nenhuma camera cadastrada nesta obra. Quando seu engenheiro habilitar cameras no canteiro, elas aparecerao aqui em tempo real.
        </div>
      </div>
    );
  }

  const onlineCount = CAMERAS.filter(c => c.online).length;

  return (
    <div className="page" style={{ maxWidth: "none" }}>
      <div className="page-header">
        <div>
          <h1 className="page-title">Cameras ao vivo</h1>
          <div className="page-sub">{CAMERAS.length} camera{CAMERAS.length !== 1 ? "s" : ""} · transmissao em tempo real</div>
        </div>
        <div className="page-actions">
          <span className="pill green"><span className="status-dot live" style={{ background: "#16a34a" }} />{onlineCount} online</span>
        </div>
      </div>

      {CAMERAS.length >= 3 ? (
        <div className="grid" style={{ gridTemplateColumns: "2fr 1fr", gap: 12, marginBottom: 12 }}>
          <Cam cam={CAMERAS[0]} big />
          <div style={{ display: "grid", gridTemplateRows: "1fr 1fr", gap: 12 }}>
            <Cam cam={CAMERAS[1]} />
            <Cam cam={CAMERAS[2]} />
          </div>
        </div>
      ) : (
        <div className="grid" style={{ gridTemplateColumns: CAMERAS.length === 2 ? "1fr 1fr" : "1fr", gap: 12, marginBottom: 12 }}>
          {CAMERAS.map(c => <Cam key={c.id} cam={c} big />)}
        </div>
      )}
      {CAMERAS.length > 3 && (
        <div className="grid grid-3" style={{ gap: 12 }}>
          {CAMERAS.slice(3).map(c => <Cam key={c.id} cam={c} />)}
        </div>
      )}

      {focus && (
        <div className="modal-backdrop" onClick={() => setFocus(null)}>
          <div className="modal" onClick={e => e.stopPropagation()}>
            <div className="modal-head">
              <div>
                <div style={{ fontSize: 14, fontWeight: 600 }}>{focus.name}</div>
                <div className="mono" style={{ fontSize: 11, color: "#999", marginTop: 2 }}>{focus.id} · {focus.zone}</div>
              </div>
              <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                <span className="pill green"><span className="status-dot live" style={{ background: focus.online ? "#16a34a" : "#ff5e5e" }} />{focus.online ? "LIVE" : "OFF"}</span>
                <button className="icon-btn" onClick={() => setFocus(null)}><I.X size={14} /></button>
              </div>
            </div>
            <div className="modal-body" style={{ padding: 0 }}>
              <LiveHlsPlayer cam={focus} big />
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

window.CamerasPage = CamerasPage;
