import { Document, Image, Page, StyleSheet, Text, View } from '@react-pdf/renderer';

import type { ReportPayload, ReportSection } from '@/lib/reports/types';
import type { ReportBranding } from './types';

/**
 * Generic payload-driven PDF document. Takes a `ReportPayload` from any
 * report (Sales / Operational / Custom / future) and renders it in a
 * branded shell — cover with port logo + title + period + generated-at
 * stamp, KPI grid below, then one section per ReportSection with a
 * tabular layout.
 *
 * This is the "v2" PDF surface; the legacy per-kind documents
 * (DashboardReport, ClientListReport, etc.) under this folder remain
 * for the original `/api/v1/reports/[id]` route and aren't touched.
 */

interface Props {
  payload: ReportPayload;
  branding: ReportBranding;
  generatedAt: string;
}

export function PayloadReportDocument({ payload, branding, generatedAt }: Props) {
  const styles = makeStyles(branding);
  return (
    <Document
      title={payload.title}
      author={branding.portName}
      subject={payload.description ?? `${branding.portName} report`}
      creator="Port Nimara CRM"
      producer="Port Nimara CRM"
    >
      <Page size="A4" style={styles.page} wrap>
        {/* Cover header — logo + title + period */}
        <View style={styles.coverHeader}>
          {branding.logoUrl ? (
            <Image src={branding.logoUrl} style={styles.logo} cache />
          ) : (
            <View style={{ width: 36, height: 36 }} />
          )}
          <View style={styles.coverHeaderText}>
            <Text style={styles.title}>{payload.title}</Text>
            {payload.description ? (
              <Text style={styles.subtitle}>{payload.description}</Text>
            ) : null}
            <Text style={styles.period}>
              {formatDate(payload.range.from)} – {formatDate(payload.range.to)}
            </Text>
          </View>
        </View>

        {/* KPI grid — three per row */}
        {payload.kpis.length > 0 ? (
          <View style={styles.kpiGrid}>
            {payload.kpis.map((kpi, i) => (
              <View key={i} style={styles.kpiTile}>
                <Text style={styles.kpiLabel}>{String(kpi.label).toUpperCase()}</Text>
                <Text style={styles.kpiValue}>{String(kpi.value)}</Text>
                {kpi.hint ? <Text style={styles.kpiHint}>{kpi.hint}</Text> : null}
              </View>
            ))}
          </View>
        ) : null}

        {/* Sections */}
        {payload.sections.map((section, i) => (
          <SectionBlock key={i} section={section} styles={styles} />
        ))}

        {/* Footer (fixed across pages) */}
        <View style={styles.footer} fixed>
          <Text style={styles.footerLeft}>{branding.portName}</Text>
          <Text style={styles.footerRight}>Generated {formatDateTime(generatedAt)}</Text>
          <Text
            style={styles.footerCenter}
            render={({ pageNumber, totalPages }) => `${pageNumber} / ${totalPages}`}
            fixed
          />
        </View>
      </Page>
    </Document>
  );
}

function SectionBlock({
  section,
  styles,
}: {
  section: ReportSection;
  styles: ReturnType<typeof makeStyles>;
}) {
  return (
    <View style={styles.section} wrap>
      <Text style={styles.sectionTitle}>{section.title}</Text>
      {section.rows.length === 0 ? (
        <Text style={styles.empty}>No data in this section.</Text>
      ) : (
        <View style={styles.table}>
          {/* Header */}
          <View style={[styles.tableRow, styles.tableHeader]}>
            {section.columns.map((col, i) => {
              const cellStyle =
                col.align === 'right'
                  ? [styles.tableCell, styles.tableHeaderCell, styles.tableCellRight]
                  : [styles.tableCell, styles.tableHeaderCell];
              return (
                <Text key={i} style={cellStyle}>
                  {col.label}
                </Text>
              );
            })}
          </View>
          {/* Body */}
          {section.rows.map((row, ri) => {
            const rowStyle =
              ri % 2 === 1 ? [styles.tableRow, styles.tableRowZebra] : styles.tableRow;
            return (
              <View key={ri} style={rowStyle}>
                {section.columns.map((col, ci) => {
                  const v = row[col.key];
                  const text = col.format ? col.format(v) : formatPlain(v);
                  const cellStyle =
                    col.align === 'right'
                      ? [styles.tableCell, styles.tableCellRight]
                      : styles.tableCell;
                  return (
                    <Text key={ci} style={cellStyle}>
                      {text}
                    </Text>
                  );
                })}
              </View>
            );
          })}
        </View>
      )}
    </View>
  );
}

