// ESS — "My NuCo" chat-first employee app. Replaces the manager shell when state.view === "ess".
// The UX intent: not a static self-service menu. A conversational surface with tiles.

function EmployeeApp() {
  const { state, dispatch } = useApp();
  const person = state.staff.find(s => s.id === state.essPersonId) || state.staff[0];
  const balance = state.leaveBalances.find(b => b.personId === person.id) || { annual: 10, sick: 5, personal: 2, lsl: 0 };

  return (
    <div className="ess-shell">
      <EssTopbar person={person} />
      <div className="ess-page">
        <EssQuickTiles person={person} balance={balance} />
        <EssChat person={person} balance={balance} />
        <EssRoster person={person} />
        <EssCareImpact />
      </div>
    </div>
  );
}

function EssTopbar({ person }) {
  const { dispatch } = useApp();
  return (
    <header className="ess-topbar">
      <div className="hstack" style={{ gap: 10 }}>
        <div className="brand-mark">N</div>
        <div>
          <div style={{ fontWeight: 600, fontSize: 14 }}>My NuCo</div>
          <div className="sub" style={{ fontSize: 11 }}>{person.name} · {person.grade} · {person.ward}</div>
        </div>
      </div>
      <div className="hstack" style={{ gap: 8 }}>
        <Badge tone="ai" dot>Guardrails · L3</Badge>
        <button className="btn" onClick={() => dispatch({ type: "SET_VIEW", view: "manager" })}>
          <Icon name="arrowRight" size={12} /> Back to Manager
        </button>
      </div>
    </header>
  );
}

function EssQuickTiles({ person, balance }) {
  const { dispatch } = useApp();
  return (
    <div className="ess-tiles">
      <div className="ess-tile">
        <div className="eyebrow">Next shift</div>
        <div className="serif" style={{ fontSize: 20, fontWeight: 500, letterSpacing: "-0.01em", marginTop: 4 }}>Tue 21 Apr · 07:00</div>
        <div className="sub" style={{ fontSize: 11.5 }}>{person.ward} · Day · 8h</div>
        <button className="btn ghost" style={{ marginTop: 8, padding: "3px 8px", fontSize: 11 }} onClick={() => dispatch({ type: "PUSH_TOAST", toast: { tone: "ok", text: "Swap request drafted · NuCo looking for cover" } })}>Swap shift</button>
      </div>
      <div className="ess-tile">
        <div className="eyebrow">Last pay</div>
        <div className="serif" style={{ fontSize: 20, fontWeight: 500, letterSpacing: "-0.01em", marginTop: 4 }}>$2,140</div>
        <div className="sub" style={{ fontSize: 11.5 }}>Period 4 Apr – 17 Apr · payslip available</div>
        <button className="btn ghost" style={{ marginTop: 8, padding: "3px 8px", fontSize: 11 }} onClick={() => dispatch({ type: "PUSH_TOAST", toast: { tone: "ok", text: "Payslip opened" } })}>View payslip</button>
      </div>
      <div className="ess-tile">
        <div className="eyebrow">Leave balance</div>
        <div className="hstack" style={{ gap: 10, marginTop: 4, flexWrap: "wrap", fontSize: 12 }}>
          <span>Annual <strong>{balance.annual}d</strong></span>
          <span>Sick <strong>{balance.sick}d</strong></span>
          <span>Personal <strong>{balance.personal}d</strong></span>
        </div>
        <div className="sub" style={{ fontSize: 11.5, marginTop: 6 }}>LSL {balance.lsl}d · accruing live</div>
      </div>
    </div>
  );
}

// Conversational leave — scripted LLM stand-in that parses intents and applies policy rules.
const LEAVE_KEYWORDS = [
  { k: ["sick", "unwell", "ill", "medical"], type: "Sick" },
  { k: ["carer", "family", "parent", "kid", "child"],   type: "Personal" },
  { k: ["annual", "holiday", "vacation", "leave"], type: "Annual" },
  { k: ["day off", "off on", "off this", "off next"], type: "Personal" },
];
const DAY_KEYWORDS = {
  monday: { label: "Mon 20 Apr", iso: "2026-04-20" },
  tuesday: { label: "Tue 21 Apr", iso: "2026-04-21" },
  wednesday: { label: "Wed 22 Apr", iso: "2026-04-22" },
  thursday: { label: "Thu 23 Apr", iso: "2026-04-23" },
  friday: { label: "Fri 24 Apr", iso: "2026-04-24" },
  saturday: { label: "Sat 25 Apr", iso: "2026-04-25" },
  sunday: { label: "Sun 26 Apr", iso: "2026-04-26" },
  tomorrow: { label: "Tomorrow", iso: "2026-04-18" },
  today: { label: "Today", iso: "2026-04-17" },
};

