// ============== candidate dashboard ==============

const SENIORITY = ["Mid", "Senior", "Lead", "Staff", "Director"];
const OPEN_TO = [
  { v: "actively_looking", l: "Actively looking" },
  { v: "open", l: "Open to offers" },
  { v: "passive", l: "Passive" },
  { v: "closed", l: "Not looking" },
];
const STATUS_LABEL = {
  submitted: "Submitted",
  reviewed: "Under review",
  shortlisted: "Shortlisted",
  interviewing: "Interviewing",
  offered: "Offer extended",
  placed: "Placed",
  rejected: "Closed",
  withdrawn: "Withdrawn",
};

function Tabs({ tabs, value, onChange }) {
  return (
    <div className="tabs">
      {tabs.map((t) => (
        <button key={t.id} className={`tab ${value === t.id ? "is-on" : ""}`} onClick={() => onChange(t.id)}>
          {t.label}{t.count != null && <span className="tab-count">{t.count}</span>}
        </button>
      ))}
    </div>
  );
}

function CandidateDashboard({ go }) {
  const { user, logout } = useAuth();
  const [tab, setTab] = React.useState("profile");
  const [profile, setProfile] = React.useState(null);
  const [apps, setApps] = React.useState([]);
  const [roles, setRoles] = React.useState({});
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    if (!user) return;
    (async () => {
      try {
        const [p, a] = await Promise.all([
          window.W3J_API.apiFetch("/candidates/me"),
          window.W3J_API.apiFetch("/applications/me"),
        ]);
        setProfile(p);
        setApps(a);
        const roleIds = [...new Set(a.map((x) => x.role_id))];
        const fetched = await Promise.all(roleIds.map((id) => window.W3J_API.apiFetch(`/roles/${id}`).catch(() => null)));
        const map = {};
        fetched.forEach((r) => { if (r) map[r.id] = r; });
        setRoles(map);
      } finally {
        setLoading(false);
      }
    })();
  }, [user]);

  if (loading) return <main><section className="section"><div className="shell"><p className="lede">Loading…</p></div></section></main>;
  if (!profile) return null;

  return (
    <main>
      <section className="page-hero">
        <div className="shell">
          <div className="dash-head">
            <div>
              <Eyebrow>Candidate · Signed in as {user.email}</Eyebrow>
              <h1 style={{ marginTop: 24, fontSize: "clamp(40px, 6vw, 88px)" }}>
                {profile.full_name || "Your"} <em>file.</em>
              </h1>
            </div>
            <button className="btn btn--quiet" onClick={() => { logout(); go("home"); }}>Sign out</button>
          </div>
        </div>
      </section>

      <section>
        <div className="shell">
          <Tabs
            value={tab}
            onChange={setTab}
            tabs={[
              { id: "profile", label: "Profile" },
              { id: "resume", label: "Resume" },
              { id: "applications", label: "Applications", count: apps.length },
            ]}
          />
          <div className="dash-body">
            {tab === "profile" && <ProfileForm profile={profile} onSaved={setProfile} />}
            {tab === "resume" && <ResumePanel profile={profile} onUploaded={setProfile} />}
            {tab === "applications" && <ApplicationsList apps={apps} roles={roles} onChange={setApps} />}
          </div>
        </div>
      </section>
    </main>
  );
}

