// app/bereal-composer.jsx — Composer photo (caméra live + fallback pellicule)
// Loaded after bereal-overlays.jsx so it can use BrPhotoFrame.

function BrComposer({ prompt, onClose, onPublish }) {
  // Étape : "capture" (caméra) | "review" (preview + caption)
  const [step, setStep] = React.useState("capture");

  // Source : "camera" | "upload"
  const [source, setSource] = React.useState("camera");

  // Photo capturée (base64 data URL)
  const [photoUrl, setPhotoUrl] = React.useState(null);

  // Caption + name
  const [caption, setCaption] = React.useState("");
  const [name, setName] = React.useState(() => Store.get(BR_NAME_KEY, ""));

  // Caméra : refs + état
  const videoRef = React.useRef(null);
  const streamRef = React.useRef(null);
  const fileRef = React.useRef(null);
  const [cameraError, setCameraError] = React.useState(null);
  const [cameraReady, setCameraReady] = React.useState(false);

  // ─── Démarrage caméra ────────────────────────────────────────────────
  React.useEffect(() => {
    if (step !== "capture" || source !== "camera") return;
    let cancelled = false;

    async function start() {
      try {
        if (!navigator.mediaDevices?.getUserMedia) {
          throw new Error("Caméra non supportée par ce navigateur");
        }
        const stream = await navigator.mediaDevices.getUserMedia({
          video: { facingMode: { ideal: "environment" }, width: { ideal: 1080 }, height: { ideal: 1350 } },
          audio: false,
        });
        if (cancelled) { stream.getTracks().forEach(t => t.stop()); return; }
        streamRef.current = stream;
        if (videoRef.current) {
          videoRef.current.srcObject = stream;
          await videoRef.current.play().catch(() => {});
          setCameraReady(true);
        }
      } catch (e) {
        if (cancelled) return;
        setCameraError(e?.message || "Accès caméra bloqué");
        setSource("upload"); // bascule auto sur l'uploader
      }
    }
    start();

    return () => {
      cancelled = true;
      if (streamRef.current) {
        streamRef.current.getTracks().forEach(t => t.stop());
        streamRef.current = null;
      }
      setCameraReady(false);
    };
  }, [step, source]);

  // ─── Capture ─────────────────────────────────────────────────────────
  const capture = () => {
    const v = videoRef.current;
    if (!v || !v.videoWidth) return;
    const canvas = document.createElement("canvas");
    // Cible 4:5 portrait, max 1080 de hauteur
    const targetRatio = 4 / 5;
    const srcRatio = v.videoWidth / v.videoHeight;
    let sw, sh, sx, sy;
    if (srcRatio > targetRatio) {
      sh = v.videoHeight;
      sw = sh * targetRatio;
      sx = (v.videoWidth - sw) / 2;
      sy = 0;
    } else {
      sw = v.videoWidth;
      sh = sw / targetRatio;
      sx = 0;
      sy = (v.videoHeight - sh) / 2;
    }
    const dh = Math.min(1080, sh);
    const dw = dh * targetRatio;
    canvas.width = dw;
    canvas.height = dh;
    const ctx = canvas.getContext("2d");
    ctx.drawImage(v, sx, sy, sw, sh, 0, 0, dw, dh);
    const dataUrl = canvas.toDataURL("image/jpeg", 0.82);
    setPhotoUrl(dataUrl);
    setStep("review");
  };

  // ─── Upload pellicule ────────────────────────────────────────────────
  const onPickFile = (e) => {
    const f = e.target.files?.[0];
    if (!f) return;
    if (!f.type.startsWith("image/")) return;
    const reader = new FileReader();
    reader.onload = () => {
      setPhotoUrl(reader.result);
      setStep("review");
    };
    reader.readAsDataURL(f);
    e.target.value = "";
  };

  // ─── Publier ─────────────────────────────────────────────────────────
  const submit = () => {
    if (!photoUrl) return;
    Store.set(BR_NAME_KEY, name);
    onPublish({
      photo_url: photoUrl,
      photo_color: null,
      caption: caption.slice(0, 80).trim(),
      nom_invite: name.trim() || "Anonyme",
    });
  };

  const retake = () => {
    setPhotoUrl(null);
    setStep("capture");
    setSource("camera");
    setCameraError(null);
  };

  // ─── Render ─────────────────────────────────────────────────────────
  return (
    <div style={{
      position: "fixed", inset: 0, zIndex: 250, background: A.ink,
      display: "flex", flexDirection: "column",
      animation: "a-fade .25s ease both",
    }}>
      {/* Header */}
      <div style={{
        padding: "calc(14px + env(safe-area-inset-top)) 18px 14px",
        background: "rgba(0,0,0,0.6)",
        display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 14,
        borderBottom: "1px solid rgba(255,255,255,0.08)",
      }}>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontFamily: A.mono, fontSize: 8.5, letterSpacing: 2, color: A.or, fontWeight: 600 }}>
            PROMPT N° {prompt.numero || "★"} {prompt.id === "phila-secret" && <>· <Phila variant="head" size={12} style={{ marginRight: 3, verticalAlign: "-2px" }} />PHILA</>}
          </div>
          <div style={{ fontFamily: A.display, fontStyle: "italic", fontSize: 17, color: A.white, lineHeight: 1.15, marginTop: 3, textWrap: "balance" }}>
            "{prompt.question}"
          </div>
        </div>
        <button onClick={onClose} style={{
          width: 38, height: 38, borderRadius: "50%",
          background: "rgba(255,255,255,0.1)", color: A.white,
          border: "1px solid rgba(255,255,255,0.2)",
          fontSize: 22, lineHeight: 1, cursor: "pointer", flexShrink: 0,
        }} aria-label="Fermer">×</button>
      </div>

      {/* Body — capture ou review */}
      <div style={{
        flex: 1, overflow: "auto", padding: "16px 18px 24px",
        display: "flex", flexDirection: "column", gap: 14,
      }}>
        {step === "capture" ? (
          <CaptureStep
            source={source} setSource={setSource}
            videoRef={videoRef} cameraReady={cameraReady} cameraError={cameraError}
            capture={capture}
            fileRef={fileRef} onPickFile={onPickFile}
          />
        ) : (
          <ReviewStep
            photoUrl={photoUrl} retake={retake}
            caption={caption} setCaption={setCaption}
            name={name} setName={setName}
            submit={submit}
            isPhila={prompt.id === "phila-secret"}
          />
        )}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// Étape 1 : capture (caméra live ou pellicule)