function parseLeave(text) {
  const t = text.toLowerCase();
  // Intent
  let type = "Personal";
  for (const group of LEAVE_KEYWORDS) { if (group.k.some(w => t.includes(w))) { type = group.type; break; } }
  // Day
  let day = null;
  for (const key in DAY_KEYWORDS) { if (t.includes(key)) { day = DAY_KEYWORDS[key]; break; } }
  // Multi-day heuristic
  const multiDay = /\b(\d+)\s+(day|days|week|weeks)\b/.exec(t);
  const days = multiDay ? (parseInt(multiDay[1]) * (multiDay[2].startsWith("week") ? 7 : 1)) : (day ? 1 : 0);
  return { type, day, days };
}

function EssChat({ person, balance }) {
  const { state, dispatch } = useApp();
  const [input, setInput] = React.useState("");
  const [pendingRequest, setPendingRequest] = React.useState(null);
  const bodyRef = React.useRef(null);

  React.useEffect(() => {
    if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
  }, [state.essMessages, pendingRequest]);

  function respond(text) {
    const parsed = parseLeave(text);
    if (parsed.day && parsed.days > 0) {
      const balanceField = parsed.type === "Annual" ? "annual" : parsed.type === "Sick" ? "sick" : "personal";
      const remaining = balance[balanceField] - parsed.days;
      const needsCert = parsed.type === "Sick" && parsed.days >= 2;
      const escalate = parsed.days >= 2 || parsed.type === "Annual";
      const policyOk = remaining >= 0 && !needsCert;

      const summary = {
        personId: person.id,
        personName: person.name,
        type: parsed.type,
        start: parsed.day.iso,
        end: parsed.day.iso,
        days: parsed.days,
        reason: `Submitted via My NuCo · "${text}"`,
        rosterImpact: `${parsed.day.label} shift needs cover · NuCo has 2 options ready`,
        policyOk,
        escalate,
        remaining,
        balanceField,
        needsCert,
      };
      setPendingRequest(summary);

      const ai = [
        `Got it — ${parsed.type.toLowerCase()} leave on ${parsed.day.label}.`,
        `Balance impact: ${parsed.type} ${balance[balanceField]}d → **${remaining}d**.`,
        `Policy check: ${policyOk ? "✅ within policy" : "⚠️ requires evidence or manager approval"}. ${needsCert ? "Sick leave over 2 days needs a medical certificate." : ""}`,
        `Roster impact: ${summary.rosterImpact}.`,
        escalate ? "This one needs **Jess Palmer's** approval — she'll see it in the Leave queue as soon as you confirm." : "This fits auto-approve policy — confirm and I'll book it.",
        "Review the summary below and tap Confirm.",
      ].join("\n\n");

      dispatch({ type: "ESS_MSG", msg: { role: "ai", text: ai } });
      return;
    }
    // Non-leave general answers.
    if (text.toLowerCase().includes("pay")) {
      dispatch({ type: "ESS_MSG", msg: { role: "ai", text: "Your last payslip was $2,140 for period 4–17 Apr. Your super went to HESTA ($228). Anything else?" } });
      return;
    }
    if (text.toLowerCase().includes("shift") || text.toLowerCase().includes("roster")) {
      dispatch({ type: "ESS_MSG", msg: { role: "ai", text: "Your next 7 days: Tue 21 Apr 07:00 Banksia, Thu 23 Apr 07:00 Banksia, Sat 25 Apr 15:00 Banksia. Want to swap any?" } });
      return;
    }
    dispatch({ type: "ESS_MSG", msg: { role: "ai", text: "I can help with leave, shifts, pay, and credential uploads. Try 'I need Thursday off' or 'When's my next shift?'" } });
  }

  function send(e) {
    e && e.preventDefault();
    const q = input.trim();
    if (!q) return;
    dispatch({ type: "ESS_MSG", msg: { role: "me", text: q } });
    setInput("");
    setTimeout(() => respond(q), 400);
  }

  function quick(text) {
    dispatch({ type: "ESS_MSG", msg: { role: "me", text } });
    setTimeout(() => respond(text), 400);
  }

  function confirmLeave() {
    const payload = { ...pendingRequest };
    dispatch({ type: "NEW_LEAVE_REQUEST", payload });
    dispatch({ type: "PUSH_TOAST", toast: { tone: "ok", text: "Leave request submitted · tracked in Leave queue" } });
    dispatch({ type: "ESS_MSG", msg: { role: "ai", text: `Done — request submitted. ${payload.escalate ? "Jess will review it this shift." : "Auto-approved under policy. Your roster has been updated."}` } });
    setPendingRequest(null);
  }

  function cancelPending() {
    setPendingRequest(null);
    dispatch({ type: "ESS_MSG", msg: { role: "ai", text: "No worries — cancelled. Anything else?" } });
  }

  return (
    <div className="ess-chat">
      <div className="ess-chat-head">
        <div className="hstack" style={{ gap: 8 }}>
          <Icon name="sparkle" size={14} />
          <strong style={{ fontSize: 13 }}>Ask NuCo</strong>
        </div>
        <div className="hstack" style={{ gap: 6 }}>
          <TierBadge tier="L3" />
          <ConfidencePill value={0.91} />
        </div>
      </div>
      <div className="ess-chat-body" ref={bodyRef}>
        {state.essMessages.map(m => (
          <div key={m.id} className={"chat-msg" + (m.role === "me" ? " me" : "")}>
            {m.text.split("\n\n").map((para, i) => <div key={i} style={{ marginTop: i ? 8 : 0 }}>{para}</div>)}
          </div>
        ))}
        {pendingRequest && (
          <div className="ess-leave-card">
            <div className="hstack" style={{ justifyContent: "space-between", marginBottom: 6 }}>
              <strong style={{ fontSize: 13 }}>{pendingRequest.type} leave · {pendingRequest.days}d</strong>
              <Badge tone={pendingRequest.policyOk ? "ok" : "warn"} dot>{pendingRequest.policyOk ? "within policy" : "needs review"}</Badge>
            </div>
            <div className="sub" style={{ fontSize: 11.5, marginBottom: 10 }}>{pendingRequest.start} → {pendingRequest.end} · remaining balance {pendingRequest.remaining}d</div>
            <div className="sub" style={{ fontSize: 11, marginBottom: 10 }}>{pendingRequest.rosterImpact}</div>
            <div className="hstack" style={{ gap: 6 }}>
              <button className="btn sage" onClick={confirmLeave}><Icon name="check" size={12} /> Confirm</button>
              <button className="btn" onClick={cancelPending}>Cancel</button>
            </div>
          </div>
        )}
      </div>
      <div className="ess-quick-row">
        {[
          "I need Thursday off",
          "When's my next shift?",
          "Last payslip",
          "Upload certificate",
        ].map(q => (
          <button key={q} className="chip" onClick={() => quick(q)}>{q}</button>
        ))}
      </div>
      <form className="chat-input" onSubmit={send} style={{ borderRadius: "0 0 12px 12px" }}>
        <input placeholder="Ask NuCo anything…" value={input} onChange={e => setInput(e.target.value)} />
        <button type="submit" className="icon-btn" style={{ background: "var(--ink)", color: "var(--paper)" }}><Icon name="arrowRight" size={14} /></button>
      </form>
    </div>
  );
}

