// Vanday DAM — upload page
// A hi-fi snapshot of an active upload session:
//   • hero drop zone (top)
//   • queue with progress / AI-tag / status per row (middle)
//   • apply-to-all settings panel (right rail)
//   • sticky footer with totals + primary action

// Pre-staged queue. Each row carries enough state to look "live":
//   status: queued | uploading | analyzing | ready | failed | duplicate
//   progress: 0..100
//   aiTags / aiState: pending | done
const QUEUE_SEED = [
  { id: "u01", name: "DSC_04812.NEF",                size: 38.2, w: 6240, h: 4160, ratio: "raw",
    status: "uploading", progress: 64, aiState: "pending", aiTags: [],
    thumb: "https://images.unsplash.com/photo-1500382017468-9049fed747ef?w=240&q=70&auto=format&fit=crop" },
  { id: "u02", name: "DSC_04813.NEF",                size: 41.8, w: 6240, h: 4160, ratio: "raw",
    status: "uploading", progress: 28, aiState: "pending", aiTags: [],
    thumb: "https://images.unsplash.com/photo-1502082553048-f009c37129b9?w=240&q=70&auto=format&fit=crop" },
  { id: "u03", name: "studio-still-hero-01.jpg",     size: 4.6,  w: 5184, h: 3456, ratio: "4:3",
    status: "analyzing", progress: 100, aiState: "pending", aiTags: [],
    thumb: "https://images.unsplash.com/photo-1556228720-195a672e8a03?w=240&q=70&auto=format&fit=crop" },
  { id: "u04", name: "studio-still-hero-02.jpg",     size: 4.4,  w: 5184, h: 3456, ratio: "4:3",
    status: "ready",     progress: 100, aiState: "done",
    aiTags: ["product", "skincare", "minimal", "studio"],
    thumb: "https://images.unsplash.com/photo-1571781926291-c477ebfd024b?w=240&q=70&auto=format&fit=crop" },
  { id: "u05", name: "studio-still-hero-03.jpg",     size: 5.1,  w: 5184, h: 3456, ratio: "4:3",
    status: "ready",     progress: 100, aiState: "done",
    aiTags: ["product", "bottle", "clean", "white background"],
    thumb: "https://images.unsplash.com/photo-1620916566398-39f1143ab7be?w=240&q=70&auto=format&fit=crop" },
  { id: "u06", name: "team-offsite-DSC_1142.jpg",    size: 6.7,  w: 6000, h: 4000, ratio: "3:2",
    status: "duplicate", progress: 100, aiState: "done",
    aiTags: ["team", "outdoor", "group", "candid"],
    thumb: "https://images.unsplash.com/photo-1522071820081-009f0129c71c?w=240&q=70&auto=format&fit=crop" },
  { id: "u07", name: "team-offsite-DSC_1143.jpg",    size: 6.4,  w: 6000, h: 4000, ratio: "3:2",
    status: "ready",     progress: 100, aiState: "done",
    aiTags: ["team", "outdoor", "candid", "smile"],
    thumb: "https://images.unsplash.com/photo-1529390079861-591de354faf5?w=240&q=70&auto=format&fit=crop" },
  { id: "u08", name: "campaign-still-board.psd",     size: 84.3, w: 7000, h: 4500, ratio: "psd",
    status: "failed",    progress: 12,  aiState: "pending", aiTags: [],
    error: "File exceeds 75 MB plan limit",
    thumb: "https://images.unsplash.com/photo-1561070791-2526d30994b8?w=240&q=70&auto=format&fit=crop" },
  { id: "u09", name: "ceramics-flatlay-08.jpg",      size: 3.9,  w: 4500, h: 3000, ratio: "3:2",
    status: "queued",    progress: 0,   aiState: "pending", aiTags: [],
    thumb: "https://images.unsplash.com/photo-1610701596007-11502861dcfa?w=240&q=70&auto=format&fit=crop" },
  { id: "u10", name: "ceramics-flatlay-09.jpg",      size: 4.0,  w: 4500, h: 3000, ratio: "3:2",
    status: "queued",    progress: 0,   aiState: "pending", aiTags: [],
    thumb: "https://images.unsplash.com/photo-1578749556591-ab63c6f7df40?w=240&q=70&auto=format&fit=crop" },
  { id: "u11", name: "ceramics-flatlay-10.jpg",      size: 3.7,  w: 4500, h: 3000, ratio: "3:2",
    status: "queued",    progress: 0,   aiState: "pending", aiTags: [],
    thumb: "https://images.unsplash.com/photo-1493106641515-6b5631de4bb9?w=240&q=70&auto=format&fit=crop" },
];