// ─────────────────────────────────────────────────────────────────────────
function CaptureStep({ source, setSource, videoRef, cameraReady, cameraError, capture, fileRef, onPickFile }) {
  return (
    <>
      <div style={{
        flex: 1, minHeight: 280,
        background: "#0c0a08",
        position: "relative", overflow: "hidden",
        display: "flex", alignItems: "center", justifyContent: "center",
        aspectRatio: "4/5", maxHeight: "65vh", margin: "0 auto",
        width: "100%", maxWidth: 480,
        border: "1px solid rgba(255,255,255,0.08)",
      }}>
        {source === "camera" ? (
          <>
            <video ref={videoRef} playsInline muted style={{
              width: "100%", height: "100%", objectFit: "cover",
              opacity: cameraReady ? 1 : 0, transition: "opacity .3s",
            }}/>
            {!cameraReady && !cameraError && (
              <div style={{
                position: "absolute", inset: 0,
                display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 14,
                fontFamily: A.italic, fontStyle: "italic", fontSize: 14, color: "rgba(255,255,255,0.5)",
              }}>
                <div style={{ width: 32, height: 32, border: "2px solid rgba(255,255,255,0.18)", borderTopColor: A.or, borderRadius: "50%", animation: "br-spin 1s linear infinite" }}/>
                Démarrage de la caméra…
              </div>
            )}
            {/* Cadrage 4:5 indicator */}
            <div style={{
              position: "absolute", top: 8, left: 8,
              fontFamily: A.mono, fontSize: 8, letterSpacing: 1.5, color: "rgba(255,255,255,0.55)",
              background: "rgba(0,0,0,0.4)", padding: "3px 7px",
            }}>4:5 · CADRE PAPARAZZI</div>
          </>
        ) : (
          <div style={{
            display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 16,
            padding: 24, textAlign: "center",
          }}>
            <div style={{ fontSize: 48, color: A.or, lineHeight: 1 }}>✦</div>
            {cameraError && (
              <div style={{ fontFamily: A.italic, fontStyle: "italic", fontSize: 14, color: "rgba(255,255,255,0.7)", maxWidth: 260, lineHeight: 1.5 }}>
                L'accès caméra est bloqué dans la prévisualisation.
                <br/>
                <span style={{ fontFamily: A.mono, fontSize: 11, color: "rgba(255,255,255,0.4)", letterSpacing: 1 }}>
                  ({cameraError})
                </span>
                <br/><br/>
                Une fois l'app déployée, votre navigateur demandera l'autorisation.
                Pour l'instant, envoyez une photo depuis la pellicule.
              </div>
            )}
            {!cameraError && (
              <div style={{ fontFamily: A.italic, fontStyle: "italic", fontSize: 14, color: "rgba(255,255,255,0.7)", maxWidth: 240, lineHeight: 1.5 }}>
                Choisissez une image depuis votre téléphone.
              </div>
            )}
            <input ref={fileRef} type="file" accept="image/*" onChange={onPickFile} style={{ display: "none" }}/>
            <button onClick={() => fileRef.current?.click()} style={{
              padding: "14px 22px", background: A.or, color: A.ink, border: "none",
              fontFamily: A.mono, fontSize: 11, letterSpacing: 2.5, fontWeight: 600, textTransform: "uppercase",
              cursor: "pointer",
            }}>↑ Choisir une photo</button>
            {cameraError && (
              <button onClick={() => { setSource("camera"); }} style={{
                marginTop: 4, padding: "8px 14px", background: "transparent", color: "rgba(255,255,255,0.6)",
                border: "1px solid rgba(255,255,255,0.18)",
                fontFamily: A.mono, fontSize: 9, letterSpacing: 1.5, textTransform: "uppercase",
                cursor: "pointer",
              }}>Réessayer la caméra</button>
            )}
          </div>
        )}
      </div>

      {/* Actions */}
      {source === "camera" && (
        <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 16, marginTop: 4 }}>
          <button onClick={capture} disabled={!cameraReady} style={{
            width: 78, height: 78, borderRadius: "50%",
            background: A.white, color: A.ink,
            border: `4px solid ${A.or}`,
            cursor: cameraReady ? "pointer" : "not-allowed",
            opacity: cameraReady ? 1 : 0.5,
            transition: "transform .15s",
            display: "flex", alignItems: "center", justifyContent: "center",
            boxShadow: "0 6px 18px rgba(0,0,0,0.4)",
          }} onMouseDown={(e) => e.currentTarget.style.transform = "scale(.95)"}
             onMouseUp={(e) => e.currentTarget.style.transform = "scale(1)"}
             onMouseLeave={(e) => e.currentTarget.style.transform = "scale(1)"}
             aria-label="Capturer">
            <div style={{ width: 56, height: 56, borderRadius: "50%", background: A.or }}/>
          </button>
          <button onClick={() => setSource("upload")} style={{
            background: "transparent", border: "none", color: "rgba(255,255,255,0.55)",
            fontFamily: A.mono, fontSize: 9, letterSpacing: 1.8, cursor: "pointer", textTransform: "uppercase",
            padding: 4,
          }}>
            ou envoyer depuis la pellicule
          </button>
        </div>
      )}
    </>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// Étape 2 : review (preview + caption + nom + publish)
