import { View, Text } from '@react-pdf/renderer';

import { formatCurrency } from '@/lib/utils/currency';
import { BrandedReportDocument } from './branded-document';
import { ReportTable } from './report-table';
import { makeReportStyles } from './styles';
import type { BerthListReportConfig, ReportBranding } from './types';
import type { BerthReportData } from '@/lib/services/list-report-data.service';

interface Props {
  title: string;
  subtitle?: string;
  branding: ReportBranding;
  generatedAt: string;
  config: BerthListReportConfig;
  data: BerthReportData;
}

const DEFAULT_COLUMNS: ReadonlyArray<{ key: string; label: string; widthPct: number }> = [
  { key: 'mooringNumber', label: 'Mooring', widthPct: 12 },
  { key: 'area', label: 'Area', widthPct: 8 },
  { key: 'status', label: 'Status', widthPct: 12 },
  { key: 'tenureType', label: 'Tenure', widthPct: 13 },
  { key: 'lengthFt', label: 'Length (ft)', widthPct: 12 },
  { key: 'widthFt', label: 'Width (ft)', widthPct: 11 },
  { key: 'draftFt', label: 'Draft (ft)', widthPct: 11 },
  { key: 'price', label: 'Price', widthPct: 21 },
];

export function BerthListReport({ title, subtitle, branding, generatedAt, config, data }: Props) {
  const styles = makeReportStyles(branding);
  const columns = pickColumns(config.columns);
  const cappedNotice = data.capHit
    ? `Showing the first ${data.rows.length} of ${data.total.toLocaleString()} matching berths.`
    : `${data.rows.length} ${data.rows.length === 1 ? 'berth' : 'berths'}`;

  return (
    <BrandedReportDocument
      branding={branding}
      title={title}
      subtitle={subtitle ?? 'Berth inventory'}
      generatedAt={generatedAt}
    >
      <View>
        <Text style={styles.sectionSubtitle} minPresenceAhead={80}>
          {cappedNotice}
        </Text>
        <ReportTable
          styles={styles}
          headers={columns.map((c) => c.label)}
          widths={columns.map((c) => c.widthPct)}
          rows={data.rows.map((r) => columns.map((c) => formatCell(c.key, r)))}
        />
      </View>
    </BrandedReportDocument>
  );
}

function pickColumns(override?: string[]) {
  if (!override || override.length === 0) return [...DEFAULT_COLUMNS];
  const map = new Map(DEFAULT_COLUMNS.map((c) => [c.key, c]));
  return override.flatMap((k) => (map.has(k) ? [map.get(k)!] : []));
}

function formatCell(key: string, row: BerthReportData['rows'][number]): string {
  switch (key) {
    case 'mooringNumber':
      return row.mooringNumber;
    case 'area':
      return row.area ?? '';
    case 'status':
      return formatStatus(row.status);
    case 'tenureType':
      return row.tenureType === 'permanent'
        ? 'Permanent'
        : row.tenureType === 'fixed_term'
          ? 'Fixed-term'
          : row.tenureType;
    case 'lengthFt':
      return row.lengthFt ? Number(row.lengthFt).toFixed(1) : '';
    case 'widthFt':
      return row.widthFt ? Number(row.widthFt).toFixed(1) : '';
    case 'draftFt':
      return row.draftFt ? Number(row.draftFt).toFixed(1) : '';
    case 'price':
      return row.price
        ? formatCurrency(row.price, row.priceCurrency, { maxFractionDigits: 0 })
        : '';
    default:
      return '';
  }
}

function formatStatus(s: string): string {
  return s.replace(/_/g, ' ').replace(/\b\w/g, (m) => m.toUpperCase());
}
