'use client';

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

import {
  formatDate,
  formatCurrency,
  formatNumber,
  formatTitleCase,
} from '@/lib/helper';
import { CustomerPaymentReport } from '@/types/api/report/customer-payment';
import { PdfTable, PdfColumn } from '@/components/helper/pdf/table';
import { PdfParamBadge } from '@/components/helper/pdf/badge/PdfParamBadge';
import { PdfStatusBadge } from '@/components/helper/pdf/badge/PdfStatusBadge';
import { PdfTypography } from '@/components/helper/pdf/typography/PdfTypography';
import { getPDFBadgeStyle } from '@/components/helper/pdf/utils/pdf-badge';

Font.register({
  family: 'Helvetica',
  src: 'helvetica',
});

const pdfStyles = StyleSheet.create({
  page: {
    fontSize: 10,
    fontFamily: 'Helvetica',
    padding: 20,
    backgroundColor: '#FFFFFF',
  },
  titleSection: {
    marginBottom: 10,
  },
  parameterContainer: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    marginBottom: 8,
  },
});

interface CustomerPaymentExportPDFParams {
  data: CustomerPaymentReport[];
  params?: {
    customer_name?: string;
    // TODO: Uncomment when BE is ready
    // sales?: string;
    start_date?: string;
    end_date?: string;
    filter_by?: string;
  };
}

const getTableColumns = (
  summary?: CustomerPaymentReport['summary']
): PdfColumn<CustomerPaymentReport['rows'][number]>[] => [
  {
    key: 'no',
    header: 'No',
    flex: 0.5,
    align: 'center',
    cell: ({ index }) => index + 1,
    footer: 'Total',
  },
  {
    key: 'trans_date',
    header: 'Tanggal DO',
    flex: 1.2,
    align: 'center',
    cell: ({ row }) =>
      row.trans_date ? formatDate(row.trans_date, 'DD MMM YY') : '-',
    footer: '',
  },
  {
    key: 'delivery_date',
    header: 'Tanggal Realisasi',
    flex: 1.2,
    align: 'center',
    cell: ({ row }) =>
      row.delivery_date ? formatDate(row.delivery_date, 'DD MMM YY') : '-',
    footer: '',
  },
  {
    key: 'aging',
    header: 'Aging',
    flex: 0.8,
    align: 'center',
    cell: ({ row }) =>
      row.aging_day != null ? `${formatNumber(row.aging_day)} hari` : '-',
    footer: '',
  },
  {
    key: 'reference',
    header: 'Referensi',
    flex: 1.5,
    align: 'left',
    cell: ({ row }) => row.reference || '-',
    footer: '',
  },
  {
    key: 'vehicle_numbers',
    header: 'No Polisi',
    flex: 1.2,
    align: 'left',
    cell: ({ row }) =>
      Array.isArray(row.vehicle_numbers) && row.vehicle_numbers.length > 0
        ? row.vehicle_numbers.join(', ')
        : '-',
    footer: '',
  },
  {
    key: 'qty',
    header: 'Qty',
    flex: 0.8,
    align: 'right',
    cell: ({ row }) => formatNumber(row.qty),
    footer: summary ? formatNumber(summary.total_qty || 0) : '',
    footerAlign: 'right',
  },
  {
    key: 'weight',
    header: 'Berat',
    flex: 1,
    align: 'right',
    cell: ({ row }) => formatNumber(row.weight),
    footer: summary ? formatNumber(summary.total_weight || 0) : '',
    footerAlign: 'right',
  },
  {
    key: 'average_weight',
    header: 'Rata-Rata',
    flex: 0.8,
    align: 'right',
    cell: ({ row }) => formatNumber(row.average_weight),
    footer: '',
  },
  {
    key: 'unit_price',
    header: 'Harga/Unit (Rp)',
    flex: 1.2,
    align: 'right',
    cell: ({ row }) => formatCurrency(row.unit_price),
    footer: '',
  },
  {
    key: 'final_price',
    header: 'Harga Akhir (Rp)',
    flex: 1.2,
    align: 'right',
    cell: ({ row }) => formatCurrency(row.final_price),
    footer: summary ? formatCurrency(summary.total_final_amount || 0) : '',
    footerAlign: 'right',
  },
  {
    key: 'total_price',
    header: 'Total (Rp)',
    flex: 1.2,
    align: 'right',
    cell: ({ row }) => formatCurrency(row.total_price),
    footer: summary ? formatCurrency(summary.total_grand_amount || 0) : '',
    footerAlign: 'right',
  },
  {
    key: 'payment_amount',
    header: 'Pembayaran (Rp)',
    flex: 1.2,
    align: 'right',
    cell: ({ row }) => formatCurrency(row.payment_amount),
    footer: summary ? formatCurrency(summary.total_payment || 0) : '',
    footerAlign: 'right',
  },
  {
    key: 'accounts_receivable',
    header: 'Saldo (Rp)',
    flex: 1.2,
    align: 'right',
    cell: ({ row }) => (
      <Text style={{ color: row.accounts_receivable < 0 ? 'red' : 'black' }}>
        {formatCurrency(row.accounts_receivable)}
      </Text>
    ),
    footer: summary
      ? formatCurrency(summary.total_accounts_receivable || 0)
      : '',
    footerAlign: 'right',
    footerColor:
      (summary?.total_accounts_receivable || 0) < 0 ? 'red' : undefined,
  },
  {
    key: 'status',
    header: 'Keterangan',
    flex: 1.5,
    align: 'center',
    cell: ({ row }) =>
      row.status ? (
        <View style={{ alignItems: 'center' }}>
          <PdfStatusBadge
            style={{
              backgroundColor: getPDFBadgeStyle(row.status, 'payment').bg,
              color: getPDFBadgeStyle(row.status, 'payment').text,
              borderColor: getPDFBadgeStyle(row.status, 'payment').border,
            }}
          >
            {formatTitleCase(row.status)}
          </PdfStatusBadge>
        </View>
      ) : (
        '-'
      ),
    footer: '',
  },
  {
    key: 'pickup_info',
    header: 'Pengambilan',
    flex: 1,
    align: 'left',
    cell: ({ row }) =>
      Array.isArray(row.pickup_info) && row.pickup_info.length > 0
        ? row.pickup_info.join(', ')
        : '-',
    footer: '',
  },
  {
    key: 'sales_person',
    header: 'Sales',
    flex: 1.5,
    align: 'left',
    cell: ({ row }) => row.sales_person || '-',
    footer: '',
  },
];