const STATUS_META = {
  queued:    { label: "Queued",     dot: "var(--text-faint)" },
  uploading: { label: "Uploading",  dot: "oklch(0.62 0.16 235)" },
  analyzing: { label: "Auto-tagging", dot: "oklch(0.66 0.16 32)" },
  ready:     { label: "Ready",      dot: "oklch(0.62 0.15 145)" },
  duplicate: { label: "Duplicate",  dot: "oklch(0.62 0.14 80)" },
  failed:    { label: "Failed",     dot: "oklch(0.58 0.2 24)"  },
};

function StatusDot({ status }) {
  const m = STATUS_META[status];
  return (
    <span className="up-status">
      <span className="up-status-dot" style={{ background: m.dot }} />
      {m.label}
    </span>
  );
}

function UploadRow({ row, onRemove, onOpen }) {
  const isFailed = row.status === "failed";
  const isReady = row.status === "ready";
  const isDup = row.status === "duplicate";
  const inFlight = row.status === "uploading" || row.status === "analyzing";
  // Once an upload is ready, double-click opens the full library preview.
  const canOpen = isReady && !!onOpen;

  return (
    <div
      className={`up-row ${isFailed ? "is-failed" : ""}`}
      onDoubleClick={canOpen ? () => onOpen(row) : undefined}
      style={canOpen ? { cursor: "zoom-in" } : undefined}
      title={canOpen ? "Double-click to preview" : undefined}
    >
      <div className="up-thumb">
        <img src={row.thumb} alt="" />
        {row.ratio === "raw" && <span className="up-fmt">RAW</span>}
        {row.ratio === "psd" && <span className="up-fmt">PSD</span>}
      </div>

      <div className="up-row-main">
        <div className="up-row-head">
          <div className="up-name" title={row.name}>{row.name}</div>
          <div className="up-row-meta">
            <span>{row.w.toLocaleString()} × {row.h.toLocaleString()}</span>
            <span className="dot" />
            <span>{row.size.toFixed(1)} MB</span>
          </div>
        </div>

        {inFlight && (
          <div className="up-progress">
            <div className="up-progress-bar">
              <div
                className={`up-progress-fill ${row.status === "analyzing" ? "is-analyzing" : ""}`}
                style={{ width: `${row.progress}%` }}
              />
            </div>
            <span className="up-progress-val">
              {row.status === "analyzing" ? "Analyzing…" : `${row.progress}%`}
            </span>
          </div>
        )}

        {isReady && (
          <div className="up-tags-row">
            <span className="up-tags-label">
              <IcSparkles size={11} /> Suggested
            </span>
            {row.aiTags.map((t) => (
              <span key={t} className="tag ai">{t}</span>
            ))}
            <button className="up-add-tag" title="Add tag">
              <IcPlus size={10} /> tag
            </button>
          </div>
        )}

        {isDup && (
          <div className="up-warn">
            <IcInfo size={12} />
            Matches <span className="mono">team-offsite-DSC_1142.jpg</span> already in library.
            <a href="#" className="up-warn-link">Replace</a>
            <a href="#" className="up-warn-link">Keep both</a>
          </div>
        )}

        {isFailed && (
          <div className="up-warn is-err">
            <IcInfo size={12} />
            {row.error}
          </div>
        )}
      </div>

      <div className="up-row-right">
        <StatusDot status={row.status} />
        <button className="up-row-x" onClick={() => onRemove(row.id)} title="Remove">
          <IcClose size={14} />
        </button>
      </div>
    </div>
  );
}

