// Film management panel. Edit up to 40 films live — image, video link,
// film type, company logo, name/location — persisted to localStorage.
function THFilmAdmin({ onClose }) {
  const MAX = 40;
  const [list, setList] = React.useState(() => (window.loadSaysoFilms ? window.loadSaysoFilms() : []).map((f) => ({ ...f })));
  const upd = (i, k, v) => setList((l) => l.map((f, j) => (j === i ? { ...f, [k]: v } : f)));
  const add = () => setList((l) => (l.length >= MAX ? l : [...l, { img: "", video: "", logo: "", client: "", proj: "", loc: "", dark: true, wide: false, lh: 24 }]));
  const move = (i, d) => setList((l) => {
    const j = i + d; if (j < 0 || j >= l.length) return l;
    const n = l.slice(); const t = n[i]; n[i] = n[j]; n[j] = t; return n;
  });
  // Locally-uploaded videos become blob: object URLs, which are valid ONLY for
  // the current document — they break on refresh and must never be persisted as
  // if they were durable. We keep them for this-session preview, track them so
  // they can be revoked (on replace / delete / unmount), and block Save when any
  // remain so nothing that breaks after refresh is ever written to storage.
  const blobUrls = React.useRef(new Set());
  const isBlob = (v) => typeof v === "string" && v.indexOf("blob:") === 0;
  const revoke = (v) => { if (isBlob(v)) { try { URL.revokeObjectURL(v); } catch (_) {} blobUrls.current.delete(v); } };
  const onVideoFile = (i, file) => {
    if (!file) return;
    setList((l) => l.map((f, j) => {
      if (j !== i) return f;
      revoke(f.video);                         // release the previous upload, if any
      const u = URL.createObjectURL(file);
      blobUrls.current.add(u);
      return { ...f, video: u };
    }));
  };
  const del = (i) => setList((l) => { revoke(l[i] && l[i].video); return l.filter((_, j) => j !== i); });
  React.useEffect(() => () => { blobUrls.current.forEach((u) => { try { URL.revokeObjectURL(u); } catch (_) {} }); blobUrls.current.clear(); }, []);
  // Uploaded files used to go straight into localStorage as full-resolution
  // base64 (a single photo can be several MB raw). That fills the ~5MB
  // per-origin quota after just a handful of films, so every later save
  // silently fails and the page quietly reverts to old data. Downscale +
  // re-encode on upload so a whole library of films fits comfortably.
  const compressImage = (file, maxDim, quality, mime) => new Promise((resolve) => {
    const url = URL.createObjectURL(file);
    const img = new Image();
    img.onload = () => {
      let { width, height } = img;
      if (width > maxDim || height > maxDim) {
        const scale = maxDim / Math.max(width, height);
        width = Math.max(1, Math.round(width * scale));
        height = Math.max(1, Math.round(height * scale));
      }
      const canvas = document.createElement("canvas");
      canvas.width = width; canvas.height = height;
      canvas.getContext("2d").drawImage(img, 0, 0, width, height);
      URL.revokeObjectURL(url);
      resolve(canvas.toDataURL(mime, quality));
    };
    img.onerror = () => { URL.revokeObjectURL(url); resolve(null); };
    img.src = url;
  });
  const readThumb = (file, cb) => compressImage(file, 720, 0.74, "image/jpeg").then((d) => d && cb(d));
  const readLogo = (file, cb) => compressImage(file, 200, 1, "image/png").then((d) => d && cb(d));
  const save = () => {
    // Never silently persist a blob: video URL that will break after refresh.
    const blobFilms = list
      .map((f, i) => (isBlob(f.video) ? i + 1 : 0))
      .filter(Boolean);
    if (blobFilms.length) {
      alert(
        "Uploaded video files can't be saved permanently in this prototype — a " +
        "locally-uploaded video only works until you refresh.\n\n" +
        "Film(s) " + blobFilms.join(", ") + " still use an uploaded file. Please " +
        "replace the video with a hosted link (a Vimeo URL or a direct MP4 URL) " +
        "before saving, so it survives a refresh.\n\n" +
        "Nothing was saved."
      );
      return;
    }
    const persisted = window.saveSaysoFilms(list);
    if (!persisted) {
      alert("Films updated for this session, but couldn't be saved to browser storage (still full even after compression). Refreshing the page will lose these changes — delete a few unused films or replace some images with URLs instead of uploads to free room.");
    }
    onClose();
  };
  const reset = () => { if (window.SAYSO_FILMS_DEFAULT) setList(window.SAYSO_FILMS_DEFAULT.map((f) => ({ ...f }))); };

  // ── Backup / Restore ──────────────────────────────────────────────
  // The single most important safeguard against losing work: your films
  // (including uploaded images, encoded inside the file) can be downloaded
  // as one .json file you keep on your computer, and restored anytime —
  // on any browser, any machine. Browser storage is a convenience cache;
  // this file is the real backup.
  const downloadBackup = () => {
    const stamp = new Date().toISOString().slice(0, 16).replace(/[:T]/g, "-");
    const blob = new Blob([JSON.stringify(list, null, 2)], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = `sayso-films-backup-${stamp}.json`;
    document.body.appendChild(a); a.click(); a.remove();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
  };
  const restoreRef = React.useRef(null);
  const restoreBackup = (file) => {
    const r = new FileReader();
    r.onload = () => {
      try {
        const data = JSON.parse(r.result);
        if (Array.isArray(data) && data.length) {
          setList(data.map((f) => ({ ...f })));
          alert(`Restored ${data.length} films from backup. Click Save to keep them.`);
        } else { alert("That file doesn't look like a films backup."); }
      } catch (e) { alert("Couldn't read that backup file."); }
    };
    r.readAsText(file);
  };

  return (
    <div className="th-adm" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="th-adm-panel">
        <div className="th-adm-head">
          <div>
            <h3>Manage films</h3>
            <div className="sub">{list.length} / {MAX} films · Download a backup to keep your work safe</div>
          </div>
          <button className="th-adm-x" type="button" aria-label="Close" onClick={onClose}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18" /></svg>
          </button>
        </div>
        <div className="th-adm-body">
          {list.map((f, i) => (
            <div className="th-adm-card" key={i}>
              <div className="th-adm-thumb">
                {f.img ? <img src={f.img} alt="" /> : <span>No image</span>}
              </div>
              <div className="th-adm-fields">
                <div>
                  <label>Ordering company</label>
                  <input type="text" value={f.client || ""} placeholder="e.g. Nayax" onChange={(e) => upd(i, "client", e.target.value)} />
                </div>
                <div className="th-adm-row">
                  <div style={{ flex: 1 }}>
                    <label>Filmed company</label>
                    <input type="text" value={f.proj || ""} placeholder="Customer" onChange={(e) => upd(i, "proj", e.target.value)} />
                  </div>
                  <div style={{ flex: 1 }}>
                    <label>Location</label>
                    <input type="text" value={f.loc || ""} placeholder="Berlin, DE" onChange={(e) => upd(i, "loc", e.target.value)} />
                  </div>
                </div>
                <div>
                  <label>Video — paste a Vimeo/YouTube/MP4 link or upload a file</label>
                  <input type="url" value={typeof f.video === "string" && f.video.indexOf("blob:") !== 0 ? f.video : ""} placeholder="https://vimeo.com/… or MP4 URL" onChange={(e) => upd(i, "video", e.target.value)} />
                  <input className="th-adm-file" type="file" accept="video/*" onChange={(e) => onVideoFile(i, e.target.files[0])} />
                  {typeof f.video === "string" && f.video.indexOf("blob:") === 0 && <span className="th-adm-file" style={{ color: "var(--brand-700)" }}>Uploaded preview — not saved. Paste a Vimeo/MP4 URL to keep it.</span>}
                </div>
                <div>
                  <label>Thumbnail image</label>
                  <input type="url" value={typeof f.img === "string" && f.img.indexOf("data:") !== 0 ? f.img : ""} placeholder="https://… or upload →" onChange={(e) => upd(i, "img", e.target.value)} />
                  <input className="th-adm-file" type="file" accept="image/*" onChange={(e) => e.target.files[0] && readThumb(e.target.files[0], (d) => upd(i, "img", d))} />
                </div>
                <div>
                  <label>Ordering company logo</label>
                  <input type="url" value={typeof f.logo === "string" && f.logo.indexOf("data:") !== 0 ? f.logo : ""} placeholder="https://… or upload →" onChange={(e) => upd(i, "logo", e.target.value)} />
                  <input className="th-adm-file" type="file" accept="image/*" onChange={(e) => e.target.files[0] && readLogo(e.target.files[0], (d) => upd(i, "logo", d))} />
                </div>
                <div className="th-adm-toggles">
                  <label><input type="checkbox" checked={!!f.wide} onChange={(e) => upd(i, "wide", e.target.checked)} /> Landscape (16:9)</label>
                  <label><input type="checkbox" checked={f.dark !== false} onChange={(e) => upd(i, "dark", e.target.checked)} /> Dark background</label>
                </div>
                <div className="th-adm-toggles">
                  <button className="th-adm-ghost" type="button" onClick={() => move(i, -1)}>↑ Up</button>
                  <button className="th-adm-ghost" type="button" onClick={() => move(i, 1)}>↓ Down</button>
                  <button className="th-adm-del" type="button" onClick={() => del(i)}>Delete</button>
                </div>
              </div>
            </div>
          ))}
        </div>
        <div className="th-adm-foot">
          <button className="th-adm-add" type="button" onClick={add} disabled={list.length >= MAX}>+ Add film</button>
          <button className="th-adm-ghost" type="button" onClick={downloadBackup}>⬇ Download backup</button>
          <button className="th-adm-ghost" type="button" onClick={() => restoreRef.current && restoreRef.current.click()}>⬆ Restore backup</button>
          <input ref={restoreRef} type="file" accept="application/json,.json" style={{ display: "none" }} onChange={(e) => e.target.files[0] && restoreBackup(e.target.files[0])} />
          <button className="th-adm-ghost" type="button" onClick={reset}>Reset to defaults</button>
          <button className="th-adm-save" type="button" onClick={save}>Save</button>
        </div>
      </div>
    </div>
  );
}

window.THFilmAdmin = THFilmAdmin;
