// PortalTable Dashboard — table-driven views: Clients, Projects, Approvals, Invoices.

const { useState: useStateT } = React;

const money = (n) => "$" + n.toLocaleString();

function fmtCell(strong) { return <span style={{ fontWeight: 600, color: "var(--fg-1)" }}>{strong}</span>; }

/* Avatar-ish client cell */
function ClientCell({ name, sub, color }) {
  const initials = name.split(" ").map((p) => p[0]).slice(0, 2).join("").toUpperCase();
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 11 }}>
      <span style={{ width: 30, height: 30, borderRadius: 8, flexShrink: 0, display: "grid", placeItems: "center", background: color, color: "#fff", fontSize: 11.5, fontWeight: 600, fontFamily: "var(--font-mono)" }}>{initials}</span>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontWeight: 600, color: "var(--fg-1)", fontSize: 13.5, whiteSpace: "nowrap" }}>{name}</div>
        {sub && <div style={{ fontSize: 12, color: "var(--fg-3)", whiteSpace: "nowrap" }}>{sub}</div>}
      </div>
    </div>
  );
}

function HealthBar({ value }) {
  const tone = value >= 80 ? "green" : value >= 60 ? "amber" : "red";
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 9, minWidth: 120 }}>
      <div style={{ flex: 1 }}><Progress value={value} tone={tone} /></div>
      <span style={{ fontSize: 12, fontWeight: 600, color: "var(--fg-1)", fontVariantNumeric: "tabular-nums", width: 28, textAlign: "right" }}>{value}</span>
    </div>
  );
}

