/* studio.jsx — Studio/Thợ flow: project dashboard + project workspace
   with drag-drop upload to (mock) Cloudflare R2. */

function CoverMosaic({ project, store }) {
  const photos = store.projectPhotos(project.id).slice(0, 4);
  if (photos.length === 0) return <div style={{ position: "absolute", inset: 0, background: project.cover }} />;
  return (
    <div className="pc-mosaic">
      {[0, 1, 2].map((i) => {
        const p = photos[i] || photos[0];
        return <div key={i} style={{ backgroundImage: `url(${store.src(p)})` }} />;
      })}
    </div>
  );
}

function ProjectCard({ project, store, onOpen }) {
  const photos = store.projectPhotos(project.id);
  const picked = photos.filter((p) => p.status === "pick" || (p.picks || 0) > 0).length;
  const reviewed = photos.filter((p) => p.stars > 0 || p.status !== "none" || p.liked || (p.picks || 0) > 0 || (p.likes || 0) > 0).length;
  const pct = photos.length ? Math.round((reviewed / photos.length) * 100) : 0;
  const d = new Date(project.date);
  const dateStr = d.toLocaleDateString("vi-VN", { day: "2-digit", month: "long", year: "numeric" });
  return (
    <div className="project-card" onClick={onOpen}>
      <div className="project-cover">
        <CoverMosaic project={project} store={store} />
        <div className="pc-veil" />
        <span className="pc-date">{dateStr}</span>
      </div>
      <div className="project-body">
        <div className="project-name">{project.name}</div>
        <div className="project-meta">
          <span>{photos.length} ảnh</span><span className="dot" />
          <span style={{ color: "var(--accent)", fontWeight: 600 }}>{picked} đã chọn</span><span className="dot" />
          <span>{(project.guests || []).length} khách</span>
        </div>
        <div className="project-progress"><div style={{ width: pct + "%" }} /></div>
        <div style={{ fontSize: 11.5, color: "var(--ink-3)", marginTop: 7 }}>{pct}% đã duyệt</div>
      </div>
    </div>
  );
}

function NewProjectModal({ store, onClose, onCreated }) {
  const [name, setName] = React.useState("");
  const [couple, setCouple] = React.useState("");
  const [date, setDate] = React.useState("2026-07-01");
  const [cover, setCover] = React.useState(COVERS[0]);
  const create = async () => {
    if (!name.trim()) return;
    const id = await store.addProject({ name: name.trim(), couple: couple.trim(), date, cover });
    onCreated(id);
  };
  return (
    <Modal onClose={onClose}>
      <div className="modal-head"><h2>Project mới</h2><p>Tạo bộ ảnh để upload và gửi khách chọn.</p></div>
      <div className="modal-body">
        <div className="input-group"><label>Tên project</label>
          <input value={name} onChange={(e) => setName(e.target.value)} placeholder="VD: Linh & Quân — Wedding" autoFocus /></div>
        <div className="input-group"><label>Tên khách / cặp đôi (tuỳ chọn)</label>
          <input value={couple} onChange={(e) => setCouple(e.target.value)} placeholder="VD: Minh Linh · Đăng Quân" /></div>
        <div style={{ display: "flex", gap: 14 }}>
          <div className="input-group" style={{ flex: 1 }}><label>Ngày chụp / cưới</label>
            <input type="date" value={date} onChange={(e) => setDate(e.target.value)} /></div>
        </div>
        <div className="input-group"><label>Màu bìa</label>
          <div className="cover-picker">
            {COVERS.map((c) => <div key={c} className={"cover-swatch" + (cover === c ? " on" : "")} style={{ background: c }} onClick={() => setCover(c)} />)}
          </div></div>
      </div>
      <div className="modal-foot">
        <button className="btn btn-ghost" onClick={onClose}>Huỷ</button>
        <button className="btn btn-primary" onClick={create} disabled={!name.trim()}><Icon name="plus" size={16} /> Tạo project</button>
      </div>
    </Modal>
  );
}

