// Vanday DAM — Quick-upload flow
//   • UploadDestinationModal  — appears when user hits any Upload button.
//     Confirms the current folder (or asks them to pick one), and lets them
//     set batch metadata (tags, license, photographer) and AI processing
//     options before files are queued.
//   • UploadDock              — floating bottom-right progress panel.
//     Persists across page navigation because it lives in App.

// Format chip helper — pulls the right label/color from the filename.
function fmtBadge(name) {
  const ext = (name || "").split(".").pop().toLowerCase();
  const map = {
    nef:  { label: "RAW",  kind: "raw"   },
    cr2:  { label: "RAW",  kind: "raw"   },
    arw:  { label: "RAW",  kind: "raw"   },
    psd:  { label: "PSD",  kind: "psd"   },
    pdf:  { label: "PDF",  kind: "doc"   },
    doc:  { label: "DOC",  kind: "doc"   },
    docx: { label: "DOCX", kind: "doc"   },
    ppt:  { label: "PPT",  kind: "ppt"   },
    pptx: { label: "PPTX", kind: "ppt"   },
    heic: { label: "HEIC", kind: "img"   },
    mp4:  { label: "MP4",  kind: "video" },
    mov:  { label: "MOV",  kind: "video" },
    webm: { label: "WEBM", kind: "video" },
  };
  return map[ext] || null;
}
window.fmtBadge = fmtBadge;

const SAMPLE_UPLOADS = [
  { name: "spring-26-DSC_0411.NEF",   size: 38.2, thumb: "https://images.unsplash.com/photo-1500382017468-9049fed747ef?w=240&q=70&auto=format&fit=crop" },
  { name: "spring-26-lookbook.pdf",   size: 12.4, thumb: null },
  { name: "studio-hero-01.heic",       size: 5.1,  thumb: "https://images.unsplash.com/photo-1556228720-195a672e8a03?w=240&q=70&auto=format&fit=crop" },
  { name: "product-walkthrough.mp4",   size: 22.7, thumb: "https://images.unsplash.com/photo-1620916566398-39f1143ab7be?w=240&q=70&auto=format&fit=crop", duration: "1:24" },
  { name: "brand-guidelines-v3.docx",  size: 2.8,  thumb: null },
  { name: "investor-deck-q2.pptx",     size: 8.6,  thumb: null },
  { name: "behind-the-shoot.mov",      size: 48.1, thumb: "https://images.unsplash.com/photo-1529390079861-591de354faf5?w=240&q=70&auto=format&fit=crop", duration: "0:42" },
  { name: "ceramics-flatlay-08.jpg",   size: 3.9,  thumb: "https://images.unsplash.com/photo-1610701596007-11502861dcfa?w=240&q=70&auto=format&fit=crop" },
];