function rowActions(onView, label) {
  return (
    <DropdownMenu align="right" width={188}
      trigger={(open) => (
        <span style={{ width: 28, height: 28, display: "grid", placeItems: "center", borderRadius: 7, cursor: "pointer", color: "var(--fg-3)", background: open ? "var(--ink-800)" : "transparent" }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="5" r="1.6" /><circle cx="12" cy="12" r="1.6" /><circle cx="12" cy="19" r="1.6" /></svg>
        </span>
      )}
      items={[
        { label: "Open portal", icon: "external", onClick: () => window.pdToast({ tone: "info", title: "Opening portal…", body: `${label} portal opened in a new tab.` }) },
        { label: "View details", icon: "grid", onClick: onView },
        { label: "Edit", icon: "palette", onClick: () => window.pdToast("Edit mode coming soon") },
        { separator: true },
        { label: "Archive", icon: "history", tone: "danger", onClick: () => window.pdToast({ tone: "error", title: "Archived", body: `${label} moved to archive.` }) },
      ]}
    />
  );
}

/* ========================================================================== */
/* CLIENTS                                                                     */
/* ========================================================================== */
function ClientsView() {
  const [tab, setTab] = useStateT("all");
  const [q, setQ] = useStateT("");
  const [detail, setDetail] = useStateT(null);

  const counts = {
    all: PD_CLIENTS.length,
    live: PD_CLIENTS.filter((c) => c.portal === "live").length,
    draft: PD_CLIENTS.filter((c) => c.portal === "draft").length,
    paused: PD_CLIENTS.filter((c) => c.portal === "paused").length,
  };
  let rows = PD_CLIENTS;
  if (tab !== "all") rows = rows.filter((c) => c.portal === tab);
  if (q) rows = rows.filter((c) => (c.name + c.contact + c.email).toLowerCase().includes(q.toLowerCase()));

  const columns = [
    { key: "name", header: "Client", sortable: true, render: (r) => <ClientCell name={r.name} sub={r.contact} color={r.color} /> },
    { key: "portal", header: "Portal", sortable: true, render: (r) => <Pill tone={PD_PORTAL_STATUS[r.portal].tone} dot>{PD_PORTAL_STATUS[r.portal].label}</Pill> },
    { key: "plan", header: "Plan", sortable: true, render: (r) => <span style={{ fontSize: 13 }}>{r.plan}</span> },
    { key: "projects", header: "Projects", sortable: true, align: "right", render: (r) => fmtCell(r.projects) },
    { key: "mrr", header: "MRR", sortable: true, align: "right", render: (r) => <span style={{ fontVariantNumeric: "tabular-nums", color: r.mrr ? "var(--fg-1)" : "var(--fg-4)", fontWeight: 600 }}>{r.mrr ? money(r.mrr) : "—"}</span> },
    { key: "lastActiveTs", header: "Last active", sortable: true, render: (r) => <span style={{ fontSize: 12.5, color: "var(--fg-3)" }}>{r.lastActive}</span> },
    { key: "health", header: "Health", sortable: true, width: 170, render: (r) => <HealthBar value={r.health} /> },
    { key: "_act", header: "", align: "right", width: 52, render: (r) => rowActions(() => setDetail(r), r.name) },
  ];

  return (
    <div>
      <PageHeader title="Clients" subtitle={`${PD_CLIENTS.length} client accounts · ${counts.live} live portals`}
        actions={<React.Fragment>
          <Button variant="secondary" size="md" icon="upload">Export</Button>
          <Button variant="primary" size="md" icon="plus" onClick={() => window.pdToast({ tone: "success", title: "Invite sent", body: "We emailed an invite to set up a new client portal." })}>Invite client</Button>
        </React.Fragment>} />

      <Surface pad={0}>
        <div className="pd-table-toolbar" style={{ display: "flex", alignItems: "center", gap: 14, padding: "12px 16px", borderBottom: "1px solid var(--line-2)", flexWrap: "wrap" }}>
          <Tabs style={{ border: 0, flex: "0 0 auto" }} value={tab} onChange={setTab}
            tabs={[{ id: "all", label: "All", count: counts.all }, { id: "live", label: "Live", count: counts.live }, { id: "draft", label: "Draft", count: counts.draft }, { id: "paused", label: "Paused", count: counts.paused }]} />
          <div className="pd-toolbar-search" style={{ marginLeft: "auto", display: "flex", alignItems: "center", gap: 10 }}>
            <SearchInput value={q} onChange={setQ} placeholder="Search clients…" width={220} />
            <Button variant="secondary" size="md" icon="checklist">Filters</Button>
          </div>
        </div>
        <DataTable columns={columns} rows={rows} selectable onRowClick={(r) => setDetail(r)} initialSort={{ key: "name", dir: "asc" }} />
      </Surface>

      <ClientSheet client={detail} onClose={() => setDetail(null)} />
    </div>
  );
}

function ClientSheet({ client, onClose }) {
  if (!client) return null;
  const projects = PD_PROJECTS.filter((p) => p.clientId === client.id);
  const invoices = PD_INVOICES.filter((i) => i.clientId === client.id);
  return (
    <Sheet open={!!client} onClose={onClose} eyebrow="CLIENT" title={client.name}
      footer={<React.Fragment>
        <Button variant="secondary" size="md" onClick={onClose}>Close</Button>
        <Button variant="primary" size="md" icon="external" onClick={() => window.pdToast({ tone: "info", title: "Opening portal…" })}>Open portal</Button>
      </React.Fragment>}>
      <div style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: 22 }}>
        <span style={{ width: 48, height: 48, borderRadius: 12, display: "grid", placeItems: "center", background: client.color, color: "#fff", fontSize: 17, fontWeight: 600, fontFamily: "var(--font-mono)" }}>{client.name.split(" ").map((p) => p[0]).slice(0, 2).join("")}</span>
        <div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <Pill tone={PD_PORTAL_STATUS[client.portal].tone} dot>{PD_PORTAL_STATUS[client.portal].label}</Pill>
            <Pill tone="accent">{client.plan}</Pill>
          </div>
          <div style={{ fontSize: 13, color: "var(--fg-3)", marginTop: 6 }}>{client.contact} · {client.email}</div>
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "repeat(3, minmax(0, 1fr))", gap: 10, marginBottom: 24 }}>
        {[["MRR", client.mrr ? money(client.mrr) : "—"], ["Projects", client.projects], ["Health", client.health]].map(([k, v]) => (
          <div key={k} style={{ padding: 12, borderRadius: 10, background: "var(--ink-950)", border: "1px solid var(--line-2)" }}>
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--fg-3)" }}>{k}</div>
            <div style={{ fontSize: 20, fontWeight: 600, color: "var(--fg-1)", marginTop: 4, letterSpacing: "-0.02em" }}>{v}</div>
          </div>
        ))}
      </div>

      <div style={{ marginBottom: 8 }}><MonoLabel>Workspace</MonoLabel></div>
      <div style={{ display: "flex", alignItems: "center", gap: 10, padding: 12, borderRadius: 10, background: "var(--ink-950)", border: "1px solid var(--line-2)", marginBottom: 24 }}>
        <span style={{ display: "inline-flex", padding: 6, borderRadius: 8, background: "var(--accent)", color: "var(--fg-inverse)" }}><Ic name="database" size={16} /></span>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 13.5, fontWeight: 600, color: "var(--fg-1)" }}>{client.base}</div>
          <div style={{ fontSize: 12, color: "var(--fg-3)" }}>Updated 4 min ago</div>
        </div>
        <StatusDot status="healthy" />
      </div>

      <div style={{ marginBottom: 10 }}><MonoLabel>Projects ({projects.length})</MonoLabel></div>
      <div style={{ display: "flex", flexDirection: "column", gap: 8, marginBottom: 24 }}>
        {projects.length === 0 && <div style={{ fontSize: 13, color: "var(--fg-3)" }}>No active projects.</div>}
        {projects.map((p) => (
          <div key={p.id} style={{ display: "flex", alignItems: "center", gap: 12, padding: "10px 12px", borderRadius: 10, border: "1px solid var(--line-2)" }}>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13, fontWeight: 600, color: "var(--fg-1)" }}>{p.name}</div>
              <div style={{ fontSize: 11.5, color: "var(--fg-3)", marginTop: 2 }}>Due {p.due} · {p.tasks} tasks</div>
            </div>
            <Pill tone={PD_PROJECT_STATUS[p.status].tone}>{PD_PROJECT_STATUS[p.status].label}</Pill>
          </div>
        ))}
      </div>

      <div style={{ marginBottom: 10 }}><MonoLabel>Recent invoices</MonoLabel></div>
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        {invoices.slice(0, 3).map((inv) => (
          <div key={inv.id} style={{ display: "flex", alignItems: "center", gap: 12, padding: "9px 12px", borderRadius: 10, border: "1px solid var(--line-2)" }}>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--fg-2)" }}>{inv.id}</span>
            <span style={{ marginLeft: "auto", fontSize: 13, fontWeight: 600, color: "var(--fg-1)" }}>{money(inv.amount)}</span>
            <Pill tone={PD_INVOICE_STATUS[inv.status].tone}>{PD_INVOICE_STATUS[inv.status].label}</Pill>
          </div>
        ))}
      </div>
    </Sheet>
  );
}

