/**
 * Server-side data resolver for the dashboard PDF report.
 *
 * Each section is gated on its widget id being present in
 * `config.widgetIds`, so a report that only includes the pipeline
 * funnel runs ONE query instead of the full dashboard panel. Keeps
 * cold-call latency low even when the actual port has hundreds of
 * berths.
 *
 * Lives in its own file (not inside dashboard.service.ts) so the
 * report-builder concerns — what widget ids map to what fetcher,
 * which fields the PDF shape requires — stay scoped to the
 * report-side surface, not the dashboard UI.
 */
import {
  getKpis,
  getPipelineCounts,
  getBerthStatusDistribution,
  getHotDeals,
  getSourceConversion,
} from './dashboard.service';
import type { DashboardReportData } from '@/lib/pdf/reports/dashboard-report';

/**
 * Maps widget ids the dashboard PDF understands. The id space is
 * intentionally a subset of the on-screen `DASHBOARD_WIDGETS`
 * registry — only widgets that have a sensible printable form
 * appear here. The dialog's widget picker filters its option list
 * by this set.
 */
export const PDF_DASHBOARD_WIDGET_IDS = [
  'kpi_overview',
  'pipeline_funnel',
  'berth_status',
  'source_conversion',
  'hot_deals',
] as const;

export type PdfDashboardWidgetId = (typeof PDF_DASHBOARD_WIDGET_IDS)[number];

export interface PdfDashboardWidgetOption {
  id: PdfDashboardWidgetId;
  label: string;
  description: string;
}

/**
 * Public widget list (label + description) for the export dialog.
 * Mirrored from the on-screen widget-registry but with PDF-friendly
 * copy: a "Berth heat" chart is "Berth demand ranking" in print.
 */
export const PDF_DASHBOARD_WIDGETS: readonly PdfDashboardWidgetOption[] = [
  {
    id: 'kpi_overview',
    label: 'Key metrics',
    description: 'Total clients, active interests, pipeline value, occupancy %.',
  },
  {
    id: 'pipeline_funnel',
    label: 'Pipeline funnel',
    description: 'Active interests grouped by pipeline stage.',
  },
  {
    id: 'berth_status',
    label: 'Berth status distribution',
    description: 'Available / under offer / reserved / sold counts.',
  },
  {
    id: 'source_conversion',
    label: 'Source conversion',
    description: 'Inquiries → Clients → Interests → Won, by lead source.',
  },
  {
    id: 'hot_deals',
    label: 'Hot deals',
    description: 'Top 5 active interests by deal-health score.',
  },
];

export async function resolveDashboardReportData(
  portId: string,
  widgetIds: string[],
): Promise<DashboardReportData> {
  const want = new Set(widgetIds);
  // Each fetcher returns its own shape; default to undefined to
  // signal "don't render this section" downstream.
  const data: DashboardReportData = {};

  if (want.has('kpi_overview')) {
    data.kpis = await getKpis(portId);
  }
  if (want.has('pipeline_funnel')) {
    data.pipelineCounts = await getPipelineCounts(portId);
  }
  if (want.has('berth_status')) {
    const dist = await getBerthStatusDistribution(portId);
    // `dist` shape from the service is already the totals dict; pass
    // straight through. If the service changes shape, the type-check
    // here will trip.
    data.berthStatus = dist;
  }
  if (want.has('source_conversion')) {
    data.sourceConversion = await getSourceConversion(portId);
  }
  if (want.has('hot_deals')) {
    const deals = await getHotDeals(portId, 5);
    data.hotDeals = deals.map((d) => ({
      id: d.id,
      clientName: d.clientName,
      mooringNumber: d.mooringNumber,
      stage: d.stage,
      lastContact: d.lastContact,
    }));
  }
  return data;
}