function EssRoster({ person }) {
  const days = [
    { d: "Tue 21 Apr", kind: "day",     time: "07:00–15:00", ward: "Banksia" },
    { d: "Thu 23 Apr", kind: "day",     time: "07:00–15:00", ward: "Banksia" },
    { d: "Sat 25 Apr", kind: "evening", time: "15:00–23:00", ward: "Banksia" },
  ];
  return (
    <div className="ess-card">
      <div className="hstack" style={{ justifyContent: "space-between", marginBottom: 8 }}>
        <div><strong style={{ fontSize: 13.5 }}>My roster · next 7 days</strong></div>
        <Badge tone="ok" dot>3 shifts</Badge>
      </div>
      <div className="vstack" style={{ gap: 8 }}>
        {days.map((s, i) => (
          <div key={i} className="hstack" style={{ gap: 10, padding: 10, background: "var(--bone)", borderRadius: 6, border: "1px solid var(--line)" }}>
            <div className="shift" data-kind={s.kind} style={{ position: "static", width: 72, padding: "2px 6px", fontSize: 10.5, overflow: "hidden" }}>{s.kind}</div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontWeight: 500, fontSize: 12.5 }}>{s.d}</div>
              <div className="sub mono" style={{ fontSize: 11 }}>{s.time} · {s.ward}</div>
            </div>
            <Gate tone="ok" />
          </div>
        ))}
      </div>
    </div>
  );
}

function EssCareImpact() {
  return (
    <div className="ess-card">
      <div className="hstack" style={{ justifyContent: "space-between", marginBottom: 8 }}>
        <div><strong style={{ fontSize: 13.5 }}>My care impact · this week</strong></div>
        <Badge tone="ai" dot>patient-centred</Badge>
      </div>
      <div className="grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(130px, 1fr))", gap: 10 }}>
        {[
          { label: "Residents on my rounds",  value: "14" },
          { label: "Medication rounds",       value: "48" },
          { label: "Wound care tasks",        value: "12" },
          { label: "Handovers logged",        value: "6" },
        ].map(m => (
          <div key={m.label} style={{ padding: 10, background: "var(--bone)", border: "1px solid var(--line)", borderRadius: 6 }}>
            <div className="serif" style={{ fontSize: 22, fontWeight: 500, letterSpacing: "-0.015em" }}>{m.value}</div>
            <div className="sub" style={{ fontSize: 11 }}>{m.label}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { EmployeeApp });