/* ========================================================================== */
/* PROJECTS                                                                    */
/* ========================================================================== */
function ProjectsView() {
  const [tab, setTab] = useStateT("all");
  const [q, setQ] = useStateT("");
  const counts = { all: PD_PROJECTS.length };
  Object.keys(PD_PROJECT_STATUS).forEach((k) => { counts[k] = PD_PROJECTS.filter((p) => p.status === k).length; });
  let rows = PD_PROJECTS;
  if (tab !== "all") rows = rows.filter((p) => p.status === tab);
  if (q) rows = rows.filter((p) => (p.name + p.client).toLowerCase().includes(q.toLowerCase()));

  const columns = [
    { key: "name", header: "Project", sortable: true, render: (r) => (
      <div><div style={{ fontWeight: 600, color: "var(--fg-1)", fontSize: 13.5, whiteSpace: "nowrap" }}>{r.name}</div><div style={{ fontSize: 12, color: "var(--fg-3)", marginTop: 1, whiteSpace: "nowrap" }}>{r.client}</div></div>
    ) },
    { key: "status", header: "Status", sortable: true, render: (r) => <Pill tone={PD_PROJECT_STATUS[r.status].tone} dot>{PD_PROJECT_STATUS[r.status].label}</Pill> },
    { key: "progress", header: "Progress", sortable: true, width: 150, render: (r) => <HealthBar value={r.progress} /> },
    { key: "tasks", header: "Tasks", align: "right", render: (r) => <span style={{ fontFamily: "var(--font-mono)", fontSize: 12.5, color: "var(--fg-2)", whiteSpace: "nowrap" }}>{r.tasks}</span> },
    { key: "owner", header: "Owner", sortable: true, render: (r) => <div style={{ display: "flex", alignItems: "center", gap: 8 }}><Avatar name={r.owner} size={24} /><span style={{ fontSize: 13, whiteSpace: "nowrap" }}>{r.owner}</span></div> },
    { key: "due", header: "Due", sortable: true, render: (r) => <span style={{ fontSize: 13, color: "var(--fg-2)", whiteSpace: "nowrap" }}>{r.due}</span> },
    { key: "_act", header: "", align: "right", width: 52, render: (r) => rowActions(() => window.pdToast(r.name), r.name) },
  ];

  return (
    <div>
      <PageHeader title="Projects" subtitle={`${counts.in_progress} in progress · ${counts.review} in review · ${counts.blocked} blocked`}
        actions={<Button variant="primary" size="md" icon="plus" onClick={() => window.pdNewProject && window.pdNewProject()}>New project</Button>} />
      <Surface pad={0}>
        <div className="pd-table-toolbar" style={{ display: "flex", alignItems: "center", gap: 14, padding: "12px 16px", borderBottom: "1px solid var(--line-2)", flexWrap: "wrap" }}>
          <Tabs style={{ border: 0 }} value={tab} onChange={setTab}
            tabs={[{ id: "all", label: "All", count: counts.all }, { id: "in_progress", label: "In progress", count: counts.in_progress }, { id: "review", label: "In review", count: counts.review }, { id: "blocked", label: "Blocked", count: counts.blocked }, { id: "done", label: "Done", count: counts.done }]} />
          <div className="pd-toolbar-search" style={{ marginLeft: "auto" }}><SearchInput value={q} onChange={setQ} placeholder="Search projects…" width={220} /></div>
        </div>
        <DataTable columns={columns} rows={rows} initialSort={{ key: "due", dir: "asc" }} onRowClick={(r) => window.pdToast({ tone: "info", title: r.name, body: `${r.client} · ${PD_PROJECT_STATUS[r.status].label}` })} />
      </Surface>
    </div>
  );
}