function formatPlain(v: unknown): string {
  if (v === null || v === undefined) return '';
  if (v instanceof Date) return v.toISOString().slice(0, 10);
  return String(v);
}

function formatDate(d: Date): string {
  return d.toISOString().slice(0, 10);
}

function formatDateTime(iso: string): string {
  return iso.replace('T', ' ').slice(0, 16) + ' UTC';
}

function makeStyles(branding: ReportBranding) {
  return StyleSheet.create({
    page: {
      paddingTop: 40,
      paddingBottom: 56,
      paddingHorizontal: 36,
      fontSize: 9.5,
      fontFamily: 'Helvetica',
      color: '#1e2844',
      backgroundColor: '#ffffff',
    },
    coverHeader: {
      flexDirection: 'row',
      alignItems: 'flex-start',
      gap: 14,
      borderBottomWidth: 2,
      borderBottomColor: branding.primaryColor,
      paddingBottom: 14,
      marginBottom: 18,
    },
    logo: { width: 36, height: 36, objectFit: 'contain' },
    coverHeaderText: { flexDirection: 'column', flex: 1 },
    title: {
      fontSize: 18,
      fontFamily: 'Helvetica-Bold',
      color: branding.primaryColor,
      marginBottom: 3,
    },
    subtitle: { fontSize: 10, color: '#475569', marginBottom: 4 },
    period: { fontSize: 9, color: '#64748b', fontFamily: 'Helvetica' },
    kpiGrid: {
      flexDirection: 'row',
      flexWrap: 'wrap',
      gap: 8,
      marginBottom: 18,
    },
    kpiTile: {
      width: '32%',
      borderWidth: 0.5,
      borderColor: '#e2e8f0',
      borderRadius: 3,
      padding: 8,
      backgroundColor: '#f8fafc',
    },
    kpiLabel: {
      fontSize: 7,
      color: '#64748b',
      letterSpacing: 1,
      fontFamily: 'Helvetica-Bold',
      marginBottom: 3,
    },
    kpiValue: {
      fontSize: 14,
      fontFamily: 'Helvetica-Bold',
      color: '#0f172a',
      marginBottom: 2,
    },
    kpiHint: { fontSize: 7.5, color: '#94a3b8' },
    section: { marginBottom: 16 },
    sectionTitle: {
      fontSize: 11,
      fontFamily: 'Helvetica-Bold',
      color: branding.primaryColor,
      marginBottom: 6,
      paddingBottom: 3,
      borderBottomWidth: 0.5,
      borderBottomColor: '#cbd5e1',
    },
    empty: { fontSize: 9, color: '#94a3b8', fontStyle: 'italic', paddingVertical: 6 },
    table: { borderTopWidth: 0.5, borderTopColor: '#e2e8f0' },
    tableRow: {
      flexDirection: 'row',
      borderBottomWidth: 0.5,
      borderBottomColor: '#e2e8f0',
      paddingVertical: 4,
    },
    tableRowZebra: { backgroundColor: '#f8fafc' },
    tableHeader: { backgroundColor: branding.primaryColor },
    tableHeaderCell: { color: '#ffffff', fontFamily: 'Helvetica-Bold', fontSize: 8 },
    tableCell: {
      flex: 1,
      paddingHorizontal: 6,
      fontSize: 8.5,
      color: '#1e293b',
    },
    tableCellRight: { textAlign: 'right' },
    footer: {
      position: 'absolute',
      bottom: 20,
      left: 36,
      right: 36,
      borderTopWidth: 0.5,
      borderTopColor: '#e2e8f0',
      paddingTop: 6,
      flexDirection: 'row',
      justifyContent: 'space-between',
      alignItems: 'center',
    },
    footerLeft: { fontSize: 8, color: '#64748b' },
    footerRight: { fontSize: 8, color: '#94a3b8' },
    footerCenter: {
      position: 'absolute',
      left: 0,
      right: 0,
      top: 6,
      textAlign: 'center',
      fontSize: 8,
      color: '#64748b',
    },
  });
}