function ProfileForm({ profile, onSaved }) {
  const [form, setForm] = React.useState({ ...profile, skills: profile.skills || [], chains: profile.chains || [] });
  const [skillsText, setSkillsText] = React.useState((profile.skills || []).join(", "));
  const [chainsText, setChainsText] = React.useState((profile.chains || []).join(", "));
  const [saving, setSaving] = React.useState(false);
  const [msg, setMsg] = React.useState("");

  const set = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value === "" ? null : e.target.value }));
  const setNum = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value === "" ? null : Number(e.target.value) }));

  const submit = async (e) => {
    e.preventDefault();
    setSaving(true); setMsg("");
    try {
      const body = {
        full_name: form.full_name,
        headline: form.headline,
        bio: form.bio,
        location: form.location,
        timezone: form.timezone,
        skills: skillsText.split(",").map((s) => s.trim()).filter(Boolean),
        chains: chainsText.split(",").map((s) => s.trim()).filter(Boolean),
        years_experience: form.years_experience,
        seniority: form.seniority,
        comp_min_k: form.comp_min_k,
        comp_max_k: form.comp_max_k,
        open_to_offers: form.open_to_offers,
        github_url: form.github_url,
        twitter_url: form.twitter_url,
        linkedin_url: form.linkedin_url,
        website_url: form.website_url,
      };
      const saved = await window.W3J_API.apiFetch("/candidates/me", { method: "PUT", body });
      onSaved(saved);
      setMsg("Saved.");
    } catch (ex) {
      setMsg(ex.message || "Save failed");
    } finally {
      setSaving(false);
    }
  };

  return (
    <form className="form-grid" onSubmit={submit}>
      <div className="form-section">
        <h4 className="form-h">Basics</h4>
        <label className="field"><span className="field-label">Full name</span>
          <input value={form.full_name || ""} onChange={set("full_name")} required maxLength={160} /></label>
        <label className="field"><span className="field-label">Headline</span>
          <input value={form.headline || ""} onChange={set("headline")} placeholder="e.g. Senior Protocol Engineer" /></label>
        <label className="field"><span className="field-label">Bio</span>
          <textarea rows={5} value={form.bio || ""} onChange={set("bio")} /></label>
        <div className="field-row">
          <label className="field"><span className="field-label">Location</span>
            <input value={form.location || ""} onChange={set("location")} placeholder="NYC, Berlin, Remote…" /></label>
          <label className="field"><span className="field-label">Timezone</span>
            <input value={form.timezone || ""} onChange={set("timezone")} placeholder="UTC-5" /></label>
        </div>
      </div>

      <div className="form-section">
        <h4 className="form-h">Experience</h4>
        <div className="field-row">
          <label className="field"><span className="field-label">Years experience</span>
            <input type="number" min="0" max="80" value={form.years_experience ?? ""} onChange={setNum("years_experience")} /></label>
          <label className="field"><span className="field-label">Seniority</span>
            <select value={form.seniority || ""} onChange={set("seniority")}>
              <option value="">—</option>
              {SENIORITY.map((s) => <option key={s} value={s}>{s}</option>)}
            </select></label>
        </div>
        <label className="field"><span className="field-label">Skills (comma-separated)</span>
          <input value={skillsText} onChange={(e) => setSkillsText(e.target.value)} placeholder="Rust, Solidity, MEV" /></label>
        <label className="field"><span className="field-label">Chains (comma-separated)</span>
          <input value={chainsText} onChange={(e) => setChainsText(e.target.value)} placeholder="Solana, EVM, Bitcoin" /></label>
      </div>

      <div className="form-section">
        <h4 className="form-h">Comp & availability</h4>
        <div className="field-row">
          <label className="field"><span className="field-label">Comp min (USD, in $k)</span>
            <input type="number" min="0" value={form.comp_min_k ?? ""} onChange={setNum("comp_min_k")} /></label>
          <label className="field"><span className="field-label">Comp max (USD, in $k)</span>
            <input type="number" min="0" value={form.comp_max_k ?? ""} onChange={setNum("comp_max_k")} /></label>
        </div>
        <label className="field"><span className="field-label">Status</span>
          <select value={form.open_to_offers} onChange={set("open_to_offers")}>
            {OPEN_TO.map((o) => <option key={o.v} value={o.v}>{o.l}</option>)}
          </select></label>
      </div>

      <div className="form-section">
        <h4 className="form-h">Links</h4>
        <label className="field"><span className="field-label">GitHub</span>
          <input value={form.github_url || ""} onChange={set("github_url")} /></label>
        <label className="field"><span className="field-label">X / Twitter</span>
          <input value={form.twitter_url || ""} onChange={set("twitter_url")} /></label>
        <label className="field"><span className="field-label">LinkedIn</span>
          <input value={form.linkedin_url || ""} onChange={set("linkedin_url")} /></label>
        <label className="field"><span className="field-label">Website</span>
          <input value={form.website_url || ""} onChange={set("website_url")} /></label>
      </div>

      <div className="form-actions">
        <button type="submit" className="btn btn--primary" disabled={saving}>{saving ? "Saving…" : "Save profile"} <Icon.Arrow /></button>
        {msg && <span className="form-msg">{msg}</span>}
      </div>
    </form>
  );
}