/* ========================================================================== */
/* APPROVALS                                                                   */
/* ========================================================================== */
function ApprovalsView() {
  const [tab, setTab] = useStateT("pending");
  const [items, setItems] = useStateT(PD_APPROVALS);
  const counts = {
    pending: items.filter((a) => a.status === "pending").length,
    approved: items.filter((a) => a.status === "approved").length,
    changes: items.filter((a) => a.status === "changes").length,
  };
  const rows = items.filter((a) => a.status === tab);

  function act(id, status, label) {
    setItems((prev) => prev.map((a) => a.id === id ? { ...a, status } : a));
    window.pdToast(label);
  }

  return (
    <div>
      <PageHeader title="Approvals" subtitle={`${counts.pending} awaiting your review across ${new Set(items.filter(a=>a.status==='pending').map(a=>a.client)).size} clients`} />
      <Tabs style={{ marginBottom: 18 }} value={tab} onChange={setTab}
        tabs={[{ id: "pending", label: "Pending", count: counts.pending }, { id: "approved", label: "Approved", count: counts.approved }, { id: "changes", label: "Changes requested", count: counts.changes }]} />
      <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
        {rows.length === 0 && <Surface pad={40} style={{ textAlign: "center", color: "var(--fg-3)", fontSize: 14 }}>Nothing here. You're all caught up.</Surface>}
        {rows.map((a) => {
          const client = PD_CLIENTS.find((c) => c.id === a.clientId);
          return (
            <Surface key={a.id} hover pad={16} className="pd-approval-row" style={{ display: "flex", alignItems: "center", gap: 16, flexWrap: "wrap" }}>
              <span style={{ width: 42, height: 42, borderRadius: 10, display: "grid", placeItems: "center", background: "var(--ink-800)", color: "var(--fg-2)", flexShrink: 0 }}><Ic name={{ Copy: "file", Design: "palette", Asset: "upload", Plan: "checklist" }[a.type] || "file"} size={19} /></span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 14.5, fontWeight: 600, color: "var(--fg-1)" }}>{a.title}</div>
                <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 5, fontSize: 12.5, color: "var(--fg-3)" }}>
                  <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>{client && <span style={{ width: 16, height: 16, borderRadius: 5, background: client.color, color: "#fff", fontSize: 8, fontWeight: 700, display: "grid", placeItems: "center", fontFamily: "var(--font-mono)" }}>{a.client.split(" ").map(p=>p[0]).slice(0,2).join("")}</span>}{a.client}</span>
                  <span>·</span><span>{a.type}</span><span>·</span><span>Submitted {a.submitted} by {a.by}</span>
                </div>
              </div>
              {a.status === "pending" ? (
                <div className="pd-approval-actions" style={{ display: "flex", gap: 8, flexShrink: 0 }}>
                  <Button variant="secondary" size="md" onClick={() => act(a.id, "changes", { tone: "info", title: "Changes requested", body: a.title })}>Request changes</Button>
                  <Button variant="primary" size="md" icon="check" onClick={() => act(a.id, "approved", { tone: "success", title: "Approved", body: a.title })}>Approve</Button>
                </div>
              ) : (
                <Pill tone={a.status === "approved" ? "green" : "amber"} dot>{a.status === "approved" ? "Approved" : "Changes requested"}</Pill>
              )}
            </Surface>
          );
        })}
      </div>
    </div>
  );
}

