// Candidates list (ranked) + Upload screen + shared CandidatesTable

const { StatusPill, RecPill, Avatar, ScoreRing, ScoreBar, FairnessBanner, scoreColor, REC_STYLES } = window.UI;

const CandidatesTable = ({ candidates, positions, onOpen, compact = false }) => {
  const [sort, setSort] = React.useState("score");
  const [filter, setFilter] = React.useState("all");

  const sorted = [...candidates]
    .filter(c => filter === "all" || c.recommendation === filter)
    .sort((a, b) => sort === "score" ? b.score - a.score : new Date(b.appliedDate) - new Date(a.appliedDate));

  return (
    <div className="card">
      {!compact && (
        <div className="card-head">
          <div className="row gap-8">
            {["all", "Strong fit", "Potential fit", "Weak fit", "Not recommended"].map(f => (
              <button key={f}
                className={"btn btn-sm " + (filter === f ? "btn-primary" : "btn-ghost")}
                onClick={() => setFilter(f)}>
                {f === "all" ? "All" : f}
                <span style={{ marginLeft: 4, opacity: 0.7, fontSize: 11 }}>
                  {f === "all" ? candidates.length : candidates.filter(c => c.recommendation === f).length}
                </span>
              </button>
            ))}
          </div>
          <div className="row gap-8">
            <button className="btn btn-ghost btn-sm" onClick={() => setSort(sort === "score" ? "date" : "score")}>
              Sort: {sort === "score" ? "Fit score" : "Date applied"}
              <Icon name="chevron-down" size={12}/>
            </button>
            <button className="btn btn-ghost btn-sm"><Icon name="filter" size={12}/>Filter</button>
          </div>
        </div>
      )}
      <table className="tbl">
        <thead>
          <tr>
            <th style={{ width: 36 }}></th>
            <th>Candidate</th>
            <th>Current role</th>
            <th>Experience</th>
            <th style={{ width: 160 }}>Fit score</th>
            <th>Recommendation</th>
            <th>Status</th>
            <th>Applied</th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          {sorted.length === 0 && (
            <tr><td colSpan="9" style={{ padding: "32px 16px", textAlign: "center", color: "var(--text-muted)" }}>
              <div style={{ fontSize: 14, marginBottom: 6 }}>
                {candidates.length === 0 ? "ยังไม่มีผู้สมัคร" : "ไม่มีผู้สมัครตามตัวกรอง"}
              </div>
              <div style={{ fontSize: 12.5 }}>
                {candidates.length === 0 ? "อัพโหลด resume เพื่อเริ่มต้น" : "ลองเปลี่ยน filter เพื่อดูผลลัพธ์อื่น"}
              </div>
            </td></tr>
          )}
          {sorted.map((c, i) => (
            <tr key={c.id} className="row-link" onClick={() => onOpen("candidate", c.id)}>
              <td>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, color: "var(--text-subtle)" }}>
                  {String(i + 1).padStart(2, "0")}
                </span>
              </td>
              <td>
                <div className="row gap-10">
                  <Avatar initials={c.initials} color={c.avatarColor} size="sm"/>
                  <div className="col">
                    <div style={{ fontWeight: 500 }}>{c.name}</div>
                    <div className="subtle" style={{ fontSize: 11.5 }}>{c.location}</div>
                  </div>
                </div>
              </td>
              <td>
                <div className="col">
                  <div style={{ fontSize: 13 }}>{c.currentTitle}</div>
                  <div className="subtle" style={{ fontSize: 11.5 }}>{c.currentCompany}</div>
                </div>
              </td>
              <td className="muted no-wrap">{c.yearsExperience} yrs</td>
              <td>
                <div className="row gap-10">
                  <div style={{
                    width: 60, height: 6, borderRadius: 999,
                    background: "var(--sand-200)", overflow: "hidden"
                  }}>
                    <div style={{ width: c.score + "%", height: "100%", background: scoreColor(c.score) }}/>
                  </div>
                  <span style={{ fontFamily: "var(--font-serif)", fontSize: 18, fontWeight: 500, color: "var(--green-900)", fontVariantNumeric: "tabular-nums" }}>{c.score}</span>
                </div>
              </td>
              <td><RecPill rec={c.recommendation}/></td>
              <td><StatusPill status={c.status}/></td>
              <td className="muted no-wrap" style={{ fontSize: 12.5 }}>{c.appliedDate}</td>
              <td><Icon name="chevron-right" size={14} style={{ color: "var(--text-subtle)" }}/></td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

const CandidatesList = ({ candidates, positions, onOpen }) => {
  const { t } = window.I18N.useI18n();
  const [posFilter, setPosFilter] = React.useState("pos_001");
  const filtered = candidates.filter(c => posFilter === "all" || c.positionId === posFilter);
  const pos = positions.find(p => p.id === posFilter);
  return (
    <div className="fade-in">
      <div className="page-head">
        <div>
          <div className="page-eyebrow">{t.cands.eyebrow}</div>
          <h1 className="page-title">{t.cands.title}</h1>
          <div className="page-sub">{pos ? t.cands.subWith(filtered.length, pos.title) : t.cands.subAll(filtered.length)}</div>
        </div>
        <div className="row gap-8">
          <select className="field-input" style={{ width: 280, height: 38 }} value={posFilter} onChange={e => setPosFilter(e.target.value)}>
            <option value="all">{t.cands.allPositions}</option>
            {positions.map(p => <option key={p.id} value={p.id}>{p.title}</option>)}
          </select>
        </div>
      </div>
      <FairnessBanner show={true}/>
      <CandidatesTable candidates={filtered} positions={positions} onOpen={onOpen}/>
    </div>
  );
};

const UploadScreen = ({ positions, onDone }) => {
  const [stage, setStage] = React.useState("idle"); // idle | uploading | thinking | done
  const [files, setFiles] = React.useState([]);
  const [position, setPosition] = React.useState("pos_001");
  const [thinkingStep, setThinkingStep] = React.useState(0);
  const [dragOver, setDragOver] = React.useState(false);
  const [uploadError, setUploadError] = React.useState("");
  const fileInputRef = React.useRef(null);

  const supabase = window.AUTH && window.AUTH.supabase;

  const formatSize = (bytes) => {
    if (bytes < 1024) return bytes + " B";
    if (bytes < 1024 * 1024) return Math.round(bytes / 1024) + " KB";
    return (bytes / 1024 / 1024).toFixed(1) + " MB";
  };

  const uploadFiles = async (fileList) => {
    const arr = Array.from(fileList);
    if (arr.length === 0) return;
    setUploadError("");

    if (!supabase) {
      // Offline mode — keep prototype behaviour
      setFiles(arr.map((f) => ({ name: f.name, size: formatSize(f.size), status: "done" })));
      setStage("thinking");
      setThinkingStep(0);
      return;
    }

    const initial = arr.map((f) => ({ name: f.name, size: formatSize(f.size), status: "uploading", path: null, error: null }));
    setFiles(initial);
    setStage("uploading");

    const datePrefix = new Date().toISOString().slice(0, 10);
    let allOk = true;

    for (let i = 0; i < arr.length; i++) {
      const f = arr[i];
      const safeName = f.name.replace(/[^a-zA-Z0-9._-]/g, "_");
      const path = `${position}/${datePrefix}/${Date.now()}_${i}_${safeName}`;
      const { error: upErr } = await supabase.storage
        .from("resumes")
        .upload(path, f, { cacheControl: "3600", upsert: false });

      // Create a candidate record so the resume shows up in the candidates list
      let candidateError = null;
      if (!upErr && window.DATA?.api?.createCandidateFromUpload) {
        const { error } = await window.DATA.api.createCandidateFromUpload({
          file: f, positionId: position, storagePath: path,
        });
        candidateError = error || null;
      }

      setFiles((curr) => {
        const next = curr.slice();
        const finalErr = upErr || candidateError;
        next[i] = finalErr
          ? { ...next[i], status: "error", error: (finalErr.message || String(finalErr)) }
          : { ...next[i], status: "uploaded", path };
        return next;
      });
      if (upErr || candidateError) allOk = false;
    }

    if (allOk) {
      // Smoothly move to the AI screening visual
      setStage("thinking");
      setThinkingStep(0);
    } else {
      setUploadError("Some files failed to upload — check items below.");
    }
  };

  const onPickFiles = (e) => uploadFiles(e.target.files);

  const triggerBrowse = () => fileInputRef.current && fileInputRef.current.click();

  React.useEffect(() => {
    if (stage !== "thinking") return;
    if (thinkingStep >= 4) {
      const t = setTimeout(() => setStage("done"), 600);
      return () => clearTimeout(t);
    }
    const t = setTimeout(() => setThinkingStep(s => s + 1), 1100);
    return () => clearTimeout(t);
  }, [stage, thinkingStep]);

  const pos = positions.find(p => p.id === position);

  const STEPS = [
    { label: "Parsing 6 resumes (PDF + DOCX)", detail: "Extracting structured fields: name, contact, work history, education, skills…" },
    { label: "Cross-referencing against the JD", detail: "Mapping each candidate's experience to must-haves and nice-to-haves." },
    { label: "Scoring across 6 dimensions", detail: "Experience · Skills · Industry · Leadership · KPI · Stability" },
    { label: "Generating explanations & call-prep notes", detail: "Per-score reasoning, suggested questions, salary & availability probes." },
  ];

  return (
    <div className="fade-in">
      <div className="page-head">
        <div>
          <div className="page-eyebrow">Resume ingestion</div>
          <h1 className="page-title">Upload &amp; AI screen</h1>
          <div className="page-sub">Drop a folder of resumes. The AI parses each one, scores it against the position you select, and surfaces a ranked list — usually in under 90 seconds for batches of 20.</div>
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1.5fr 1fr", gap: 18 }}>
        <div className="col gap-12">
          <div className="card card-pad">
            <div className="field-label mb-8">Screen against position</div>
            <select className="field-input" value={position} onChange={e => setPosition(e.target.value)} disabled={stage !== "idle"}>
              {positions.map(p => <option key={p.id} value={p.id}>{p.title} — {p.department}</option>)}
            </select>
            {pos && (
              <div className="row gap-8 mt-12" style={{ flexWrap: "wrap" }}>
                {pos.skills.slice(0, 4).map((s, i) => <span key={i} className="pill pill-sand">{s}</span>)}
                <span className="pill pill-outline">{pos.mustHave.length} must-haves</span>
                <span className="pill pill-outline">{pos.kpis.length} KPIs</span>
              </div>
            )}
          </div>

          {stage === "idle" && (
            <div
              className={"drop-zone" + (dragOver ? " drag-over" : "")}
              onDragOver={e => { e.preventDefault(); setDragOver(true); }}
              onDragLeave={() => setDragOver(false)}
              onDrop={e => { e.preventDefault(); setDragOver(false); uploadFiles(e.dataTransfer.files); }}
            >
              <input
                ref={fileInputRef}
                type="file"
                multiple
                accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,image/png,image/jpeg"
                style={{ display: "none" }}
                onChange={onPickFiles}
              />
              <div style={{
                width: 56, height: 56, borderRadius: "50%",
                background: "var(--green-100)", color: "var(--green-700)",
                display: "grid", placeItems: "center", margin: "0 auto 14px"
              }}>
                <Icon name="upload" size={24}/>
              </div>
              <div style={{ fontFamily: "var(--font-serif)", fontSize: 20, fontWeight: 500, color: "var(--green-900)", marginBottom: 6 }}>
                Drop resumes here
              </div>
              <div className="muted mb-16" style={{ fontSize: 13 }}>PDF, DOCX, PNG, JPG · up to 50 files · 10 MB each</div>
              <button className="btn btn-primary" onClick={triggerBrowse}>
                <Icon name="upload" size={14}/>Browse files
              </button>
              {uploadError && (
                <div className="muted mt-12" style={{ fontSize: 12, color: "var(--rose-500, #c93d3d)" }}>{uploadError}</div>
              )}
            </div>
          )}

          {(stage === "uploading" || stage === "thinking" || stage === "done") && (
            <div className="card card-pad">
              <div className="row gap-8 mb-16" style={{ justifyContent: "space-between" }}>
                <div className="row gap-8">
                  <Icon name="sparkles" size={16} style={{ color: "var(--green-600)" }}/>
                  <div className="card-title" style={{ margin: 0 }}>
                    {stage === "uploading" ? "Uploading to secure storage…"
                      : stage === "done" ? "Screening complete"
                      : "AI is screening…"}
                  </div>
                </div>
                {stage === "done" && <span className="pill pill-green"><Icon name="check" size={11}/>Done in 1m 12s</span>}
              </div>

              {uploadError && (
                <div className="banner banner-info" style={{ marginBottom: 12, background: "var(--rose-50, #fef2f2)", borderColor: "var(--rose-200, #fecaca)" }}>
                  <Icon name="alert" size={16} className="banner-icon" style={{ color: "var(--rose-500, #c93d3d)" }}/>
                  <div className="banner-body" style={{ fontSize: 12.5 }}>{uploadError}</div>
                </div>
              )}

              <div className="col gap-8 mb-16">
                {files.map((f, i) => (
                  <div key={i} className="row gap-10" style={{ padding: "8px 12px", background: "var(--sand-50)", borderRadius: 8 }}>
                    <Icon name="file-text" size={16} style={{ color: "var(--text-muted)" }}/>
                    <div className="flex-1 truncate">
                      <span style={{ fontSize: 13, fontWeight: 500 }}>{f.name}</span>
                      <span className="subtle" style={{ marginLeft: 8, fontSize: 11.5 }}>{f.size}</span>
                      {f.error && <span style={{ marginLeft: 8, fontSize: 11.5, color: "var(--rose-500, #c93d3d)" }}>· {f.error}</span>}
                    </div>
                    {f.status === "uploading" ? (
                      <span className="pill pill-blue"><span className="dot pulse-soft"/>Uploading</span>
                    ) : f.status === "error" ? (
                      <span className="pill pill-rose"><Icon name="alert" size={10}/>Failed</span>
                    ) : stage === "thinking" && i <= thinkingStep ? (
                      <span className="pill pill-blue"><span className="dot pulse-soft"/>Processing</span>
                    ) : stage === "done" ? (
                      <span className="pill pill-green"><Icon name="check" size={10}/>Scored</span>
                    ) : f.status === "uploaded" ? (
                      <span className="pill pill-green"><Icon name="check" size={10}/>Uploaded</span>
                    ) : (
                      <span className="pill pill-outline">Queued</span>
                    )}
                  </div>
                ))}
              </div>

              <div className="col gap-12" style={{ display: stage === "uploading" ? "none" : undefined }}>
                {STEPS.map((s, i) => {
                  const active = i === thinkingStep && stage === "thinking";
                  const done = stage === "done" || i < thinkingStep;
                  return (
                    <div key={i} className="row gap-12" style={{ alignItems: "flex-start" }}>
                      <div style={{
                        width: 22, height: 22, borderRadius: 999,
                        background: done ? "var(--green-500)" : active ? "var(--green-100)" : "var(--sand-200)",
                        color: done ? "#fff" : active ? "var(--green-700)" : "var(--text-subtle)",
                        display: "grid", placeItems: "center", flexShrink: 0, fontSize: 12, marginTop: 1
                      }} className={active ? "pulse-soft" : ""}>
                        {done ? <Icon name="check" size={12}/> : i + 1}
                      </div>
                      <div className="col gap-4 flex-1">
                        <div style={{ fontWeight: active ? 600 : 500, fontSize: 13.5, color: done || active ? "var(--text)" : "var(--text-subtle)" }}>{s.label}</div>
                        <div className="subtle" style={{ fontSize: 12 }}>{s.detail}</div>
                      </div>
                    </div>
                  );
                })}
              </div>

              {stage === "done" && (
                <div className="row gap-8 mt-24" style={{ justifyContent: "flex-end" }}>
                  <button className="btn btn-ghost" onClick={() => { setStage("idle"); setFiles([]); setThinkingStep(0); }}>Upload more</button>
                  <button className="btn btn-primary" onClick={() => onDone()}>Review {files.length} candidates<Icon name="arrow-right" size={12}/></button>
                </div>
              )}
            </div>
          )}
        </div>

        <div className="col gap-12">
          <div className="card card-pad">
            <div className="card-title mb-12">What the AI extracts</div>
            <div className="col gap-10">
              {[
                ["Identity", "Name, contact (redactable)"],
                ["Work history", "Companies, titles, dates, gaps"],
                ["Education & certs", "Degrees, schools, licenses"],
                ["Skills", "Technical & functional"],
                ["Career signal", "Tenure pattern, progression"],
              ].map(([k, v], i) => (
                <div key={i} className="row gap-12">
                  <Icon name="check" size={14} style={{ color: "var(--green-600)" }}/>
                  <div className="col">
                    <span style={{ fontSize: 13, fontWeight: 500 }}>{k}</span>
                    <span className="subtle" style={{ fontSize: 12 }}>{v}</span>
                  </div>
                </div>
              ))}
            </div>
          </div>
          <div className="banner banner-warn">
            <Icon name="shield" size={16} className="banner-icon"/>
            <div>
              <div className="banner-title">Never extracted or used in scoring</div>
              <div className="banner-body">Photo, age, gender, marital status, religion, race, nationality, health. PDPA-compliant: candidate can request deletion at any time.</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

window.SCREENS_B = { CandidatesTable, CandidatesList, UploadScreen };