function ResumePanel({ profile, onUploaded }) {
  const [uploading, setUploading] = React.useState(false);
  const [parsing, setParsing] = React.useState(false);
  const [err, setErr] = React.useState("");
  const [parsed, setParsed] = React.useState(null);
  const inputRef = React.useRef(null);

  const upload = async (file) => {
    if (!file) return;
    setErr(""); setUploading(true); setParsed(null);
    try {
      const fd = new FormData();
      fd.append("file", file);
      const res = await window.W3J_API.apiFetch("/uploads/resume", { method: "POST", body: fd, isForm: true });
      onUploaded({ ...profile, resume_key: res.resume_key });
    } catch (ex) {
      setErr(ex.message || "Upload failed");
    } finally {
      setUploading(false);
    }
  };

  const viewResume = async () => {
    const { download_url } = await window.W3J_API.apiFetch(`/uploads/resume/${profile.user_id}/url`);
    window.open(download_url, "_blank", "noopener");
  };

  const parseResume = async () => {
    setParsing(true); setErr(""); setParsed(null);
    try {
      const res = await window.W3J_API.apiFetch("/uploads/resume/parse", { method: "POST" });
      setParsed(res);
    } catch (ex) {
      setErr(ex.status === 503
        ? "Resume parsing isn't configured on this server. Set LLM_PROVIDER + LLM_API_KEY."
        : (ex.message || "Parsing failed"));
    } finally {
      setParsing(false);
    }
  };

  const applyParsed = async () => {
    const body = {
      full_name: parsed.full_name ?? profile.full_name,
      headline: parsed.headline ?? profile.headline,
      bio: parsed.bio ?? profile.bio,
      location: parsed.location ?? profile.location,
      timezone: profile.timezone,
      skills: parsed.skills ?? profile.skills ?? [],
      chains: parsed.chains ?? profile.chains ?? [],
      years_experience: parsed.years_experience ?? profile.years_experience,
      seniority: parsed.seniority ?? profile.seniority,
      comp_min_k: parsed.comp_min_k ?? profile.comp_min_k,
      comp_max_k: parsed.comp_max_k ?? profile.comp_max_k,
      open_to_offers: profile.open_to_offers,
      github_url: parsed.github_url ?? profile.github_url,
      twitter_url: parsed.twitter_url ?? profile.twitter_url,
      linkedin_url: parsed.linkedin_url ?? profile.linkedin_url,
      website_url: parsed.website_url ?? profile.website_url,
    };
    const saved = await window.W3J_API.apiFetch("/candidates/me", { method: "PUT", body });
    onUploaded(saved);
    setParsed(null);
  };

  return (
    <div className="form-section" style={{ maxWidth: 720 }}>
      <h4 className="form-h">Resume</h4>
      <p className="body" style={{ marginBottom: 20 }}>
        PDF or DOCX, up to 10 MB. Visible only to recruiters who match you to a role.
      </p>
      {profile.resume_key ? (
        <div className="resume-row">
          <div>
            <div style={{ color: "var(--fg)", fontSize: 14 }}>Resume on file</div>
            <div className="mono" style={{ fontSize: 11, color: "var(--fg-faint)", letterSpacing: "0.06em", marginTop: 4 }}>
              {profile.resume_key.split("/").slice(-1)[0]}
            </div>
          </div>
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
            <button type="button" className="btn btn--ghost" onClick={viewResume}>View</button>
            <button type="button" className="btn btn--ghost" onClick={() => inputRef.current?.click()}>Replace</button>
            <button type="button" className="btn btn--primary" onClick={parseResume} disabled={parsing}>
              {parsing ? "Parsing…" : "Autofill profile"} <Icon.Arrow />
            </button>
          </div>
        </div>
      ) : (
        <button type="button" className="btn btn--primary" onClick={() => inputRef.current?.click()} disabled={uploading}>
          {uploading ? "Uploading…" : "Upload resume"} <Icon.Arrow />
        </button>
      )}
      <input ref={inputRef} type="file" accept=".pdf,.doc,.docx,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"
             style={{ display: "none" }} onChange={(e) => upload(e.target.files?.[0])} />
      {err && <div className="form-error" style={{ marginTop: 12 }}>{err}</div>}

      {parsed && (
        <div className="parsed-preview">
          <div className="form-h" style={{ marginBottom: 12 }}>Parsed from your resume</div>
          <div className="kv-grid">
            {Object.entries(parsed).filter(([, v]) => v != null && v !== "" && !(Array.isArray(v) && v.length === 0))
              .map(([k, v]) => (
                <div className="kv" key={k}>
                  <div className="kv-key">{k.replace(/_/g, " ")}</div>
                  <div className="kv-val" style={{ fontSize: 14, fontWeight: 400, wordBreak: "break-word" }}>
                    {Array.isArray(v) ? v.join(", ") : String(v)}
                  </div>
                </div>
              ))}
          </div>
          <div style={{ marginTop: 16, display: "flex", gap: 8 }}>
            <button type="button" className="btn btn--primary" onClick={applyParsed}>Apply to profile <Icon.Arrow /></button>
            <button type="button" className="btn btn--ghost" onClick={() => setParsed(null)}>Discard</button>
          </div>
        </div>
      )}
    </div>
  );
}

function ApplicationsList({ apps, roles, onChange }) {
  const withdraw = async (id) => {
    const updated = await window.W3J_API.apiFetch(`/applications/${id}/withdraw`, { method: "POST" });
    onChange(apps.map((a) => (a.id === id ? updated : a)));
  };

  if (apps.length === 0) {
    return <div className="jb-empty"><div className="h3">No applications yet.</div><p>Browse open roles to get started.</p></div>;
  }

  return (
    <div className="role-list">
      {apps.map((a) => {
        const r = roles[a.role_id];
        return (
          <div className="role-card" key={a.id}>
            <span className="rid">{r?.public_id || "—"}</span>
            <div>
              <div className="rtitle">{r?.title || "Role removed"}</div>
              <div className="rcompany">{r?.company_display || "—"} · applied {new Date(a.created_at).toLocaleDateString()}</div>
            </div>
            <div className="rmeta"><span className="chip">{STATUS_LABEL[a.status] || a.status}</span></div>
            <div className="rcomp">{r ? <><span className="ccy">$</span>{r.min_comp_k}–{r.max_comp_k}k</> : ""}</div>
            <div className="rarrow">
              {a.status === "submitted" || a.status === "reviewed" ? (
                <button onClick={() => withdraw(a.id)} title="Withdraw" className="btn btn--quiet" style={{ padding: 6 }}><Icon.Close /></button>
              ) : <Icon.Arrow size={12} />}
            </div>
          </div>
        );
      })}
    </div>
  );
}

window.CandidateDashboard = CandidateDashboard;