/* ========================================================================== */
/* INVOICES                                                                    */
/* ========================================================================== */
function InvoicesView() {
  const [tab, setTab] = useStateT("all");
  const [q, setQ] = useStateT("");
  const counts = { all: PD_INVOICES.length };
  Object.keys(PD_INVOICE_STATUS).forEach((k) => { counts[k] = PD_INVOICES.filter((i) => i.status === k).length; });
  let rows = PD_INVOICES;
  if (tab !== "all") rows = rows.filter((i) => i.status === tab);
  if (q) rows = rows.filter((i) => (i.id + i.client).toLowerCase().includes(q.toLowerCase()));

  const paid = PD_INVOICES.filter((i) => i.status === "paid").reduce((s, i) => s + i.amount, 0);
  const outstanding = PD_INVOICES.filter((i) => i.status === "due" || i.status === "overdue").reduce((s, i) => s + i.amount, 0);
  const overdue = PD_INVOICES.filter((i) => i.status === "overdue").reduce((s, i) => s + i.amount, 0);

  const columns = [
    { key: "id", header: "Invoice", sortable: true, render: (r) => <span style={{ fontFamily: "var(--font-mono)", fontSize: 13, fontWeight: 600, color: "var(--fg-1)" }}>{r.id}</span> },
    { key: "client", header: "Client", sortable: true, render: (r) => { const c = PD_CLIENTS.find((x) => x.id === r.clientId); return <ClientCell name={r.client} color={c ? c.color : "#888"} />; } },
    { key: "issued", header: "Issued", sortable: true, render: (r) => <span style={{ fontSize: 13, color: "var(--fg-2)" }}>{r.issued}</span> },
    { key: "due", header: "Due", sortable: true, render: (r) => <span style={{ fontSize: 13, color: r.status === "overdue" ? "var(--red)" : "var(--fg-2)", fontWeight: r.status === "overdue" ? 600 : 400 }}>{r.due}</span> },
    { key: "amount", header: "Amount", sortable: true, align: "right", render: (r) => <span style={{ fontWeight: 600, color: "var(--fg-1)", fontVariantNumeric: "tabular-nums" }}>{money(r.amount)}</span> },
    { key: "status", header: "Status", sortable: true, render: (r) => <Pill tone={PD_INVOICE_STATUS[r.status].tone} dot>{PD_INVOICE_STATUS[r.status].label}</Pill> },
    { key: "_act", header: "", align: "right", width: 52, render: (r) => (
      <DropdownMenu align="right" width={180} trigger={(open) => <span style={{ width: 28, height: 28, display: "grid", placeItems: "center", borderRadius: 7, cursor: "pointer", color: "var(--fg-3)", background: open ? "var(--ink-800)" : "transparent" }}><svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="5" r="1.6" /><circle cx="12" cy="12" r="1.6" /><circle cx="12" cy="19" r="1.6" /></svg></span>}
        items={[{ label: "View invoice", icon: "file", onClick: () => window.pdToast(r.id) }, { label: "Download PDF", icon: "arrowDown", onClick: () => window.pdToast({ tone: "success", title: "Downloaded", body: r.id + ".pdf" }) }, { label: "Send reminder", icon: "message", onClick: () => window.pdToast({ tone: "success", title: "Reminder sent", body: r.client }) }] } />
    ) },
  ];

  return (
    <div>
      <PageHeader title="Invoices" subtitle="Billing across all client portals"
        actions={<Button variant="primary" size="md" icon="plus" onClick={() => window.pdToast({ tone: "success", title: "Draft created", body: "New invoice draft ready to edit." })}>New invoice</Button>} />
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16, marginBottom: 16 }} className="pd-kpi-grid">
        <StatCard label="Paid this month" value={money(paid)} delta="on time" deltaUp footnote="" icon="check" />
        <StatCard label="Outstanding" value={money(outstanding)} delta={`${counts.due + counts.overdue} open`} deltaUp={false} footnote="" icon="clock" />
        <StatCard label="Overdue" value={money(overdue)} delta="1 invoice" deltaUp={false} footnote="" icon="card" />
      </div>
      <Surface pad={0}>
        <div className="pd-table-toolbar" style={{ display: "flex", alignItems: "center", gap: 14, padding: "12px 16px", borderBottom: "1px solid var(--line-2)", flexWrap: "wrap" }}>
          <Tabs style={{ border: 0 }} value={tab} onChange={setTab}
            tabs={[{ id: "all", label: "All", count: counts.all }, { id: "due", label: "Due", count: counts.due }, { id: "overdue", label: "Overdue", count: counts.overdue }, { id: "paid", label: "Paid", count: counts.paid }, { id: "draft", label: "Draft", count: counts.draft }]} />
          <div className="pd-toolbar-search" style={{ marginLeft: "auto" }}><SearchInput value={q} onChange={setQ} placeholder="Search invoices…" width={220} /></div>
        </div>
        <DataTable columns={columns} rows={rows} initialSort={{ key: "id", dir: "desc" }} />
      </Surface>
    </div>
  );
}

Object.assign(window, { ClientsView, ProjectsView, ApprovalsView, InvoicesView });
