/* Dispatch — lane pages (Net Admin, Architects, Developers, QA)
 * Loaded by index.html as a <script type="text/babel"> module, after hub.jsx
 * (it reuses LANE_META + LaneBadge from there) and lib.jsx (primitives,
 * sort, pagination, CollapseToggle, helpers).
 *
 * One reusable LanePage per the saved demo design: collapsible description +
 * KPI cards, a filter toolbar, and a sortable/paginated table. Fed by the live
 * cross-lane feed (window.__DISPATCH_LIVE__.tickets) filtered to the lane, so
 * these show real tickets — the same source as the Hub. */

const LANE_BLURBS = {
  netadmin: 'Connectivity, VPN, DNS, switches, and infrastructure incidents.',
  architect: 'Architecture reviews, ADRs, and cross-cutting technical decisions.',
  dev: 'Feature development and bug fixes across the platform repos.',
  qa: 'Test coverage, regressions, and release readiness.',
};

// Architecture "New proposal" form (ported from the old ArchitectView's
// ProposalModal). Demo stub — captures the ask and closes.
function ProposalModal({ onClose }) {
  const [title, setTitle] = useState('');
  const [problem, setProblem] = useState('');
  const [outcome, setOutcome] = useState('');
  const [sponsor, setSponsor] = useState('');
  const [stage, setStage] = useState('Idea');
  const [effort, setEffort] = useState('M');
  const [horizon, setHorizon] = useState('Q3');
  const [businessValue, setBusinessValue] = useState(60);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState(null);
  const [done, setDone] = useState(null); // the created Help Desk ticket
  const canSubmit = title.trim().length > 3 && problem.trim().length > 5 && !busy;

  const Seg = ({ options, value, onChange }) => (
    <div className="inline-flex rounded-md border p-0.5">
      {options.map(o => (
        <button key={o} type="button" onClick={() => onChange(o)}
          className={cn('rounded px-2.5 py-1 text-xs font-medium', value === o ? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:text-foreground')}>{o}</button>
      ))}
    </div>
  );

  // Persist the proposal as a Help Desk ticket (the real intake — from there it
  // can be triaged and, if it's engineering work, sent to GitHub). The old
  // ProposalModal was a stub with no backend; this makes the button real.
  async function submit() {
    if (!canSubmit) return;
    setBusy(true); setError(null);
    const priority = businessValue >= 80 ? 'high' : businessValue >= 50 ? 'medium' : 'low';
    const description =
      `**Architecture proposal**\n\n` +
      `**Problem**\n${problem.trim()}\n\n` +
      (outcome.trim() ? `**Desired outcome**\n${outcome.trim()}\n\n` : '') +
      `**Sponsor:** ${sponsor || '—'}\n` +
      `**Stage:** ${stage} · **Effort:** ${effort} · **Horizon:** ${horizon} · **Business value:** ${businessValue}/100`;
    try {
      const reporter = api.getCurrentUserName() || api.getCurrentUserEmail() || 'Anonymous';
      const created = await api.createHelpdeskTicket({ title: `[Proposal] ${title.trim()}`, description, category: 'general', priority, reporter }, []);
      setDone(created || {});
    } catch (e) { setError(e.message || 'Failed to file proposal'); }
    finally { setBusy(false); }
  }

  const footer = done
    ? <Button size="sm" onClick={onClose}>Close</Button>
    : (
      <>
        <span className="mr-auto text-xs text-muted-foreground">Filed as a Help Desk ticket for triage.</span>
        <Button size="sm" variant="outline" onClick={onClose}>Cancel</Button>
        <Button size="sm" disabled={!canSubmit} onClick={submit}>{busy ? 'Filing…' : 'Submit proposal'}</Button>
      </>
    );

  if (done) {
    return (
      <Modal open onClose={onClose} title="Proposal submitted" footer={footer}>
        <div className="space-y-3 py-4 text-center">
          <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-primary/10 text-2xl text-primary">✓</div>
          <div className="text-sm font-medium">Proposal filed as a Help Desk ticket{done.githubIssueNumber ? ` · #${done.githubIssueNumber}` : ''}.</div>
          <p className="text-sm text-muted-foreground">It’s in the queue now — the AI Triager will route it, and Architecture can send it to GitHub if it’s engineering work.</p>
        </div>
      </Modal>
    );
  }

  return (
    <Modal open onClose={onClose} title="Submit a proposal" footer={footer}>
      <div className="space-y-4">
        {error && <div className="rounded-md bg-destructive/10 px-3 py-2 text-sm text-destructive">{error}</div>}
        <div className="space-y-1.5">
          <Label>Proposal title</Label>
          <Input autoFocus value={title} onChange={e => setTitle(e.target.value)} placeholder="e.g. Replace legacy SSO with OIDC broker" />
        </div>
        <div className="space-y-1.5">
          <Label>Problem</Label>
          <Textarea value={problem} onChange={e => setProblem(e.target.value)} placeholder="What's broken or missing today? Who feels it?" />
        </div>
        <div className="space-y-1.5">
          <Label>Desired outcome</Label>
          <Textarea value={outcome} onChange={e => setOutcome(e.target.value)} placeholder="What changes when this lands? How will we measure it?" />
        </div>
        <div className="grid grid-cols-2 gap-3">
          <div className="space-y-1.5">
            <Label>Business sponsor</Label>
            <Select value={sponsor} onChange={e => setSponsor(e.target.value)}>
              <option value="">Select…</option>
              <option>Finance — D. Park</option>
              <option>Operations — M. Reyes</option>
              <option>Sales — J. Whitfield</option>
              <option>Engineering — K. Tanaka</option>
              <option>People Ops — L. Owens</option>
            </Select>
          </div>
          <div className="space-y-1.5">
            <Label>Initial stage</Label>
            <div><Seg options={['Idea', 'Discovery', 'Design']} value={stage} onChange={setStage} /></div>
          </div>
        </div>
        <div className="grid grid-cols-2 gap-3">
          <div className="space-y-1.5">
            <Label>Effort</Label>
            <div><Seg options={['S', 'M', 'L', 'XL']} value={effort} onChange={setEffort} /></div>
          </div>
          <div className="space-y-1.5">
            <Label>Target horizon</Label>
            <div><Seg options={['Q2', 'Q3', 'Q4', '2027']} value={horizon} onChange={setHorizon} /></div>
          </div>
        </div>
        <div className="space-y-1.5">
          <Label>Business value <span className="font-normal text-muted-foreground">(self-rated)</span></Label>
          <div className="flex items-center gap-3">
            <input type="range" min="0" max="100" value={businessValue} onChange={e => setBusinessValue(+e.target.value)} className="w-full accent-primary" />
            <span className="w-8 text-right text-sm font-semibold">{businessValue}</span>
          </div>
        </div>
      </div>
    </Modal>
  );
}

function LanePage({ lane }) {
  const meta = LANE_META[lane] || { label: lane, color: '#6c3994' };

  // Live cross-lane feed (same as the Hub), filtered to this lane.
  const [live, setLive] = useState(() => (window.__DISPATCH_LIVE__ && window.__DISPATCH_LIVE__.tickets) || null);
  useEffect(() => {
    const read = () => setLive((window.__DISPATCH_LIVE__ && window.__DISPATCH_LIVE__.tickets) || null);
    read();
    window.addEventListener('dispatch:data-loaded', read);
    return () => window.removeEventListener('dispatch:data-loaded', read);
  }, []);
  const who = (t) => t.requester || t.owner || '—';
  const feed = (Array.isArray(live) ? live : []).filter(t => t.lane === lane);

  const [search, setSearch] = useState('');
  const [status, setStatus] = useState('all');
  const [priority, setPriority] = useState('all');
  const [page, setPage] = useState(1);
  const [sort, toggleSort] = useSort(null);
  const [overviewOpen, setOverviewOpen] = useOverviewOpen();
  const [openItem, setOpenItem] = useState(null);
  const [proposalOpen, setProposalOpen] = useState(false);

  const q = search.trim().toLowerCase();
  const filtered = feed.filter(t =>
    (status === 'all' || t.status === status) &&
    (priority === 'all' || t.priority === priority) &&
    (!q || (t.title || '').toLowerCase().includes(q) || (t.num || '').toLowerCase().includes(q) || String(who(t)).toLowerCase().includes(q)));
  const laneSortVal = (t, k) => k === 'priority' ? (PRIORITY_RANK[t.priority] ?? 9) : k === 'requester' ? String(who(t)) : (t[k] ?? '');
  const rows = sortRows(filtered, sort, laneSortVal);
  useEffect(() => { setPage(1); }, [search, status, priority, sort, lane]);
  const pageCount = Math.max(1, Math.ceil(rows.length / PER_PAGE));
  const paged = rows.slice((page - 1) * PER_PAGE, page * PER_PAGE);

  const kpis = [
    { label: 'Total', value: feed.length },
    { label: 'Open', value: feed.filter(t => t.status === 'new' || t.status === 'in_progress').length },
    { label: 'High / critical', value: feed.filter(t => t.priority === 'high' || t.priority === 'critical').length },
    { label: 'Resolved', value: feed.filter(t => t.status === 'resolved' || t.status === 'closed').length },
  ];
  const statuses = [...new Set(feed.map(t => t.status).filter(Boolean))];

  return (
    <div className="space-y-4">
      {overviewOpen && (
        <>
          <Card className="border-primary/20 bg-primary/5">
            <CardContent className="pt-6">
              <h2 className="text-2xl font-semibold tracking-tight">{meta.label}</h2>
              <p className="mt-1 text-sm text-muted-foreground">{LANE_BLURBS[lane] || 'Work tracked in this lane.'}</p>
            </CardContent>
          </Card>
          <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
            {kpis.map(k => (
              <Card key={k.label}><CardContent className="pt-5">
                <div className="text-sm text-muted-foreground">{k.label}</div>
                <div className="mt-1 text-3xl font-semibold tracking-tight">{k.value}</div>
              </CardContent></Card>
            ))}
          </div>
        </>
      )}

      {lane === 'architect' && (
        <div className="flex items-center justify-end">
          <Button size="sm" onClick={() => setProposalOpen(true)}>New proposal</Button>
        </div>
      )}

      <Card>
        <div className="flex flex-wrap items-center gap-2 border-b p-3">
          <Input className="w-56" placeholder="Search this lane…" value={search} onChange={e => setSearch(e.target.value)} />
          <Select className="w-40" value={status} onChange={e => setStatus(e.target.value)}>
            <option value="all">All statuses</option>
            {statuses.map(s => <option key={s} value={s}>{titleCase(s)}</option>)}
          </Select>
          <Select className="w-40" value={priority} onChange={e => setPriority(e.target.value)}>
            <option value="all">All priorities</option>
            {['low', 'medium', 'high', 'critical'].map(p => <option key={p} value={p}>{titleCase(p)}</option>)}
          </Select>
          <span className="ml-auto text-xs text-muted-foreground">{Array.isArray(live) ? `Live · ${feed.length} in ${meta.label}` : 'Waiting for live data…'}</span>
        </div>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead className="border-b text-muted-foreground">
              <tr className="[&>th]:px-4 [&>th]:py-2.5 [&>th]:text-left [&>th]:font-medium">
                <SortHeader label="Item" sortKey="title" sort={sort} onSort={toggleSort} />
                <SortHeader label="Status" sortKey="status" sort={sort} onSort={toggleSort} />
                <SortHeader label="Priority" sortKey="priority" sort={sort} onSort={toggleSort} />
                <SortHeader label="Requester" sortKey="requester" sort={sort} onSort={toggleSort} />
                <SortHeader label="Age" sortKey="age" sort={sort} onSort={toggleSort} align="right" />
              </tr>
            </thead>
            <tbody className="divide-y">
              {feed.length === 0 && <tr><td colSpan="5" className="px-4 py-6 text-center text-muted-foreground">{Array.isArray(live) ? 'No tickets in this lane.' : 'Sign in on the demo to load live tickets.'}</td></tr>}
              {feed.length > 0 && rows.length === 0 && <tr><td colSpan="5" className="px-4 py-6 text-center text-muted-foreground">No items match.</td></tr>}
              {paged.map(t => (
                <tr key={t.id} onClick={() => setOpenItem(t)} className="cursor-pointer transition-colors hover:bg-muted/50">
                  <td className="max-w-[340px] px-4 py-2.5">
                    <div className="truncate font-medium">{t.title}</div>
                    <div className="font-mono text-xs text-muted-foreground">{t.num}</div>
                  </td>
                  <td className="px-4 py-2.5"><Badge variant="outline">{titleCase(t.status)}</Badge></td>
                  <td className="px-4 py-2.5"><Badge variant={prioVariant(t.priority)}>{t.priority}</Badge></td>
                  <td className="max-w-[160px] truncate px-4 py-2.5 text-muted-foreground">{who(t)}</td>
                  <td className="px-4 py-2.5 text-right text-muted-foreground">{t.age}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        <div className="flex flex-wrap items-center justify-between gap-2 border-t px-4 py-2">
          <span className="text-xs text-muted-foreground">{rows.length} shown · {feed.length} total</span>
          <Pagination page={page} pageCount={pageCount} onPage={setPage} />
        </div>
      </Card>
      {openItem && <TicketDetailModal item={openItem} onClose={() => setOpenItem(null)} />}
      {proposalOpen && <ProposalModal onClose={() => setProposalOpen(false)} />}
    </div>
  );
}
