// Login screen + profile-completion onboarding (multi-step with API calls)

// Constellation canvas — feed-forward neural net with firing pulses.
// Input neurons fire periodically; signals travel along weighted edges as glowing
// pulses, activating downstream neurons which forward to the next layer.
const ConstellationCanvas = () => {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    let raf;
    let nodes = [];
    let edges = [];
    let outEdges = new Map();
    let lastFire = 0;
    const LAYER_COUNT = 4;

    const build = () => {
      const W = canvas.width = canvas.offsetWidth;
      const H = canvas.height = canvas.offsetHeight;
      const xs = [W * 0.18, W * 0.40, W * 0.62, W * 0.84];
      const counts = [8, 11, 11, 6];
      nodes = [];
      counts.forEach((c, li) => {
        const padY = 80;
        const usable = H - padY * 2;
        for (let i = 0; i < c; i++) {
          const y = padY + (usable * (i + 0.5)) / c;
          nodes.push({
            x: xs[li], y, baseX: xs[li], baseY: y,
            layer: li, activation: 0,
            phase: Math.random() * Math.PI * 2,
          });
        }
      });
      edges = [];
      outEdges = new Map();
      for (let li = 0; li < LAYER_COUNT - 1; li++) {
        const a = nodes.filter(n => n.layer === li);
        const b = nodes.filter(n => n.layer === li + 1);
        for (const na of a) for (const nb of b) {
          if (Math.random() < 0.72) {
            const e = { a: na, b: nb, w: 0.2 + Math.random() * 0.8, fires: [] };
            edges.push(e);
            if (!outEdges.has(na)) outEdges.set(na, []);
            outEdges.get(na).push(e);
          }
        }
      }
    };
    build();
    const onResize = () => build();
    window.addEventListener("resize", onResize);

    const fireInput = (now) => {
      const inputs = nodes.filter(n => n.layer === 0);
      const n = inputs[Math.floor(Math.random() * inputs.length)];
      n.activation = 1;
      const outs = outEdges.get(n) || [];
      const k = Math.max(2, Math.floor(outs.length * 0.55));
      const picks = outs.slice().sort(() => Math.random() - 0.5).slice(0, k);
      for (const e of picks) e.fires.push({ start: now, dur: 600 + Math.random() * 300 });
    };
    const activateAndForward = (n, now) => {
      n.activation = Math.min(1, n.activation + 0.9);
      if (n.layer >= LAYER_COUNT - 1) return;
      const outs = outEdges.get(n) || [];
      const k = Math.max(1, Math.floor(outs.length * (0.45 - n.layer * 0.05)));
      const picks = outs.slice().sort(() => Math.random() - 0.5).slice(0, k);
      for (const e of picks) e.fires.push({ start: now, dur: 550 + Math.random() * 300 });
    };

    const tick = (t) => {
      const W = canvas.width, H = canvas.height;
      ctx.clearRect(0, 0, W, H);

      if (t - lastFire > 180) {
        if (Math.random() < 0.7) fireInput(t);
        lastFire = t;
      }

      for (const n of nodes) {
        n.x = n.baseX + Math.sin(t / 1800 + n.phase) * 3;
        n.y = n.baseY + Math.cos(t / 2200 + n.phase) * 4;
      }

      for (const e of edges) {
        ctx.lineWidth = 0.6;
        ctx.strokeStyle = `rgba(255,255,255,${0.10 + e.w * 0.10})`;
        ctx.beginPath();
        ctx.moveTo(e.a.x, e.a.y);
        ctx.lineTo(e.b.x, e.b.y);
        ctx.stroke();

        const still = [];
        for (const f of e.fires) {
          const p = (t - f.start) / f.dur;
          if (p > 1) { activateAndForward(e.b, t); continue; }
          still.push(f);
          const eased = p * p * (3 - 2 * p);
          const hx = e.a.x + (e.b.x - e.a.x) * eased;
          const hy = e.a.y + (e.b.y - e.a.y) * eased;
          const ts = Math.max(0, eased - 0.18);
          const tx = e.a.x + (e.b.x - e.a.x) * ts;
          const ty = e.a.y + (e.b.y - e.a.y) * ts;
          const lg = ctx.createLinearGradient(tx, ty, hx, hy);
          lg.addColorStop(0, "rgba(255,220,200,0)");
          lg.addColorStop(1, "rgba(255,240,220,0.95)");
          ctx.strokeStyle = lg;
          ctx.lineWidth = 1.6;
          ctx.beginPath();
          ctx.moveTo(tx, ty);
          ctx.lineTo(hx, hy);
          ctx.stroke();
          ctx.fillStyle = "rgba(255,255,255,0.95)";
          ctx.beginPath();
          ctx.arc(hx, hy, 2.4, 0, Math.PI * 2);
          ctx.fill();
        }
        e.fires = still;
      }

      for (const n of nodes) {
        n.activation = Math.max(0, n.activation - 0.018);
        const baseR = (n.layer === 0 || n.layer === LAYER_COUNT - 1) ? 4 : 3.2;
        const a = n.activation;
        if (a > 0.05) {
          const haloR = baseR + 14 * a;
          const hg = ctx.createRadialGradient(n.x, n.y, 0, n.x, n.y, haloR);
          hg.addColorStop(0, `rgba(255,235,210,${0.55 * a})`);
          hg.addColorStop(1, "rgba(255,235,210,0)");
          ctx.fillStyle = hg;
          ctx.beginPath();
          ctx.arc(n.x, n.y, haloR, 0, Math.PI * 2);
          ctx.fill();
        }
        ctx.fillStyle = a > 0.05
          ? `rgba(255, ${Math.floor(220 + 35 * a)}, ${Math.floor(200 + 55 * a)}, ${0.85 + 0.15 * a})`
          : "rgba(255,255,255,0.55)";
        ctx.beginPath();
        ctx.arc(n.x, n.y, baseR + a * 1.5, 0, Math.PI * 2);
        ctx.fill();
        if (a > 0.2) {
          ctx.fillStyle = `rgba(255,255,255,${a})`;
          ctx.beginPath();
          ctx.arc(n.x - 0.6, n.y - 0.6, 1.2, 0, Math.PI * 2);
          ctx.fill();
        }
      }

      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => { cancelAnimationFrame(raf); window.removeEventListener("resize", onResize); };
  }, []);
  return <canvas ref={ref} className="constellation-canvas" />;
};

