
import * as ActionIcons from '@/components/Icons';
import { api, isAdmin, me } from '@/lib/api';
import { date, money, n } from '@/lib/format';
import { Card, Empty, Flash, Forbidden, PageHeader, Pill, type SP } from '@/components/ui';
import { SubmitButton } from '@/components/Actions';
import { CalendarIcon, DollarIcon, HistoryIcon, MapPinIcon, PlusIcon, SparklesIcon, XIcon } from '@/components/Icons';
import { createSponsored, endSponsored, replayStripeEvent } from '../../actions';

type Subs = {
  subscriptions: { id: number; organization: string; plan: string; status: string; currentPeriodEnd: string | null; stripeSubscriptionId: string | null; createdAt: string }[];
  payments: { id: number; organization: string; amountCents: number; currency: string; status: string; paidAt: string | null }[];
  byPlan: { plan: string; active: number; mrr: number }[];
};
type Sp = { id: number; city: string; practice_area: string | null; advertiser: string; advertiser_type: string; starts_at: string; ends_at: string; live: boolean };

export default async function Commerce({ searchParams }: { searchParams: SP }) {
  const sp = await searchParams;
  const user = await me();
  if (!isAdmin(user.role)) return <Forbidden what="subscriptions and sponsored placements" />;
  const [s, placements, ref, events] = await Promise.all([
    api<Subs>('/admin/subscriptions'),
    api<Sp[]>('/admin/sponsored'),
    api<{ cities: { id: number; name: string }[]; practiceAreas: { id: number; name: string }[] }>('/admin/reference'),
    api<{ items: { id: string; type: string; status: string; error: string | null; receivedAt: string }[]; counts: Record<string, number> }>('/admin/stripe-events'),
  ]);
  const today = new Date().toISOString().slice(0, 10);
  const totalMrr = s.byPlan.reduce((t, p) => t + p.mrr, 0);
  return (
    <>
      <PageHeader
        title="Subscriptions & sponsored placements"
        icon={<DollarIcon className="h-5 w-5" />}
        description="Commercial data is stored separately from ranking inputs. Sponsored placements render in a labelled box and never alter organic positions."
      />
      <Flash ok={sp.ok} err={sp.err} />
      <div className="mb-6 grid grid-cols-2 gap-3 md:grid-cols-4 xl:grid-cols-5">
        <div className="card p-4">
          <p className="text-xs font-medium text-muted">Total MRR</p>
          <p className="num mt-1 font-serif text-[1.65rem] font-semibold leading-tight text-ledger">{money(totalMrr)}</p>
          <p className="mt-1 text-xs text-muted">across all paid plans</p>
        </div>
        {s.byPlan.map((p) => (
          <div key={p.plan} className="card p-4">
            <p className="text-xs font-medium capitalize text-muted">{p.plan.replace(/_/g, ' ')}</p>
            <p className="num mt-1 font-serif text-[1.65rem] font-semibold leading-tight">{money(p.mrr)}</p>
            <p className="mt-1 text-xs text-muted">{n(p.active)} active · monthly</p>
          </div>
        ))}
      </div>
      <Card title="Sponsored placements" icon={<SparklesIcon className="h-4 w-4" />}>
        {placements.length ? (
          <div className="overflow-x-auto">
            <table className="tbl">
              <thead>
                <tr>
                  <th>Advertiser</th>
                  <th>Where</th>
                  <th>Runs</th>
                  <th>State</th>
                  <th />
                </tr>
              </thead>
              <tbody>
                {placements.map((p) => (
                  <tr key={p.id}>
                    <td>
                      <span className="font-medium">{p.advertiser}</span> <span className="rounded bg-sunken px-1.5 py-0.5 text-[11px] text-muted">{p.advertiser_type}</span>
                    </td>
                    <td>
                      <span className="inline-flex items-center gap-1">
                        <MapPinIcon className="h-3.5 w-3.5 text-muted" />
                        {p.practice_area ?? 'All areas'} · {p.city}
                      </span>
                    </td>
                    <td className="whitespace-nowrap text-xs">
                      {date(p.starts_at)} → {date(p.ends_at)}
                    </td>
                    <td>
                      <Pill value={p.live ? 'live' : 'ended'} />
                    </td>
                    <td className="text-right">
                      {p.live && (
                        <form action={endSponsored}>
                          <input type="hidden" name="id" value={p.id} />
                          <SubmitButton className="btn btn-danger-quiet btn-xs" confirm={`End the placement for ${p.advertiser} now?`}>
                            <XIcon className="h-3.5 w-3.5" /> End now
                          </SubmitButton>
                        </form>
                      )}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        ) : (
          <Empty icon={<SparklesIcon className="h-6 w-6" />}>No sponsored placements yet.</Empty>
        )}
        <form action={createSponsored} className="border-t border-rule bg-paper/60 p-4">
          <p className="mb-3 flex items-center gap-2 text-sm font-semibold">
            <PlusIcon className="h-4 w-4 text-ledger" /> New placement
          </p>
          <div className="grid gap-3 sm:grid-cols-3 xl:grid-cols-6">
            <label className="block">
              <span className="field-label"><ActionIcons.UsersIcon />Lawyer id</span>
              <input name="lawyerId" type="number" min={1} inputMode="numeric" className="field" />
            </label>
            <label className="block">
              <span className="field-label">
                or firm id <span className="font-normal text-muted">(one of the two)</span>
              </span>
              <input name="firmId" type="number" min={1} inputMode="numeric" className="field" />
            </label>
            <label className="block">
              <span className="field-label"><ActionIcons.MapPinIcon />City</span>
              <select name="cityId" required className="field">
                {ref.cities.map((c) => (
                  <option key={c.id} value={c.id}>
                    {c.name}
                  </option>
                ))}
              </select>
            </label>
            <label className="block">
              <span className="field-label"><ActionIcons.ScaleIcon />Practice area</span>
              <select name="practiceAreaId" className="field">
                <option value="">All areas</option>
                {ref.practiceAreas.map((c) => (
                  <option key={c.id} value={c.id}>
                    {c.name}
                  </option>
                ))}
              </select>
            </label>
            <label className="block">
              <span className="field-label"><ActionIcons.CalendarIcon />Starts</span>
              <input name="startsAt" type="date" required defaultValue={today} className="field" />
            </label>
            <label className="block">
              <span className="field-label"><ActionIcons.CalendarIcon />Ends</span>
              <input name="endsAt" type="date" required min={today} className="field" />
            </label>
          </div>
          <div className="mt-3">
            <SubmitButton pendingLabel="Adding…">
              <PlusIcon className="h-4 w-4" /> Add placement
            </SubmitButton>
          </div>
        </form>
      </Card>
      <div className="mt-6 grid gap-6 xl:grid-cols-2">
        <Card title="Subscriptions" icon={<CalendarIcon className="h-4 w-4" />}>
          {s.subscriptions.length ? (
            <div className="max-h-[28rem] overflow-y-auto">
              <table className="tbl">
                <thead>
                  <tr>
                    <th>Organisation</th>
                    <th>Plan</th>
                    <th>Status</th>
                    <th>Renews</th>
                  </tr>
                </thead>
                <tbody>
                  {s.subscriptions.map((x) => (
                    <tr key={x.id}>
                      <td className="font-medium">{x.organization}</td>
                      <td className="capitalize">{x.plan.replace(/_/g, ' ')}</td>
                      <td>
                        <Pill value={x.status} />
                      </td>
                      <td className="whitespace-nowrap text-xs text-muted">{date(x.currentPeriodEnd)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          ) : (
            <Empty>No subscriptions yet.</Empty>
          )}
        </Card>
        <Card title="Recent payments" icon={<DollarIcon className="h-4 w-4" />}>
          {s.payments.length ? (
            <div className="max-h-[28rem] overflow-y-auto">
              <table className="tbl">
                <thead>
                  <tr>
                    <th>Organisation</th>
                    <th className="text-right">Amount</th>
                    <th>Status</th>
                    <th>Paid</th>
                  </tr>
                </thead>
                <tbody>
                  {s.payments.map((p) => (
                    <tr key={p.id}>
                      <td className="font-medium">{p.organization}</td>
                      <td className="num text-right font-semibold">{money(p.amountCents / 100)}</td>
                      <td>
                        <Pill value={p.status} />
                      </td>
                      <td className="whitespace-nowrap text-xs text-muted">{date(p.paidAt)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          ) : (
            <Empty>No payments yet.</Empty>
          )}
        </Card>
      </div>

      <Card
        title="Stripe webhook events"
        icon={<HistoryIcon className="h-4 w-4" />}
        className="mt-6"
        actions={
          <span className="flex gap-1 text-xs">
            {Object.entries(events.counts).map(([k, v]) => (
              <Pill key={k} value={`${k} ${v}`} tone={k === 'failed' ? 'bad' : k === 'processed' ? 'good' : 'muted'} />
            ))}
          </span>
        }
      >
        {events.items.length ? (
          <div className="overflow-x-auto">
            <table className="tbl">
              <thead>
                <tr>
                  <th>Received</th>
                  <th>Type</th>
                  <th>Event</th>
                  <th>Status</th>
                  <th />
                </tr>
              </thead>
              <tbody>
                {events.items.map((e) => (
                  <tr key={e.id}>
                    <td className="whitespace-nowrap text-xs text-muted">{date(e.receivedAt, true)}</td>
                    <td>
                      <code className="text-xs">{e.type}</code>
                    </td>
                    <td className="text-xs text-muted">{e.id}</td>
                    <td>
                      <Pill value={e.status} tone={e.status === 'failed' ? 'bad' : e.status === 'processed' ? 'good' : 'muted'} />
                      {e.error && <span className="block max-w-xs truncate text-[11px] text-danger" title={e.error}>{e.error}</span>}
                    </td>
                    <td>
                      {(e.status === 'failed' || e.status === 'received') && (
                        <form action={replayStripeEvent}>
                          <input type="hidden" name="id" value={e.id} />
                          <SubmitButton className="btn btn-quiet btn-xs"><ActionIcons.RefreshIcon />Re-apply</SubmitButton>
                        </form>
                      )}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        ) : (
          <Empty>No Stripe events received yet. Point a Stripe webhook at /api/v1/billing/webhook.</Empty>
        )}
        <p className="border-t border-rule px-4 py-2.5 text-xs text-muted">Each event is applied exactly once (by Stripe event id). Failed events return an error so Stripe retries; you can also re-apply them here.</p>
      </Card>
    </>
  );
}
