import { api, isAdmin, me } from '@/lib/api';
import { n } from '@/lib/format';
import { BarChart } from '@/components/BarChart';
import { Card, Forbidden, Kpi, PageHeader, Tabs, type SP } from '@/components/ui';
import { ChartIcon, GlobeIcon, InboxIcon, MapPinIcon, UserIcon } from '@/components/Icons';

type A = {
  days: number;
  funnel: { step: string; count: number; rate: number | null }[];
  spam: number;
  accounts: { newClientAccounts: number; enquiriesFromAccounts: number };
  daily: { day: string; searches: number; views: number; leads: number }[];
  byCity: { name: string; leads: number; accepted: number; acceptance: number | null }[];
  byPracticeArea: { name: string; leads: number; accepted: number; acceptance: number | null }[];
  sources: { source: string; views: number }[];
  note: string;
};

function Breakdown({ title, rows, icon }: { title: string; rows: A['byCity']; icon: React.ReactNode }) {
  return (
    <Card title={title} icon={icon}>
      <table className="tbl">
        <thead>
          <tr>
            <th />
            <th className="text-right">Enquiries</th>
            <th className="text-right">Accepted</th>
            <th className="text-right">Rate</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r) => (
            <tr key={r.name}>
              <td>{r.name}</td>
              <td className="num text-right">{n(r.leads)}</td>
              <td className="num text-right">{n(r.accepted)}</td>
              <td className={`num text-right ${r.acceptance != null && r.acceptance < 30 ? 'text-danger' : ''}`}>{r.acceptance != null ? `${r.acceptance}%` : '—'}</td>
            </tr>
          ))}
          {!rows.length && (
            <tr>
              <td colSpan={4} className="py-6 text-center text-muted">
                No enquiries in this period.
              </td>
            </tr>
          )}
        </tbody>
      </table>
    </Card>
  );
}

export default async function Analytics({ searchParams }: { searchParams: SP }) {
  const sp = await searchParams;
  const viewer = await me();
  if (!isAdmin(viewer.role)) return <Forbidden what="analytics" />;
  const days = ['7', '30', '90'].includes(sp.days ?? '') ? sp.days! : '30';
  const d = await api<A>(`/admin/analytics?days=${days}`);
  const top = Math.max(1, ...d.funnel.map((f) => f.count));
  return (
    <>
      <PageHeader
        title="Analytics"
        icon={<ChartIcon className="h-5 w-5" />}
        description={`Where visitors go from search to an accepted enquiry, and where they drop out. ${d.note}`}
        actions={<Tabs current={days} items={['7', '30', '90'].map((v) => ({ value: v, label: `${v} days`, href: `?days=${v}` }))} />}
      />
      <div className="mb-6 grid grid-cols-2 gap-3 md:grid-cols-4">
        <Kpi label="Enquiries sent" icon={<InboxIcon className="h-4 w-4" />} value={n(d.funnel[3]?.count)} hint={`${n(d.spam)} spam filtered`} />
        <Kpi label="Accepted" icon={<InboxIcon className="h-4 w-4" />} value={n(d.funnel[6]?.count)} hint={d.funnel[6]?.rate != null ? `${d.funnel[6].rate}% of delivered` : '—'} />
        <Kpi label="New client accounts" icon={<UserIcon className="h-4 w-4" />} value={n(d.accounts.newClientAccounts)} />
        <Kpi label="Enquiries from accounts" icon={<UserIcon className="h-4 w-4" />} value={n(d.accounts.enquiriesFromAccounts)} />
      </div>
      <Card title="Funnel" icon={<ChartIcon className="h-4 w-4" />} className="mb-6">
        <ol className="space-y-3 p-5 text-sm">
          {d.funnel.map((f) => (
            <li key={f.step} className="grid grid-cols-[11rem_1fr_6rem] items-center gap-3">
              <span className="font-medium">{f.step}</span>
              <span className="h-3 overflow-hidden rounded-full bg-sunken">
                <span className="block h-full rounded-full bg-ledger" style={{ width: `${Math.max(1, (f.count / top) * 100)}%` }} />
              </span>
              <span className="num text-right">
                {n(f.count)} {f.rate != null && <span className="text-xs text-muted">({f.rate}%)</span>}
              </span>
            </li>
          ))}
        </ol>
        <p className="border-t border-rule px-5 py-2.5 text-xs text-muted">Percentages are relative to the step before. Each step counts distinct enquiries; views and searches count events.</p>
      </Card>
      <div className="mb-6 grid gap-6 xl:grid-cols-3">
        <Card title="Searches per day">
          <div className="p-4">
            <BarChart data={d.daily.map((x) => ({ x: x.day.slice(5), y: x.searches }))} label="Searches" />
          </div>
        </Card>
        <Card title="Profile views per day">
          <div className="p-4">
            <BarChart data={d.daily.map((x) => ({ x: x.day.slice(5), y: x.views }))} label="Profile views" />
          </div>
        </Card>
        <Card title="Enquiries per day">
          <div className="p-4">
            <BarChart data={d.daily.map((x) => ({ x: x.day.slice(5), y: x.leads }))} label="Enquiries" />
          </div>
        </Card>
      </div>
      <div className="grid gap-6 xl:grid-cols-3">
        <Breakdown title="By city" rows={d.byCity} icon={<MapPinIcon className="h-4 w-4" />} />
        <Breakdown title="By practice area" rows={d.byPracticeArea} icon={<ChartIcon className="h-4 w-4" />} />
        <Card title="Where visitors came from" icon={<GlobeIcon className="h-4 w-4" />}>
          <ul className="divide-y divide-rule text-sm">
            {d.sources.map((s) => (
              <li key={s.source} className="flex justify-between px-4 py-2.5">
                <span className="truncate">{s.source}</span>
                <span className="num">{n(s.views)}</span>
              </li>
            ))}
            {!d.sources.length && <li className="p-4 text-muted">No visits recorded.</li>}
          </ul>
        </Card>
      </div>
    </>
  );
}