function StudioDashboard({ store, onOpen }) {
  const [modal, setModal] = React.useState(false);
  return (
    <div className="page">
      <div className="page-head">
        <div>
          <div className="eyebrow">Studio · Bảng điều khiển</div>
          <h1 className="page-title">Các bộ ảnh của bạn</h1>
          <p className="page-sub">Tạo project, tải ảnh lên Cloudflare R2 và gửi khách hàng tự chọn.</p>
        </div>
        <button className="btn btn-primary btn-lg" onClick={() => setModal(true)}><Icon name="plus" size={18} /> Project mới</button>
      </div>
      <div className="project-grid">
        <div className="new-project-card" onClick={() => setModal(true)}>
          <div className="npc-inner"><Icon name="plus" size={28} /> Tạo project mới</div>
        </div>
        {store._data.projects.map((p) => (
          <ProjectCard key={p.id} project={p} store={store} onOpen={() => onOpen(p.id)} />
        ))}
      </div>
      {modal && <NewProjectModal store={store} onClose={() => setModal(false)} onCreated={(id) => { setModal(false); onOpen(id); }} />}
    </div>
  );
}

/* ---- Upload ---- */
function UploadTray({ items, onClose }) {
  const done = items.filter((i) => i.done).length;
  return (
    <div className="upload-tray">
      <div className="upload-tray-head">
        <span><Icon name="cloud" size={15} style={{ verticalAlign: "-2px", marginRight: 6, color: "var(--accent)" }} />
          Tải lên R2 · {done}/{items.length}</span>
        {done === items.length && <button className="icon-btn" style={{ width: 26, height: 26 }} onClick={onClose}><Icon name="close" size={16} /></button>}
      </div>
      <div style={{ maxHeight: 220, overflowY: "auto" }}>
        {items.map((it, i) => (
          <div className="upload-row" key={i}>
            {it.thumb ? <img className="upload-thumb" src={it.thumb} alt="" /> : <div className="upload-thumb" />}
            <div style={{ flex: 1, minWidth: 0 }}>
              <div className="ur-name">{it.name}</div>
              <div className="ur-bar"><div style={{ width: (it.done ? 100 : it.pct) + "%" }} /></div>
            </div>
            {it.done && <Icon name="check" size={17} className="ur-ok" />}
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---- Export ảnh khách đã chọn (cho Adobe Bridge) ---- */
function downloadText(filename, text) {
  const blob = new Blob([text], { type: "text/plain;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url; a.download = filename; document.body.appendChild(a); a.click();
  a.remove(); setTimeout(() => URL.revokeObjectURL(url), 1500);
}

// Sinh script ExtendScript cho Bridge: gắn 5 sao + select các ảnh theo tên file.
function bridgeScript(names, projectName) {
  const entries = names.map((n) => "    " + JSON.stringify(n) + ": true").join(",\n");
  return [
    "// chosepick — chọn ảnh khách đã pick trong Adobe Bridge",
    "// Project: " + (projectName || ""),
    "// CÁCH DÙNG: mở thư mục ẢNH GỐC trong Bridge → Tools > Browse... rồi chạy file .jsx này",
    "//   (hoặc kéo .jsx vào cửa sổ Bridge / chạy bằng ExtendScript Toolkit, #target là bridge).",
    "// Tác dụng: gắn RATING 5 sao + select các ảnh khớp tên → lọc 5 sao ở panel Filter để edit.",
    "#target bridge",
    "(function () {",
    "  var wanted = {",
    entries,
    "  };",
    "  function base(s){ return String(s).replace(/\\.[^.]+$/, '').toLowerCase(); }",
    "  var keys = {}; for (var k in wanted) keys[base(k)] = true;",
    "  var doc = app.document;",
    "  if (!doc) { alert('Hãy mở thư mục ảnh trong Bridge trước.'); return; }",
    "  var ths = doc.thumbnails; var sel = [], n = 0;",
    "  for (var i = 0; i < ths.length; i++) {",
    "    if (keys[base(ths[i].name)]) { try { ths[i].rating = 5; } catch (e) {} sel.push(ths[i]); n++; }",
    "  }",
    "  if (sel.length) doc.selections = sel;",
    "  alert('Đã chọn & gắn 5 sao cho ' + n + ' / ' + ths.length + ' ảnh.\\nLọc theo 5 sao ở panel Filter.');",
    "})();",
    "",
  ].join("\n");
}

function ExportPicksModal({ store, projectId, onClose }) {
  const project = store.project(projectId);
  const photos = store.projectPhotos(projectId);
  const toast = useToast();
  // "đã chọn" = khách pick (picks>0) hoặc chính studio pick
  const chosen = photos.filter((p) => (p.picks || 0) > 0 || p.status === "pick");
  const names = chosen.map((p) => p.filename);
  const txt = names.join("\n");
  const slug = (project.name || "album").replace(/[^\w]+/g, "_").replace(/^_+|_+$/g, "") || "album";

  return (
    <Modal onClose={onClose} max={540}>
      <div className="modal-head">
        <h2>Xuất ảnh đã chọn</h2>
        <p>{names.length} ảnh được chọn trong “{project.name}” — để lọc & edit trong Adobe Bridge.</p>
      </div>
      <div className="modal-body">
        {names.length === 0 ? (
          <div style={{ fontSize: 13.5, color: "var(--ink-3)", padding: "10px 2px" }}>
            Chưa có ảnh nào được chọn. Khi khách bấm “Chọn” cho ảnh, danh sách sẽ hiện ở đây.
          </div>
        ) : (
          <>
            <textarea readOnly value={txt} onFocus={(e) => e.target.select()}
              style={{ width: "100%", height: 150, padding: "10px 12px", borderRadius: 10, border: "1px solid var(--line)", background: "var(--surface-2)", color: "var(--ink-1)", fontSize: 12.5, fontFamily: "ui-monospace, monospace", resize: "vertical", outline: "none" }} />
            <div style={{ display: "flex", gap: 8, marginTop: 12, flexWrap: "wrap" }}>
              <button className="btn btn-ghost btn-sm" onClick={() => { try { navigator.clipboard.writeText(txt); } catch (e) {} toast("Đã copy " + names.length + " tên file", "check"); }}>
                <Icon name="download" size={15} /> Copy danh sách
              </button>
              <button className="btn btn-ghost btn-sm" onClick={() => downloadText(slug + "_da_chon.txt", txt)}>
                <Icon name="download" size={15} /> Tải .txt
              </button>
              <button className="btn btn-primary btn-sm" onClick={() => downloadText(slug + "_bridge_select.jsx", bridgeScript(names, project.name))}>
                <Icon name="check" size={15} /> Tải script Bridge (.jsx)
              </button>
            </div>
            <div style={{ marginTop: 14, fontSize: 12.5, color: "var(--ink-3)", lineHeight: 1.6 }}>
              <b style={{ color: "var(--ink-2)" }}>Dùng trong Bridge:</b> mở thư mục ảnh gốc → menu <i>Tools → Browse in Bridge</i> đã mở sẵn thư mục →
              chạy file <code>.jsx</code> (Bridge: <i>Tools</i> hoặc kéo thả). Script tự gắn <b>5 sao</b> + chọn đúng các ảnh,
              rồi bạn lọc <b>★★★★★</b> ở panel Filter để edit. So khớp theo tên (bỏ phần đuôi, không phân biệt hoa thường).
            </div>
          </>
        )}
      </div>
      <div className="modal-foot"><button className="btn btn-primary" onClick={onClose}>Xong</button></div>
    </Modal>
  );
}

function StudioProjectView({ projectId, store, onBack }) {
  const project = store.project(projectId);
  const photos = store.projectPhotos(projectId);
  const [drag, setDrag] = React.useState(false);
  const [tray, setTray] = React.useState(null);
  const [albumModal, setAlbumModal] = React.useState(false);
  const [shareModal, setShareModal] = React.useState(false);
  const [exportModal, setExportModal] = React.useState(false);
  const fileRef = React.useRef();
  const toast = useToast();

  const pickCount = photos.filter((p) => p.status === "pick" || (p.picks || 0) > 0).length;

  const handleFiles = async (fileList) => {
    const files = [...fileList].filter((f) => f.type.startsWith("image/"));
    if (!files.length) return;
    const items = files.map((f) => ({ name: f.name, pct: 0, done: false, thumb: null }));
    setTray(items);
    const albumId = project.albums[0].id;
    // simulate progressive R2 upload UI
    let idx = 0;
    const tick = setInterval(() => {
      setTray((t) => t && t.map((it, i) => i === idx && !it.done ? { ...it, pct: Math.min(95, it.pct + 18) } : it));
    }, 120);
    await store.addUploads(projectId, albumId, files, (done, total, name) => {
      idx = done;
      setTray((t) => t && t.map((it, i) => i < done ? { ...it, done: true, pct: 100 } : it));
    });
    clearInterval(tick);
    setTray((t) => t && t.map((it) => ({ ...it, done: true, pct: 100 })));
    toast(`Đã tải ${files.length} ảnh lên R2`, "cloud");
    setTimeout(() => setTray(null), 2600);
  };

  return (
    <div className="page">
      <input ref={fileRef} type="file" accept="image/*" multiple style={{ display: "none" }}
        onChange={(e) => { handleFiles(e.target.files); e.target.value = ""; }} />

      <div className="page-head">
        <div>
          <div className="breadcrumb" style={{ marginBottom: 10 }}>
            <button onClick={onBack}>Studio</button><span className="sep">/</span><span className="crumb-current">{project.name}</span>
          </div>
          <h1 className="page-title">{project.name}</h1>
          <p className="page-sub">{project.couple || "—"} · {photos.length} ảnh · <span style={{ color: "var(--accent)", fontWeight: 600 }}>{pickCount} ảnh khách đã chọn để chỉnh sửa</span></p>
        </div>
        <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
          <span className="r2-pill"><span className="dot-live" /> {(window.cpConfigured && window.cpConfigured()) ? "Cloudflare R2 · đã kết nối" : "Chế độ demo · chưa nối R2"}</span>
          <button className="btn btn-ghost" onClick={() => setShareModal(true)}><Icon name="user" size={16} /> Chia sẻ &amp; quyền</button>
          <button className="btn btn-ghost" onClick={() => setExportModal(true)}><Icon name="download" size={16} /> Xuất ảnh đã chọn</button>
          <button className="btn btn-ghost" onClick={() => setAlbumModal(true)}><Icon name="folder" size={16} /> Thêm album</button>
          <button className="btn btn-primary" onClick={() => fileRef.current.click()}><Icon name="upload" size={16} /> Tải ảnh lên</button>
        </div>
      </div>

      {photos.length === 0 ? (
        <div className={"dropzone" + (drag ? " drag" : "")}
          onDragOver={(e) => { e.preventDefault(); setDrag(true); }}
          onDragLeave={() => setDrag(false)}
          onDrop={(e) => { e.preventDefault(); setDrag(false); handleFiles(e.dataTransfer.files); }}
          onClick={() => fileRef.current.click()}>
          <Icon name="cloud" size={46} className="dz-ic" sw={1.3} />
          <h3>Kéo thả ảnh vào đây</h3>
          <p>Hoặc bấm để chọn ảnh từ máy. Ảnh được tải lên Cloudflare R2.</p>
          <div className="dz-hint">JPG · PNG · WEBP — không giới hạn số lượng</div>
        </div>
      ) : (
        <div onDragOver={(e) => { e.preventDefault(); setDrag(true); }} onDragLeave={() => setDrag(false)}
          onDrop={(e) => { e.preventDefault(); setDrag(false); handleFiles(e.dataTransfer.files); }}
          style={drag ? { outline: "2px dashed var(--accent)", outlineOffset: 8, borderRadius: 16 } : null}>
          <Gallery projectId={projectId} store={store} role="studio" />
        </div>
      )}

      {tray && <UploadTray items={tray} onClose={() => setTray(null)} />}
      {albumModal && <AlbumModal store={store} projectId={projectId} onClose={() => setAlbumModal(false)} />}
      {shareModal && <ShareModal store={store} projectId={projectId} onClose={() => setShareModal(false)} />}
      {exportModal && <ExportPicksModal store={store} projectId={projectId} onClose={() => setExportModal(false)} />}
    </div>
  );
}

function ShareModal({ store, projectId, onClose }) {
  const project = store.project(projectId);
  const [name, setName] = React.useState("");
  const [email, setEmail] = React.useState("");
  const toast = useToast();
  const copy = () => { try { navigator.clipboard.writeText(project.code); } catch (e) {} toast("Đã copy mã " + project.code, "check"); };
  const invite = () => { if (!name.trim()) return; store.addGuest(projectId, { name: name.trim(), email: email.trim() }); setName(""); setEmail(""); toast("Đã mời " + name.trim(), "user"); };
  const guests = project.guests || [];
  return (
    <Modal onClose={onClose} max={470}>
      <div className="modal-head"><h2>Chia sẻ &amp; quyền truy cập</h2><p>Cô dâu chú rể chỉ vào được album này khi có mã bên dưới.</p></div>
      <div className="modal-body">
        <div className="share-code">
          <div><div className="sc-label">Mã truy cập album</div><div className="sc-code">{project.code}</div></div>
          <button className="btn btn-ghost btn-sm" onClick={copy}><Icon name="download" size={15} /> Copy mã</button>
        </div>
        <div>
          <label style={{ display: "block", fontSize: 12.5, fontWeight: 700, color: "var(--ink-2)", marginBottom: 9 }}>Khách được mời ({guests.length})</label>
          <div className="guest-list">
            {guests.map((g) => (
              <div className="guest-row" key={g.email || g.name}>
                <Avatar name={g.name} size={32} role="client" />
                <div style={{ flex: 1, minWidth: 0 }}><div className="gr-name">{g.name}</div><div className="gr-email">{g.email || "—"}</div></div>
                <button className="icon-btn" style={{ width: 32, height: 32 }} title="Gỡ quyền" onClick={() => store.removeGuest(projectId, g.email)}><Icon name="trash" size={16} /></button>
              </div>
            ))}
            {guests.length === 0 && <div style={{ fontSize: 13, color: "var(--ink-3)", padding: "8px 2px" }}>Chưa mời ai. Khách vẫn vào được bằng mã ở trên.</div>}
          </div>
          <div className="invite-row">
            <input placeholder="Tên khách" value={name} onChange={(e) => setName(e.target.value)} />
            <input placeholder="Email (tuỳ chọn)" value={email} onChange={(e) => setEmail(e.target.value)} onKeyDown={(e) => e.key === "Enter" && invite()} />
            <button className="btn btn-primary btn-sm" onClick={invite} disabled={!name.trim()}><Icon name="plus" size={16} /></button>
          </div>
        </div>
      </div>
      <div className="modal-foot"><button className="btn btn-primary" onClick={onClose}>Xong</button></div>
    </Modal>
  );
}

function AlbumModal({ store, projectId, onClose }) {
  const [name, setName] = React.useState("");
  return (
    <Modal onClose={onClose} max={400}>
      <div className="modal-head"><h2>Thêm album</h2><p>Chia ảnh thành các nhóm trong project.</p></div>
      <div className="modal-body">
        <div className="input-group"><label>Tên album</label>
          <input value={name} onChange={(e) => setName(e.target.value)} placeholder="VD: Phóng sự, Concept biển…" autoFocus
            onKeyDown={(e) => { if (e.key === "Enter" && name.trim()) { store.addAlbum(projectId, name.trim()); onClose(); } }} /></div>
      </div>
      <div className="modal-foot">
        <button className="btn btn-ghost" onClick={onClose}>Huỷ</button>
        <button className="btn btn-primary" disabled={!name.trim()} onClick={() => { store.addAlbum(projectId, name.trim()); onClose(); }}>Tạo album</button>
      </div>
    </Modal>
  );
}

Object.assign(window, { StudioDashboard, StudioProjectView });
