import {
  BarChart,
  DataTable,
  DocumentShell,
  KeyValueGrid,
  Section,
  type BarDatum,
} from '@/lib/pdf/brand-kit';
import type { ActivityData } from '@/lib/services/report-generators';

export interface ActivityReportPdfProps {
  portName: string;
  logoBuffer: Buffer | null;
  data: ActivityData;
  /** Optional ISO range for the meta line. Falls back to data.generatedAt. */
  dateFrom?: string;
  dateTo?: string;
}

interface RowShape {
  id: string;
  action: string;
  entityType: string;
  entityId: string | null;
  userId: string | null;
  createdAt: Date;
}

function bucketByDay(logs: RowShape[]): BarDatum[] {
  const buckets = new Map<string, number>();
  for (const log of logs) {
    const day = new Date(log.createdAt).toISOString().slice(0, 10);
    buckets.set(day, (buckets.get(day) ?? 0) + 1);
  }
  return [...buckets.entries()]
    .sort(([a], [b]) => a.localeCompare(b))
    .slice(-14)
    .map(([day, value]) => ({
      label: day.slice(5),
      value,
    }));
}

function topEntries(
  record: Record<string, number>,
  n: number,
): Array<{ key: string; value: number }> {
  return Object.entries(record)
    .sort((a, b) => b[1] - a[1])
    .slice(0, n)
    .map(([key, value]) => ({ key, value }));
}

function busiestDay(logs: RowShape[]): string {
  const buckets = new Map<string, number>();
  for (const log of logs) {
    const day = new Date(log.createdAt).toISOString().slice(0, 10);
    buckets.set(day, (buckets.get(day) ?? 0) + 1);
  }
  let best = '';
  let bestCount = 0;
  for (const [day, count] of buckets) {
    if (count > bestCount) {
      best = day;
      bestCount = count;
    }
  }
  return best ? `${best} (${bestCount})` : '-';
}

export function ActivityReportPdf({
  portName,
  logoBuffer,
  data,
  dateFrom,
  dateTo,
}: ActivityReportPdfProps) {
  const topActions = topEntries(data.summary, 5);
  const topAction = topActions[0]?.key ?? '-';
  const meta =
    dateFrom || dateTo
      ? `Range: ${dateFrom ?? '-'} → ${dateTo ?? 'today'} · ${data.logs.length} events`
      : `Last 30 days · ${data.logs.length} events`;

  const chartData = bucketByDay(data.logs);
  const tableRows = data.logs.slice(0, 50);

  return (
    <DocumentShell
      portName={portName}
      docTitle="Activity Report"
      docMeta={meta}
      logoBuffer={logoBuffer}
    >
      <Section title="Summary">
        <KeyValueGrid
          rows={[
            { label: 'Total events', value: data.logs.length.toLocaleString() },
            { label: 'Top action', value: topAction },
            { label: 'Top users', value: 'see breakdown below' },
            { label: 'Busiest day', value: busiestDay(data.logs) },
          ]}
        />
      </Section>

      <Section title="Top actions" subtitle="Top 5 audit-log action types by count.">
        <DataTable<{ key: string; value: number }>
          columns={[
            { header: 'Action', flex: 3, render: (r) => r.key },
            { header: 'Count', flex: 1, align: 'right', render: (r) => r.value.toLocaleString() },
          ]}
          rows={topActions}
        />
      </Section>

      <Section title="Daily volume" subtitle="Events per day (most recent 14 days).">
        <BarChart data={chartData} height={180} />
      </Section>

      <Section title="Recent events" subtitle="Most recent 50 audit-log entries.">
        <DataTable<RowShape>
          columns={[
            {
              header: 'When',
              flex: 1.5,
              render: (r) => new Date(r.createdAt).toISOString().replace('T', ' ').slice(0, 16),
            },
            { header: 'Action', flex: 1.5, render: (r) => r.action },
            { header: 'Entity', flex: 1.5, render: (r) => r.entityType },
            { header: 'User', flex: 1.5, render: (r) => r.userId ?? '-' },
          ]}
          rows={tableRows}
          emptyMessage="No activity in the selected period."
        />
      </Section>
    </DocumentShell>
  );
}