const createPDFDocument = (params: CustomerPaymentExportPDFParams) => {
  return (
    <Document>
      {params.data.map((customerReport, customerIndex) => (
        <Page
          key={customerIndex}
          size='A3'
          orientation='landscape'
          style={pdfStyles.page}
        >
          {/* Title and Parameters */}
          <View style={pdfStyles.titleSection}>
            <PdfTypography size='h1' variant='primary'>
              Laporan &gt; Kontrol Pembayaran Customer
            </PdfTypography>
            <View style={pdfStyles.parameterContainer}>
              <PdfParamBadge>
                Periode:{' '}
                {params.params?.start_date
                  ? formatDate(params.params.start_date, 'DD MMM YYYY')
                  : '-'}{' '}
                s.d{' '}
                {params.params?.end_date
                  ? formatDate(params.params.end_date, 'DD MMM YYYY')
                  : '-'}
              </PdfParamBadge>
              {/* TODO: Uncomment when BE is ready */}
              {/* <PdfParamBadge>
                Filter Tanggal: Tanggal DO
              </PdfParamBadge> */}
              <PdfParamBadge>
                Customer: {params.params?.customer_name || 'Semua Customer'}
              </PdfParamBadge>
              <PdfParamBadge>
                Dicetak: {formatDate(new Date(), 'DD MMM YYYY HH:mm')}
              </PdfParamBadge>
            </View>
            <PdfTypography size='h2' variant='primary'>
              {customerReport.customer.name}
            </PdfTypography>
            <PdfTypography size='label'>
              Alamat: {customerReport.customer.address || '-'}
            </PdfTypography>
          </View>

          {/* Table */}
          <PdfTable
            columns={getTableColumns(customerReport.summary)}
            data={customerReport.rows}
            showFooter={!!customerReport.summary}
            firstRow={
              typeof customerReport.initial_balance === 'number' &&
              customerReport.initial_balance !== 0
                ? {
                    valueKey: 'accounts_receivable',
                    value: customerReport.initial_balance,
                    align: 'right',
                    color: customerReport.initial_balance < 0 ? 'red' : 'black',
                  }
                : undefined
            }
          />
        </Page>
      ))}
    </Document>
  );
};

export const generateCustomerPaymentPDF = async (
  params: CustomerPaymentExportPDFParams
): Promise<void> => {
  const PDFDocument = createPDFDocument(params);

  try {
    const blob = await pdf(PDFDocument).toBlob();
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = `laporan-kontrol-pembayaran-customer-${formatDate(new Date(), 'YYYY-MM-DD-HHmm')}.pdf`;

    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  } catch (error) {
    throw error;
  }
};