// ============================================================
// UploadDestinationModal
// ============================================================
function UploadDestinationModal({
  contextFolder,  // folder id the user is currently viewing (or "all")
  onCancel,
  onConfirm,      // ({ folderId, files }) => void
}) {
  // Pre-select the current folder if the user was viewing one. "All assets"
  // doesn't count — they should pick a real bucket then.
  const initialDest =
    contextFolder && contextFolder !== "all" && contextFolder.indexOf("__") !== 0
      ? contextFolder
      : "raw";
  const [destFolder, setDestFolder] = React.useState(initialDest);

  // Batch metadata that applies to every file in this upload.
  const [appliedTags, setAppliedTags] = React.useState([]);
  const [license, setLicense] = React.useState("internal");
  const [photographer, setPhotographer] = React.useState("");
  const [autoTag, setAutoTag] = React.useState(true);
  const [autoCrop, setAutoCrop] = React.useState(true);
  const [matchDup, setMatchDup] = React.useState(true);
  const [showAdvanced, setShowAdvanced] = React.useState(false);

  // Real file objects picked by the user. Each is a browser `File` plus a
  // synthesised preview (object URL) so the modal can show a thumbnail.
  const [files, setFiles] = React.useState([]);
  const fileInputRef = React.useRef(null);

  // "New folder" inline create flow.
  const [newFolderOpen, setNewFolderOpen] = React.useState(false);
  const [newFolderName, setNewFolderName] = React.useState("");
  const [creatingFolder, setCreatingFolder] = React.useState(false);
  const [folderError, setFolderError] = React.useState(null);

  const submitNewFolder = React.useCallback(async () => {
    const name = newFolderName.trim();
    if (!name) return;
    setCreatingFolder(true);
    setFolderError(null);
    try {
      const created = await window.VandayAPI.createFolder(name);
      // Append the new folder to the global FOLDERS list so the modal's
      // list re-renders with it included.
      if (Array.isArray(window.FOLDERS)) {
        window.FOLDERS.push({
          id: created.id, name: created.name, count: 0, icon: "folder",
          parent: null, isServer: true,
        });
      }
      setDestFolder(created.id);
      setNewFolderName("");
      setNewFolderOpen(false);
    } catch (err) {
      setFolderError(err?.message || "Couldn't create folder");
    } finally {
      setCreatingFolder(false);
    }
  }, [newFolderName]);

  // Open the OS file picker so the user can actually select images.
  const openPicker = React.useCallback(() => {
    if (fileInputRef.current) fileInputRef.current.click();
  }, []);

  // When the picker returns files, wrap them with display fields and merge
  // into the current list. We keep both the underlying File (for upload) and
  // a small thumb URL (for the modal preview).
  const onFilesPicked = React.useCallback((eventOrList) => {
    const fl = eventOrList?.target?.files || eventOrList;
    if (!fl || fl.length === 0) return;
    const incoming = Array.from(fl).map((f) => ({
      _file: f,
      name: f.name,
      size: f.size / (1024 * 1024),
      thumb: f.type.startsWith("image/") ? URL.createObjectURL(f) : null,
    }));
    setFiles((fs) => [...fs, ...incoming]);
    // Reset the input so picking the same file again still fires onChange.
    if (fileInputRef.current) fileInputRef.current.value = "";
  }, []);

  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onCancel(); };
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [onCancel]);

  const contextWasFolder =
    contextFolder && contextFolder !== "all" && contextFolder.indexOf("__") !== 0;
  const contextFolderObj = FOLDERS.find((f) => f.id === contextFolder);

  const totalSize = files.reduce((s, f) => s + f.size, 0);

  return (
    <div className="modal-backdrop" onClick={onCancel}>
      <div className="modal qu-modal" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <div style={{ display: "inline-flex", alignItems: "center", gap: 8, fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", color: "var(--text-faint)", fontWeight: 500, marginBottom: 4 }}>
              <IcUpload size={11} /> Upload
            </div>
            <h2 className="modal-title">
              {contextWasFolder
                ? `Upload to ${contextFolderObj?.name}?`
                : "Choose a destination"}
            </h2>
            <div style={{ fontSize: 12.5, color: "var(--text-muted)", marginTop: 4 }}>
              {contextWasFolder
                ? `${files.length} file${files.length === 1 ? "" : "s"} ready. Confirm or pick a different folder.`
                : `${files.length} file${files.length === 1 ? "" : "s"} ready. Pick where to put them.`}
            </div>
          </div>
          <button className="btn ghost sm" onClick={onCancel}><IcClose size={14} /></button>
        </div>

        <div className="qu-body">
          {/* Files about to upload */}
          <div className="qu-section">
            <div className="qu-section-h">
              <span>Files</span>
              <span className="qu-section-meta">
                {files.length} · {totalSize.toFixed(1)} MB
              </span>
            </div>
            <div className="qu-files">
              {files.map((f, i) => {
                const badge = fmtBadge(f.name);
                return (
                  <div className="qu-file" key={i}>
                    {f.thumb ? (
                      <div className="qu-file-thumb" style={{ backgroundImage: `url(${f.thumb})` }}>
                        {badge && <span className={`qu-file-badge is-${badge.kind}`}>{badge.label}</span>}
                      </div>
                    ) : (
                      <div className={`qu-file-doc is-${(badge?.kind || "doc")}`}>
                        {badge?.label || "FILE"}
                      </div>
                    )}
                    <div style={{ minWidth: 0, flex: 1 }}>
                      <div className="qu-file-name">{f.name}</div>
                      <div className="qu-file-meta">
                        {f.size.toFixed(1)} MB{f.duration ? ` · ${f.duration}` : ""}
                      </div>
                    </div>
                    <button
                      className="qu-file-remove"
                      onClick={() => setFiles((fs) => fs.filter((_, j) => j !== i))}
                      title="Remove"
                    >
                      <IcClose size={12} />
                    </button>
                  </div>
                );
              })}
              <input
                ref={fileInputRef}
                type="file"
                multiple
                accept="image/*,image/heic,image/heif,.heic,.heif,video/mp4,video/quicktime,video/webm,.mp4,.mov,.webm,.zip,application/zip"
                style={{ display: "none" }}
                onChange={onFilesPicked}
              />
              <button className="qu-add-more" onClick={openPicker}>
                <IcPlus size={12} /> {files.length === 0 ? "Choose files" : "Add more files"}
              </button>
            </div>
          </div>

          {/* Destination */}
          <div className="qu-section">
            <div className="qu-section-h">
              <span>Destination folder</span>
            </div>
            <div className="qu-folders">
              {(() => {
                // Flatten into a depth-aware list so we can render in tree order.
                const rows = [];
                const walk = (parent, depth) => {
                  (parent === null ? topLevelFolders() : childFolders(parent)).forEach((f) => {
                    rows.push({ f, depth });
                    walk(f.id, depth + 1);
                  });
                };
                walk(null, 0);
                return rows.map(({ f, depth }) => (
                  <button
                    key={f.id}
                    className={`qu-folder ${destFolder === f.id ? "is-on" : ""}`}
                    onClick={() => setDestFolder(f.id)}
                    style={{ paddingLeft: 10 + depth * 16 }}
                  >
                    <span className="qu-folder-ic">
                      <IcFolder size={depth === 0 ? 14 : 12} />
                    </span>
                    <span className="qu-folder-name">{f.name}</span>
                    {f.id === contextFolder && (
                      <span className="qu-folder-here">Current</span>
                    )}
                    <span className="qu-folder-count">{f.count}</span>
                  </button>
                ));
              })()}
            </div>
            {!newFolderOpen ? (
              <button className="qu-link" onClick={() => setNewFolderOpen(true)}>
                <IcPlus size={11} /> New folder
              </button>
            ) : (
              <div style={{ display: "flex", gap: 6, marginTop: 8, alignItems: "center" }}>
                <input
                  type="text"
                  autoFocus
                  placeholder="Folder name"
                  value={newFolderName}
                  onChange={(e) => setNewFolderName(e.target.value)}
                  onKeyDown={(e) => {
                    if (e.key === "Enter") submitNewFolder();
                    if (e.key === "Escape") { setNewFolderOpen(false); setNewFolderName(""); setFolderError(null); }
                  }}
                  maxLength={60}
                  disabled={creatingFolder}
                  style={{
                    flex: 1, padding: "6px 10px", fontSize: 13,
                    background: "var(--surface)", color: "var(--text)",
                    border: "1px solid var(--border)", borderRadius: 6, outline: "none",
                  }}
                />
                <button
                  className="btn primary sm"
                  onClick={submitNewFolder}
                  disabled={!newFolderName.trim() || creatingFolder}
                  style={{ padding: "6px 12px", fontSize: 12 }}
                >
                  {creatingFolder ? "Creating…" : "Create"}
                </button>
                <button
                  className="btn ghost sm"
                  onClick={() => { setNewFolderOpen(false); setNewFolderName(""); setFolderError(null); }}
                  disabled={creatingFolder}
                  style={{ padding: "6px 10px", fontSize: 12 }}
                >
                  Cancel
                </button>
              </div>
            )}
            {folderError && (
              <div style={{ color: "oklch(0.55 0.18 24)", fontSize: 12, marginTop: 6 }}>
                {folderError}
              </div>
            )}
          </div>
        </div>

        <div className="modal-foot" style={{ background: "var(--surface)" }}>
          <div style={{ fontSize: 12, color: "var(--text-muted)" }}>
            <IcSparkles size={11} style={{ verticalAlign: "middle", marginRight: 4, color: "var(--accent)" }} />
            Images & video are auto-tagged and cropped. Docs are indexed for search.
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            <button className="btn" onClick={onCancel}>Cancel</button>
            <button
              className="btn accent"
              disabled={files.length === 0}
              style={files.length === 0 ? { opacity: 0.5, cursor: "not-allowed" } : undefined}
              onClick={() => onConfirm({ folderId: destFolder, files })}
            >
              <IcUpload size={13} />
              Upload {files.length} to {FOLDERS.find((f) => f.id === destFolder)?.name}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// UploadDock — bottom-right progress panel
// ============================================================
function UploadDock({ queue, onDismiss, onRetry, onOpenAsset }) {
  const [collapsed, setCollapsed] = React.useState(false);

  // Auto-dismiss once everything has finished uploading successfully. We
  // leave it on screen for a few seconds so the "all uploaded" state is
  // visible, then clear it. If anything failed we keep the dock so the
  // user can retry or read the error. (Effect must run before the early
  // return below to keep hook order stable.)
  const allUploaded = queue.length > 0 && queue.every((q) => q.status === "ready");
  React.useEffect(() => {
    if (!allUploaded) return;
    const t = setTimeout(() => { onDismiss && onDismiss(); }, 4000);
    return () => clearTimeout(t);
  }, [allUploaded, onDismiss]);

  if (queue.length === 0) return null;

  const inFlight = queue.filter((q) => q.status === "uploading" || q.status === "analyzing");
  const done     = queue.filter((q) => q.status === "ready");
  const failed   = queue.filter((q) => q.status === "failed");
  const total    = queue.length;
  const summary =
    inFlight.length > 0 ? `Uploading ${inFlight.length} of ${total}` :
    failed.length > 0   ? `${done.length} of ${total} uploaded · ${failed.length} failed` :
    `${done.length} of ${total} uploaded`;

  // Average progress for the headline bar.
  const avgProgress = total === 0
    ? 0
    : queue.reduce((s, q) => s + (q.status === "ready" ? 100 : q.progress || 0), 0) / total;

  return (
    <div className={`upload-dock ${collapsed ? "is-collapsed" : ""}`}>
      <button
        className="dock-head"
        onClick={() => setCollapsed((c) => !c)}
      >
        <div className="dock-head-info">
          <div className="dock-summary">{summary}</div>
          <div className="dock-progress-bar">
            <div className="dock-progress-fill" style={{ width: `${avgProgress}%` }} />
          </div>
        </div>
        <div className="dock-head-actions">
          {failed.length > 0 && (
            <span className="dock-fail-badge">{failed.length}</span>
          )}
          <span className="dock-chev">
            <IcChevD size={14} style={{ transform: collapsed ? "rotate(180deg)" : "rotate(0)" }} />
          </span>
        </div>
      </button>

      {!collapsed && (
        <>
          <div className="dock-list">
            {queue.map((q) => {
              const folder = FOLDERS.find((f) => f.id === q.folder);
              const inFlight = q.status === "uploading" || q.status === "analyzing";
              return (
                <div key={q.id} className={`dock-row is-${q.status}`}>
                  <div className="dock-row-thumb" style={{ backgroundImage: `url(${q.thumb})` }} />
                  <div className="dock-row-main">
                    <div className="dock-row-name" title={q.name}>{q.name}</div>
                    <div className="dock-row-meta">
                      {q.status === "ready" && (
                        <>
                          <IcCheck size={10} />
                          <span>Uploaded to {folder?.name}</span>
                        </>
                      )}
                      {q.status === "uploading" && (
                        <>
                          <span>Uploading…</span>
                          <span className="dock-row-pct">{Math.round(q.progress)}%</span>
                        </>
                      )}
                      {q.status === "analyzing" && (
                        <>
                          <IcSparkles size={10} />
                          <span>Auto-tagging…</span>
                        </>
                      )}
                      {q.status === "failed" && (
                        <>
                          <IcInfo size={10} />
                          <span>{q.error || "Upload failed"}</span>
                        </>
                      )}
                    </div>
                    {inFlight && (
                      <div className="dock-row-bar">
                        <div
                          className={`dock-row-fill ${q.status === "analyzing" ? "is-analyzing" : ""}`}
                          style={{ width: `${q.progress}%` }}
                        />
                      </div>
                    )}
                  </div>
                  <div className="dock-row-actions">
                    {q.status === "failed" && (
                      <button
                        className="dock-row-btn"
                        onClick={() => onRetry(q.id)}
                        title="Retry"
                      >
                        Retry
                      </button>
                    )}
                    {q.status === "ready" && q.asset && (
                      <button
                        className="dock-row-btn"
                        onClick={() => onOpenAsset(q.asset)}
                        title="Open in library"
                      >
                        View
                      </button>
                    )}
                  </div>
                </div>
              );
            })}
          </div>

          <div className="dock-foot">
            <span style={{ fontSize: 11.5, color: "var(--text-faint)" }}>
              {done.length} uploaded · {failed.length} failed
            </span>
            <button
              className="dock-link"
              onClick={onDismiss}
              disabled={inFlight.length > 0}
              style={inFlight.length > 0 ? { opacity: 0.4, cursor: "not-allowed" } : undefined}
            >
              {inFlight.length > 0 ? "Uploading…" : "Clear"}
            </button>
          </div>
        </>
      )}
    </div>
  );
}

Object.assign(window, {
  UploadDestinationModal,
  UploadDock,
  SAMPLE_UPLOADS,
});