function UploadPage({ onNav, onOpenAsset, onQuickUpload }) {
  const [rows, setRows] = React.useState(QUEUE_SEED);
  const [dragOver, setDragOver] = React.useState(false);
  const fileInputRef = React.useRef(null);

  // Apply-to-all panel state
  const [destFolder, setDestFolder] = React.useState("raw");
  const [autoTag, setAutoTag] = React.useState(true);
  const [autoCrop, setAutoCrop] = React.useState(true);
  const [matchDup, setMatchDup] = React.useState(true);
  const [appliedTags, setAppliedTags] = React.useState(["spring-26", "campaign"]);

  // ---- Real upload pipeline ----------------------------------------------
  // Drop / browse handlers post files to /api/upload, then poll until the
  // server marks aiState='done' (vision tagging + embedding finished).

  const handleFiles = React.useCallback(async (fileList) => {
    const files = Array.from(fileList || []).filter((f) => f && f.size > 0);
    if (files.length === 0) return;

    // Optimistic queue rows so the UI reacts immediately.
    const placeholders = files.map((f, i) => ({
      id: `live-${Date.now()}-${i}`,
      name: f.name,
      size: f.size / (1024 * 1024),
      w: 0, h: 0,
      ratio: f.type.includes("raw") ? "raw" : "—",
      status: "uploading",
      progress: 8,
      aiState: "pending",
      aiTags: [],
      thumb: URL.createObjectURL(f),
      _live: true,
    }));
    setRows((rs) => [...placeholders, ...rs]);

    try {
      const { assets } = await VandayAPI.uploadFiles(files, {
        folder: destFolder,
        uploader: "You",
      });
      // Swap placeholders → real server rows.
      setRows((rs) => {
        const out = [...rs];
        assets.forEach((a, i) => {
          const ph = placeholders[i];
          const idx = out.findIndex((r) => r.id === ph.id);
          if (idx >= 0) {
            out[idx] = {
              ...ph,
              id: a.id,
              status: "analyzing",
              progress: 100,
              aiState: "pending",
              w: a.w || ph.w,
              h: a.h || ph.h,
              thumb: a.url,
              _serverId: a.id,
            };
          }
        });
        return out;
      });

      // Poll each new asset until aiState transitions out of 'pending'.
      assets.forEach((a) => {
        const start = Date.now();
        const tick = async () => {
          if (Date.now() - start > 60_000) return; // give up after 60s
          try {
            const r = await VandayAPI.getAsset(a.id);
            if (r.aiState === "done") {
              setRows((rs) =>
                rs.map((row) =>
                  row.id === a.id
                    ? { ...row, status: "ready", aiState: "done", aiTags: r.tags || [], caption: r.caption }
                    : row,
                ),
              );
              return;
            }
            if (r.aiState === "failed") {
              setRows((rs) =>
                rs.map((row) =>
                  row.id === a.id
                    ? { ...row, status: "failed", error: "Auto-tagging failed" }
                    : row,
                ),
              );
              return;
            }
          } catch {/* keep polling */}
          setTimeout(tick, 800);
        };
        setTimeout(tick, 600);
      });
    } catch (err) {
      setRows((rs) =>
        rs.map((row) =>
          placeholders.find((p) => p.id === row.id)
            ? { ...row, status: "failed", error: err.message || "Upload failed" }
            : row,
        ),
      );
    }
  }, [destFolder]);

  const onDrop = (e) => {
    e.preventDefault();
    setDragOver(false);
    if (e.dataTransfer?.files) handleFiles(e.dataTransfer.files);
  };
  const onBrowse = () => fileInputRef.current?.click();
  const onFileInput = (e) => { handleFiles(e.target.files); e.target.value = ""; };

  // Simulated live progress for the seeded demo rows only — real uploads
  // jump straight to "analyzing" once the server returns.
  React.useEffect(() => {
    const t = setInterval(() => {
      setRows((rs) =>
        rs.map((r) => {
          if (r._live) return r;
          if (r.status === "uploading") {
            const next = Math.min(100, r.progress + (3 + Math.random() * 4));
            return next >= 100
              ? { ...r, progress: 100, status: "analyzing" }
              : { ...r, progress: next };
          }
          return r;
        })
      );
    }, 700);
    return () => clearInterval(t);
  }, []);

  const counts = rows.reduce((acc, r) => {
    acc.total += 1;
    acc.size += r.size;
    if (r.status === "ready" || r.status === "duplicate") acc.done += 1;
    if (r.status === "failed") acc.failed += 1;
    if (r.status === "uploading" || r.status === "analyzing" || r.status === "queued") acc.active += 1;
    return acc;
  }, { total: 0, size: 0, done: 0, failed: 0, active: 0 });

  // Real storage usage + beta cap (counts.size is in MB).
  const limits = (typeof window.useVandayLimits === "function") ? window.useVandayLimits() : null;
  const storageCapGB = (limits?.maxStorageBytes ?? (50 * 1024 * 1024 * 1024)) / (1024 * 1024 * 1024);
  const storageUsedGB = (limits?.storageBytesUsed ?? 0) / (1024 * 1024 * 1024);
  const storageAfterGB = storageUsedGB + counts.size / 1024;

  const removeRow = (id) => setRows((rs) => rs.filter((r) => r.id !== id));
  const clearDone = () =>
    setRows((rs) => rs.filter((r) => r.status !== "ready" && r.status !== "duplicate"));

  return (
    <div className="app">
      <Rail active="upload" onNav={onNav} onLogout={() => (window.__vandayLogout ? window.__vandayLogout() : onNav("login"))} onSearch={() => onNav("library")} onNotifs={() => onNav("library")} onHelp={() => onNav("library")} onQuickUpload={onQuickUpload} />
      <Sidebar
        activeFolder="all"
        setActiveFolder={() => {}}
        onNav={onNav}
      />

      <main className="main upload-main">
        <header className="topbar">
          <div className="crumbs">
            <span>Vanday studio</span>
            <span className="sep">/</span>
            <span>Library</span>
            <span className="sep">/</span>
            <span className="here">Upload</span>
          </div>
          <div className="topbar-right">
            <span className="trial-pill" title="Free beta plan">
              <span className="dot" /> Free Beta
            </span>
            <button className="btn" onClick={() => onNav("library")}>
              Cancel
            </button>
            <button className="btn accent">
              <IcUpload size={14} />
              Add {counts.done} {counts.done === 1 ? "asset" : "assets"} to library
            </button>
          </div>
        </header>

        <div className="upload-layout">
          <section className="upload-stage">
            <div
              className={`up-drop ${dragOver ? "is-over" : ""}`}
              onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
              onDragLeave={() => setDragOver(false)}
              onDrop={onDrop}
            >
              <div className="up-drop-stripes" aria-hidden="true" />
              <div className="up-drop-inner">
                <div className="up-drop-icon">
                  <IcUpload size={22} />
                </div>
                <div className="up-drop-h">Drop files to add to Vanday</div>
                <div className="up-drop-sub">
                  Images, videos, RAW, PSD · up to 75 MB · paste with{" "}
                  <kbd>⌘</kbd> <kbd>V</kbd>
                </div>
                <div className="up-drop-actions">
                  <button className="btn" onClick={onBrowse}>Browse files</button>
                  <button className="btn">Import from Drive</button>
                  <button className="btn">Import from URL</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={onFileInput}
                />
              </div>
            </div>

            <div className="up-queue-head">
              <div>
                <h2 className="up-queue-h">Upload queue</h2>
                <div className="up-queue-sub">
                  <span>
                    <strong>{counts.active}</strong> in progress
                  </span>
                  <span className="dot" />
                  <span>
                    <strong>{counts.done}</strong> ready
                  </span>
                  {counts.failed > 0 && (
                    <>
                      <span className="dot" />
                      <span style={{ color: "oklch(0.55 0.2 24)" }}>
                        <strong>{counts.failed}</strong> failed
                      </span>
                    </>
                  )}
                </div>
              </div>
              <div style={{ display: "flex", gap: 8 }}>
                <button className="btn sm" onClick={clearDone}>Clear completed</button>
                <button className="btn sm"><IcSort size={13} /> Newest first</button>
              </div>
            </div>

            <div className="up-queue">
              {rows.map((r) => (
                <UploadRow
                  key={r.id}
                  row={r}
                  onRemove={removeRow}
                  onOpen={(row) => {
                    if (!onOpenAsset) return;
                    // For real uploads, find the live asset in ALL_ASSETS so
                    // the preview gets full server metadata (tags, caption,
                    // variants). For the seeded demo rows, fall back to a
                    // synthetic asset built from the row itself.
                    const live = (window.ALL_ASSETS || []).find((a) => a.id === row.id);
                    if (live) { onOpenAsset(live); return; }
                    onOpenAsset({
                      id: row.id,
                      name: row.name,
                      url: row.thumb,
                      thumb: row.thumb,
                      w: row.w || 0,
                      h: row.h || 0,
                      tags: row.aiTags || [],
                      caption: row.caption || "",
                      folder: "raw",
                      uploader: "You",
                      date: new Date().toLocaleDateString(),
                      size: `${(row.size || 0).toFixed(1)} MB`,
                      kind: "original",
                    });
                  }}
                />
              ))}
            </div>
          </section>

          <aside className="upload-panel">
            <div className="up-panel-h">Apply to all</div>
            <div className="up-panel-sub">
              These settings apply to every file in this batch. You can override
              per asset after upload.
            </div>

            <div className="up-panel-section">
              <div className="up-panel-label">Destination folder</div>
              <div className="up-folder-list">
                {FOLDERS.slice(1).map((f) => (
                  <button
                    key={f.id}
                    className={`up-folder ${destFolder === f.id ? "is-on" : ""}`}
                    onClick={() => setDestFolder(f.id)}
                  >
                    <span className="up-folder-ic"><IcFolder size={13} /></span>
                    <span className="up-folder-name">{f.name}</span>
                    <span className="up-folder-count">{f.count}</span>
                  </button>
                ))}
              </div>
              <button className="up-link"><IcPlus size={11} /> New folder</button>
            </div>

            <div className="up-panel-section">
              <div className="up-panel-label">Tags to add</div>
              <div className="up-applied-tags">
                {appliedTags.map((t) => (
                  <span key={t} className="up-applied-tag">
                    {t}
                    <button
                      onClick={() =>
                        setAppliedTags((ts) => ts.filter((x) => x !== t))
                      }
                      title="Remove"
                    >
                      <IcClose size={9} />
                    </button>
                  </span>
                ))}
                <input
                  className="up-tag-input"
                  placeholder="Add tag…"
                  onKeyDown={(e) => {
                    if (e.key === "Enter" && e.currentTarget.value.trim()) {
                      setAppliedTags((ts) => [...ts, e.currentTarget.value.trim()]);
                      e.currentTarget.value = "";
                    }
                  }}
                />
              </div>
            </div>

            <div className="up-panel-section">
              <div className="up-panel-label">Processing</div>
              <button
                className="up-toggle-row"
                onClick={() => setAutoTag((v) => !v)}
              >
                <div>
                  <div className="up-toggle-h">
                    <IcSparkles size={12} /> AI auto-tag
                  </div>
                  <div className="up-toggle-sub">Suggest tags from image content</div>
                </div>
                <span className={`toggle ${autoTag ? "on" : ""}`} />
              </button>
              <button
                className="up-toggle-row"
                onClick={() => setAutoCrop((v) => !v)}
              >
                <div>
                  <div className="up-toggle-h">
                    <IcCrop size={12} /> Generate social crops
                  </div>
                  <div className="up-toggle-sub">1:1, 4:5, 16:9, 9:16</div>
                </div>
                <span className={`toggle ${autoCrop ? "on" : ""}`} />
              </button>
              <button
                className="up-toggle-row"
                onClick={() => setMatchDup((v) => !v)}
              >
                <div>
                  <div className="up-toggle-h">
                    <IcShield size={12} /> Detect duplicates
                  </div>
                  <div className="up-toggle-sub">Perceptual hash match</div>
                </div>
                <span className={`toggle ${matchDup ? "on" : ""}`} />
              </button>
            </div>

            <div className="up-panel-section">
              <div className="up-panel-label">Rights & credit</div>
              <div className="up-kv">
                <label>License</label>
                <select className="up-select" defaultValue="internal">
                  <option value="internal">Internal use only</option>
                  <option value="commercial">Commercial — paid</option>
                  <option value="cc-by">CC BY 4.0</option>
                  <option value="rm">Rights-managed</option>
                </select>
              </div>
              <div className="up-kv">
                <label>Photographer</label>
                <input
                  className="up-text"
                  defaultValue="Maya Ross"
                  placeholder="Credit line…"
                />
              </div>
            </div>

            <div className="up-panel-foot">
              <div className="up-foot-row">
                <span>Files</span>
                <span className="mono">{counts.total}</span>
              </div>
              <div className="up-foot-row">
                <span>Total size</span>
                <span className="mono">{counts.size.toFixed(1)} MB</span>
              </div>
              <div className="up-foot-row">
                <span>Storage after</span>
                <span className="mono">
                  {storageAfterGB.toFixed(2)} GB / {storageCapGB} GB
                </span>
              </div>
              <div className="up-foot-bar">
                <div
                  className="up-foot-bar-fill"
                  style={{ width: `${Math.min(100, (storageAfterGB / storageCapGB) * 100 + 2)}%` }}
                />
              </div>
            </div>
          </aside>
        </div>
      </main>
    </div>
  );
}

window.UploadPage = UploadPage;