const Login = ({ onLogin }) => {
  const [email, setEmail] = React.useState("");
  const [pw, setPw] = React.useState("");
  const [step, setStep] = React.useState(0); // 0: Identity, 1: Password (manual)
  const [err, setErr] = React.useState({});
  const [loading, setLoading] = React.useState(false);

  const isSsoEmail = email.toLowerCase().endsWith("@primuspartners.in");

  const onNext = (e) => {
    if (e) e.preventDefault();
    const ne = {};
    if (!email.match(/.+@.+\..+/)) ne.email = "Enter a valid work email.";
    setErr(ne);
    if (ne.email) return;
    if (isSsoEmail) {
      setLoading(true);
      window.location.href = `/auth/sso/login?email=${encodeURIComponent(email)}`;
    } else {
      setStep(1);
    }
  };

  const onManualLogin = async (e) => {
    e.preventDefault();
    if (pw.length < 6) { setErr({ pw: "Password must be at least 6 characters." }); return; }
    setLoading(true);
    try {
      const data = await PrimaAPI.login(email, pw);
      onLogin(data);
    } catch (e) {
      setErr({ pw: e.message || "Invalid credentials." });
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="login-shell">

      {/* ── Left: Branding panel ── */}
      <div className="login-brand">
        <ConstellationCanvas />
        <div className="lb-content">
          <div className="lb-top">
            <span className="lb-logo">Prima<em>·</em>Curator</span>
            <span className="lb-version">v3.2 · Primus Partners</span>
          </div>
          <div className="lb-hero">
            <div className="lb-eyebrow">The collective intelligence</div>
            <h1 className="lb-headline">Every deck, dataset<br/>and decision —<br/>woven into one mind.</h1>
          </div>
        </div>
      </div>

      {/* ── Right: Form panel ── */}
      <div className="login-form-panel">
        <div className="login-card">
          <div className="lc-step-indicator">
            <span className="lc-step-label">Sign in</span>
            <div className="lc-steps">
              <span className={`lc-step-dot${step >= 0 ? " active" : ""}`} />
              <span className="lc-step-line" />
              <span className={`lc-step-dot${step >= 1 ? " active" : ""}`} />
            </div>
            <span className="lc-step-count">Step {step + 1} of 2</span>
          </div>

          <h2 className="lc-title">{step === 0 ? "Welcome back." : "Enter password."}</h2>
          <p className="lc-sub">{step === 0 ? "Sign in to contribute to the firm's collective intelligence." : "Enter your credentials to continue."}</p>

          <form onSubmit={step === 0 ? onNext : onManualLogin} className="lc-form">
            {step === 0 ? (
              <Field label="Work email" required error={err.email}>
                <TextInput
                  value={email}
                  onChange={e => { setEmail(e.target.value); setErr({}); }}
                  placeholder="name@primuspartners.in"
                  error={err.email}
                  autoFocus
                />
              </Field>
            ) : (
              <>
                <div className="lc-email-chip">
                  <Icon name="user" size={12} />
                  <span>{email}</span>
                  <button type="button" className="btn ghost sm" onClick={() => setStep(0)}>Edit</button>
                </div>
                <Field label="Password" required error={err.pw}>
                  <TextInput type="password" value={pw} onChange={e => { setPw(e.target.value); setErr({}); }} error={err.pw} autoFocus />
                </Field>
              </>
            )}

            <button type="submit" className="btn primary lg lc-submit" disabled={loading}>
              {loading ? "Connecting…" : <><span>{isSsoEmail ? "Continue with SSO" : step === 0 ? "Continue" : "Sign in"}</span><Icon name="chevron-right" size={14} /></>}
            </button>
          </form>

          <div className="lc-sso-notice">
            <Icon name="shield" size={12} />
            <span><strong>Secure by default</strong> · Microsoft Entra ID enforced · @primuspartners.in SSO required</span>
          </div>

          <div className="lc-footer">
            Trouble signing in? <a href="mailto:it@primuspartners.in">Contact your administrator</a>
          </div>
        </div>
      </div>

    </div>
  );
};

// ─── Profile onboarding ───
const ONBOARDING_STEPS = ["Basic", "Expertise", "Industry", "Review"];

const Onboarding = ({ user, onComplete, onSkip }) => {
  const [step, setStep] = React.useState(0);
  const [form, setForm] = React.useState({
    email: user?.primus_email || user?.email || "",
    fullName: user?.full_name || "",
    empCode: user?.emp_code || "",
    designation: user?.designation || "",
    yoe: user?.yoe || "",
    primary: user?.primary_domain || "",
    secondary: user?.secondary_domain || "",
    skills: user?.skills || [],
    tools: user?.tools || [],
    methodologies: user?.methodologies || [],
    industries: user?.industries || [],
    regions: user?.regions || [],
    languages: user?.languages || [],
  });
  const [errors, setErrors] = React.useState({});
  const [loading, setLoading] = React.useState(false);

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const validateStep = () => {
    const e = {};
    if (step === 0) {
      if (!form.fullName.trim()) e.fullName = "Full name is required.";
      if (!form.empCode.trim()) e.empCode = "Employee code is required.";
      else if (!/^[A-Z0-9-]{4,}$/i.test(form.empCode.trim())) e.empCode = "Use alphanumeric characters only.";
      if (!form.designation) e.designation = "Pick a designation.";
      if (form.yoe === "" || isNaN(+form.yoe) || +form.yoe < 0) e.yoe = "Enter a number ≥ 0.";
      else if (+form.yoe > 50) e.yoe = "That seems unusually high.";
    } else if (step === 1) {
      if (!form.primary) e.primary = "Pick a primary domain.";
      if (form.skills.length === 0) e.skills = "Add at least one skill.";
    } else if (step === 2) {
      if (form.industries.length === 0) e.industries = "Select at least one industry.";
    }
    setErrors(e);
    return Object.keys(e).length === 0;
  };

  const next = async () => {
    if (!validateStep()) return;
    setLoading(true);
    try {
      if (step === 0) {
        await PrimaAPI.profileStep1({
          full_name: form.fullName,
          emp_code: form.empCode,
          designation: form.designation,
          yoe: parseInt(form.yoe, 10),
        });
      } else if (step === 1) {
        await PrimaAPI.profileStep2({
          primary_domain: form.primary,
          secondary_domain: form.secondary || "",
          skills: form.skills,
          tools: form.tools,
          methodologies: form.methodologies,
        });
      } else if (step === 2) {
        await PrimaAPI.profileStep3({
          industries: form.industries,
          regions: form.regions,
          languages: form.languages,
        });
      }
      setStep(s => Math.min(s + 1, ONBOARDING_STEPS.length - 1));
    } catch (e) {
      setErrors({ api: e.message });
    } finally {
      setLoading(false);
    }
  };

  const back = () => setStep(s => Math.max(s - 1, 0));

  const handleSubmit = async () => {
    setLoading(true);
    try {
      await PrimaAPI.profileFinalize();
      onComplete(form);
    } catch (e) {
      setErrors({ api: e.message });
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="onb-shell">
      <aside className="onb-aside">
        <div className="deco" />
        <span className="brand-mark">Prima<em>·</em>Curator</span>
        <h1>Build the <em>Consultant DNA.</em></h1>
        <p className="lead">A few minutes to map your expertise — so the firm's intelligence layer can find you, route work to you, and surface your past work to colleagues.</p>
        <div className="pillars">
          <div className="pillar"><span className="num">01</span><div className="text"><strong>Capture once.</strong> Used everywhere — RAG retrieval, project staffing, leaderboards.</div></div>
          <div className="pillar"><span className="num">02</span><div className="text"><strong>Edit any time.</strong> Profile lives in the sidebar. Update as you grow.</div></div>
          <div className="pillar"><span className="num">03</span><div className="text"><strong>Your data.</strong> Never shared outside Primus. Restricted views by role.</div></div>
        </div>
      </aside>

      <main className="onb-form">
        <div className="container">
          <div className="eyebrow"><Icon name="user" size={11} /> Profile completion · One-time</div>
          <h2>Tell us about your <em style={{ fontFamily: "var(--font-display)", fontStyle: "italic", color: "var(--accent-deep)" }}>practice.</em></h2>
          <p className="desc">Every dropdown drives downstream tagging. Pick what's true today — you can refine later.</p>

          {/* Steps */}
          <div className="steps" style={{ borderRadius: 6, border: "1px solid var(--hairline)", margin: "20px 0 28px" }}>
            {ONBOARDING_STEPS.map((s, i) => (
              <React.Fragment key={s}>
                <div className="step" data-state={i === step ? "active" : i < step ? "done" : "pending"}>
                  <span className="dot">{i < step ? <Icon name="check" size={10} /> : i + 1}</span>
                  {s}
                </div>
                {i < ONBOARDING_STEPS.length - 1 && <span className="step-line" />}
              </React.Fragment>
            ))}
          </div>

          {errors.api && (
            <div style={{ padding: "10px 14px", background: "var(--err-soft, #fef2f2)", color: "var(--err, #dc2626)", borderRadius: 6, fontSize: 13, marginBottom: 16 }}>
              {errors.api}
            </div>
          )}

          {step === 0 && <BasicStep form={form} set={set} errors={errors} />}
          {step === 1 && <ExpertiseStep form={form} set={set} errors={errors} />}
          {step === 2 && <IndustryStep form={form} set={set} errors={errors} />}
          {step === 3 && <ReviewStep form={form} />}

          <div style={{ display: "flex", justifyContent: "space-between", marginTop: 32, paddingTop: 20, borderTop: "1px solid var(--hairline)" }}>
            <button className="btn ghost" onClick={onSkip}>Save &amp; exit</button>
            <div style={{ display: "flex", gap: 8 }}>
              {step > 0 && <button className="btn" onClick={back} disabled={loading}><Icon name="chevron-left" size={14} /> Back</button>}
              {step < ONBOARDING_STEPS.length - 1 ? (
                <button className="btn primary" onClick={next} disabled={loading}>
                  {loading ? "Saving…" : <><span>Continue</span> <Icon name="chevron-right" size={14} /></>}
                </button>
              ) : (
                <button className="btn accent" onClick={handleSubmit} disabled={loading}>
                  {loading ? "Submitting…" : <><Icon name="check" size={14} /> Submit profile</>}
                </button>
              )}
            </div>
          </div>
        </div>
      </main>
    </div>
  );
};

const BasicStep = ({ form, set, errors }) => {
  const isSso = form.email.toLowerCase().endsWith("@primuspartners.in");
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      <div className="grid-2">
        <Field label="Primus email" required hint="Read-only.">
          <TextInput readOnly value={form.email} />
        </Field>
        <Field label="Full name" required error={errors.fullName} hint={isSso ? "Synced with HR records." : null}>
          <TextInput value={form.fullName} onChange={e => set("fullName", e.target.value)}
                     placeholder="As on records" error={errors.fullName} readOnly={isSso} />
        </Field>
      </div>
      <div className="grid-2">
        <Field label="Employee code" required error={errors.empCode}>
          <TextInput value={form.empCode} onChange={e => set("empCode", e.target.value.toUpperCase())}
                     placeholder="e.g. PP-04129" error={errors.empCode} />
        </Field>
        <Field label="Designation" required error={errors.designation} hint={isSso ? "Synced from Microsoft Graph." : null}>
          <Select value={form.designation} onChange={v => set("designation", v)}
                  options={TAXONOMY.designations} error={errors.designation} disabled={isSso} />
        </Field>
      </div>
      <Field label="Years of experience" required error={errors.yoe}>
        <TextInput type="number" min="0" max="50" value={form.yoe}
                   onChange={e => set("yoe", e.target.value)} placeholder="0" error={errors.yoe} />
      </Field>
    </div>
  );
};

const ExpertiseStep = ({ form, set, errors }) => (
  <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
    <div className="grid-2">
      <Field label="Primary domain" required error={errors.primary}>
        <Select value={form.primary} onChange={v => set("primary", v)}
                options={TAXONOMY.domains} error={errors.primary} />
      </Field>
      <Field label="Secondary domain" optional>
        <Select value={form.secondary} onChange={v => set("secondary", v)}
                options={TAXONOMY.domains.filter(d => d !== form.primary)} placeholder="Optional…" />
      </Field>
    </div>
    <Field label="Skills" required hint="At least one. Type to search; Enter to add." error={errors.skills}>
      <MultiSelect values={form.skills} onChange={v => set("skills", v)} options={TAXONOMY.skills} allowCustom />
    </Field>
    <Field label="Tools / Tech" optional>
      <MultiSelect values={form.tools} onChange={v => set("tools", v)} options={TAXONOMY.tools} allowCustom />
    </Field>
    <Field label="Methodologies" optional>
      <MultiSelect values={form.methodologies} onChange={v => set("methodologies", v)} options={TAXONOMY.methodologies} />
    </Field>
  </div>
);

const IndustryStep = ({ form, set, errors }) => (
  <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
    <Field label="Industries" required hint="Sectors you have delivered work in." error={errors.industries}>
      <MultiSelect values={form.industries} onChange={v => set("industries", v)} options={TAXONOMY.industries} />
    </Field>
    <Field label="Regions" optional>
      <MultiSelect values={form.regions} onChange={v => set("regions", v)} options={TAXONOMY.regions} />
    </Field>
    <Field label="Languages" optional hint="Spoken — for stakeholder fit and translation work.">
      <MultiSelect values={form.languages} onChange={v => set("languages", v)} options={TAXONOMY.languages} allowCustom />
    </Field>
  </div>
);

const ReviewStep = ({ form }) => {
  const Row = ({ k, v }) => (
    <div className="review-pair">
      <div className="k">{k}</div>
      <div className="v">{v && (Array.isArray(v) ? (v.length ? v.map(x => <span key={x} className="chip">{x}</span>) : <span style={{ color: "var(--fg-subtle)" }}>—</span>) : v) || <span style={{ color: "var(--fg-subtle)" }}>—</span>}</div>
    </div>
  );
  const designationLabel = TAXONOMY.designations.find(d => d.value === form.designation)?.label || form.designation || "Profile";
  return (
    <div className="card">
      <div className="card-head">
        <h3 className="card-title">Review your Consultant DNA</h3>
        <span className="tag accent">{designationLabel}</span>
      </div>
      <div className="card-body" style={{ paddingTop: 4, paddingBottom: 4 }}>
        <Row k="Email" v={form.email} />
        <Row k="Full name" v={form.fullName} />
        <Row k="Employee code" v={form.empCode} />
        <Row k="Designation" v={designationLabel} />
        <Row k="Experience" v={form.yoe ? `${form.yoe} years` : null} />
        <Row k="Primary domain" v={form.primary} />
        <Row k="Secondary domain" v={form.secondary} />
        <Row k="Skills" v={form.skills} />
        <Row k="Tools / Tech" v={form.tools} />
        <Row k="Methodologies" v={form.methodologies} />
        <Row k="Industries" v={form.industries} />
        <Row k="Regions" v={form.regions} />
        <Row k="Languages" v={form.languages} />
      </div>
    </div>
  );
};

Object.assign(window, { Login, Onboarding });