// ─────────────────────────────────────────────────────────────────────────
function ReviewStep({ photoUrl, retake, caption, setCaption, name, setName, submit, isPhila }) {
  const remaining = 80 - caption.length;
  return (
    <>
      <div style={{
        background: A.white, padding: "10px 10px 22px",
        boxShadow: "0 8px 24px rgba(0,0,0,0.3)",
        maxWidth: 360, margin: "0 auto", width: "100%",
        transform: "rotate(-1.5deg)",
      }}>
        <BrPhotoFrame post={{ photo_url: photoUrl }} />
        <div style={{ marginTop: 10, textAlign: "center", fontFamily: A.italic, fontStyle: "italic", fontSize: 14, color: A.ink, minHeight: 18 }}>
          {caption ? `"${caption}"` : <span style={{ color: A.inkMute, opacity: 0.5 }}>légende ci-dessous</span>}
        </div>
      </div>

      <div style={{ marginTop: 10, display: "flex", flexDirection: "column", gap: 12, maxWidth: 360, margin: "10px auto 0", width: "100%" }}>
        <button onClick={retake} style={{
          padding: "8px", background: "transparent", color: "rgba(255,255,255,0.55)",
          border: "1px solid rgba(255,255,255,0.2)",
          fontFamily: A.mono, fontSize: 9, letterSpacing: 1.8, cursor: "pointer", textTransform: "uppercase",
        }}>Refaire la photo</button>

        <input
          value={name} onChange={(e) => setName(e.target.value)}
          placeholder="Ton prénom (optionnel)"
          maxLength={32}
          style={{
            padding: "12px 14px",
            background: "rgba(255,255,255,0.06)", color: A.white,
            border: "1px solid rgba(255,255,255,0.15)",
            fontFamily: A.sans, fontSize: 14,
            outline: "none", borderRadius: 2,
          }}
        />

        <div style={{ position: "relative" }}>
          <input
            value={caption} onChange={(e) => setCaption(e.target.value.slice(0, 80))}
            placeholder="Une légende, 80 caractères max…"
            maxLength={80}
            style={{
              width: "100%", padding: "12px 14px 12px 14px", paddingRight: 50,
              background: "rgba(255,255,255,0.06)", color: A.white,
              border: "1px solid rgba(255,255,255,0.15)",
              fontFamily: A.italic, fontStyle: "italic", fontSize: 15,
              outline: "none", borderRadius: 2,
            }}
          />
          <div style={{
            position: "absolute", right: 12, top: "50%", transform: "translateY(-50%)",
            fontFamily: A.mono, fontSize: 9, color: remaining < 10 ? A.rouge : "rgba(255,255,255,0.4)",
          }}>{remaining}</div>
        </div>

        <button onClick={submit} style={{
          padding: "16px 24px", background: A.or, color: A.ink, border: "none",
          fontFamily: A.mono, fontSize: 12, letterSpacing: 2.5, fontWeight: 700, textTransform: "uppercase",
          cursor: "pointer", marginTop: 4,
        }}>
          {isPhila ? <><Phila variant="head" size={16} style={{ marginRight: 6, verticalAlign: "-3px" }} />Envoyer à Phila</> : "★ Publier sur le mur"}
        </button>
      </div>
    </>
  );
}

// Style d'animation pour le spinner
if (typeof document !== "undefined" && !document.getElementById("br-styles")) {
  const s = document.createElement("style");
  s.id = "br-styles";
  s.textContent = `
    @keyframes br-spin { to { transform: rotate(360deg); } }
  `;
  document.head.appendChild(s);
}

Object.assign(window, { BrComposer });
