'use client';

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

import { formatDate, formatCurrency, formatNumber } from '@/lib/helper';
import { DebtSupplier } from '@/types/api/report/debt-supplier';
import { PdfParamBadge } from '@/components/helper/pdf/badge/PdfParamBadge';
import { PdfTypography } from '@/components/helper/pdf/typography/PdfTypography';
import { PdfStatusBadge } from '@/components/helper/pdf/badge/PdfStatusBadge';
import { PdfTable, PdfColumn } from '@/components/helper/pdf/table';
import { getPDFBadgeStyle } from '@/components/helper/pdf/utils/pdf-badge';
import { Text } from '@react-pdf/renderer';

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,
  },
});

const getTableColumns = (total?: DebtSupplier['total']): PdfColumn[] => {
  type DebtRow = DebtSupplier['rows'][number];

  return [
    {
      key: 'no',
      header: 'No',
      flex: 0.5,
      align: 'center',
      cell: ({ index }) => index + 1,
      footer: 'Total',
    },
    {
      key: 'pr_number',
      header: 'No. PR',
      flex: 1,
      align: 'left',
      cell: ({ row }) => (row as unknown as DebtRow).pr_number || '-',
      footer: '',
    },
    {
      key: 'po_number',
      header: 'No. PO',
      flex: 1,
      align: 'left',
      cell: ({ row }) => (row as unknown as DebtRow).po_number || '-',
      footer: '',
    },
    {
      key: 'received_date',
      header: 'Tgl Terima/Bayar',
      flex: 0.7,
      align: 'center',
      cell: ({ row }) =>
        (row as unknown as DebtRow).received_date
          ? formatDate((row as unknown as DebtRow).received_date, 'DD MMM YY')
          : '-',
      footer: '',
    },
    {
      key: 'po_date',
      header: 'Tgl PO',
      flex: 0.7,
      align: 'center',
      cell: ({ row }) =>
        (row as unknown as DebtRow).po_date
          ? formatDate((row as unknown as DebtRow).po_date, 'DD MMM YY')
          : '-',
      footer: '',
    },
    {
      key: 'aging',
      header: 'Aging',
      flex: 0.6,
      align: 'center',
      cell: ({ row }) =>
        (row as unknown as DebtRow).aging != null
          ? `${formatNumber((row as unknown as DebtRow).aging)}`
          : '-',
      footer: total ? formatNumber(total.aging || 0) + ' Hari' : '',
    },
    {
      key: 'area',
      header: 'Area',
      flex: 1,
      align: 'left',
      cell: ({ row }) => (row as unknown as DebtRow).area?.name || '-',
      footer: '',
    },
    {
      key: 'warehouse',
      header: 'Gudang',
      flex: 1,
      align: 'left',
      cell: ({ row }) => (row as unknown as DebtRow).warehouse?.name || '-',
      footer: '',
    },
    {
      key: 'due_date',
      header: 'Jatuh Tempo',
      flex: 1,
      align: 'center',
      cell: ({ row }) =>
        (row as unknown as DebtRow).due_date
          ? formatDate((row as unknown as DebtRow).due_date, 'DD MMM YY')
          : '-',
      footer: '',
    },
    {
      key: 'due_status',
      header: 'Status Jatuh Tempo',
      flex: 2,
      align: 'center',
      cell: ({ row }) =>
        (row as unknown as DebtRow).due_status &&
        (row as unknown as DebtRow).due_status !== '-' ? (
          <View style={{ alignItems: 'center' }}>
            <PdfStatusBadge
              style={{
                backgroundColor: getPDFBadgeStyle(
                  (row as unknown as DebtRow).due_status,
                  'due'
                ).bg,
                color: getPDFBadgeStyle(
                  (row as unknown as DebtRow).due_status,
                  'due'
                ).text,
                borderColor: getPDFBadgeStyle(
                  (row as unknown as DebtRow).due_status,
                  'due'
                ).border,
              }}
            >
              {(row as unknown as DebtRow).due_status}
            </PdfStatusBadge>
          </View>
        ) : (
          '-'
        ),
      footer: '',
    },
    {
      key: 'total_price',
      header: 'Nominal Pembelian (Rp)',
      flex: 1.5,
      align: 'right',
      cell: ({ row }) => (
        <Text
          style={{
            color:
              (row as unknown as DebtRow).total_price < 0 ? 'red' : 'black',
          }}
        >
          {formatCurrency((row as unknown as DebtRow).total_price)}
        </Text>
      ),
      footer: total ? formatCurrency(total.total_price || 0) : '',
      footerAlign: 'right',
    },
    {
      key: 'payment_price',
      header: 'Pembayaran (Rp)',
      flex: 1.5,
      align: 'right',
      cell: ({ row }) => (
        <Text
          style={{
            color:
              (row as unknown as DebtRow).payment_price < 0 ? 'red' : 'black',
          }}
        >
          {formatCurrency((row as unknown as DebtRow).payment_price)}
        </Text>
      ),
      footer: total ? formatCurrency(total.payment_price || 0) : '',
      footerAlign: 'right',
    },
    {
      key: 'balance',
      header: 'Sisa Saldo Hutang (Rp)',
      flex: 1.5,
      align: 'right',
      cell: ({ row }) => (
        <Text
          style={{
            color: (row as unknown as DebtRow).balance < 0 ? 'red' : 'black',
          }}
        >
          {formatCurrency((row as unknown as DebtRow).balance)}
        </Text>
      ),
      footer: total ? formatCurrency(total.debt_price || 0) : '',
      footerAlign: 'right',
      footerColor: (total?.debt_price || 0) < 0 ? 'red' : undefined,
    },
    {
      key: 'status',
      header: 'Status',
      flex: 1.2,
      align: 'center',
      cell: ({ row }) =>
        (row as unknown as DebtRow).status &&
        (row as unknown as DebtRow).status !== '-' ? (
          <View style={{ alignItems: 'center' }}>
            <PdfStatusBadge
              style={{
                backgroundColor: getPDFBadgeStyle(
                  (row as unknown as DebtRow).status,
                  'payment'
                ).bg,
                color: getPDFBadgeStyle(
                  (row as unknown as DebtRow).status,
                  'payment'
                ).text,
                borderColor: getPDFBadgeStyle(
                  (row as unknown as DebtRow).status,
                  'payment'
                ).border,
              }}
            >
              {(row as unknown as DebtRow).status}
            </PdfStatusBadge>
          </View>
        ) : (
          '-'
        ),
      footer: '',
    },
    {
      key: 'travel_number',
      header: 'No. Perjalanan',
      flex: 1,
      align: 'left',
      cell: ({ row }) => (row as unknown as DebtRow).travel_number || '-',
      footer: '',
    },
  ];
};

interface DebtSupplierExportPDFParams {
  data: DebtSupplier[];
  params?: {
    supplier_name?: string;
    start_date?: string;
    end_date?: string;
    filter_by?: string;
  };
}

const createPDFDocument = (params: DebtSupplierExportPDFParams) => {
  return (
    <Document>
      {params.data.map((supplierReport, supplierIndex) => (
        <Page
          key={supplierIndex}
          size='A3'
          orientation='landscape'
          style={pdfStyles.page}
        >
          {/* Title and Supplier Info */}
          <View style={pdfStyles.titleSection}>
            <PdfTypography size='h1' variant='primary'>
              Laporan &gt; Rekapitulasi Hutang ke Supplier
            </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>
              {params.params?.filter_by && (
                <PdfParamBadge>
                  Filter Tanggal:{' '}
                  {params.params.filter_by === 'po_date'
                    ? 'Tanggal PO'
                    : params.params.filter_by === 'received_date'
                      ? 'Tanggal Terima'
                      : params.params.filter_by === 'due_date'
                        ? 'Tanggal Jatuh Tempo'
                        : params.params.filter_by}
                </PdfParamBadge>
              )}
              <PdfParamBadge>
                Supplier: {params.params?.supplier_name || 'Semua Supplier'}
              </PdfParamBadge>
              <PdfParamBadge>
                Dicetak: {formatDate(new Date(), 'DD MMM YYYY HH:mm')}
              </PdfParamBadge>
            </View>
            <PdfTypography size='h2' variant='primary'>
              {supplierReport.supplier.name}
            </PdfTypography>
            <PdfTypography size='label'>
              {supplierReport.supplier.category}
            </PdfTypography>
          </View>

          {/* Table */}
          <PdfTable
            columns={getTableColumns(supplierReport.total)}
            data={supplierReport.rows as unknown as Record<string, unknown>[]}
            showFooter={!!supplierReport.total}
            firstRow={
              typeof supplierReport.initial_balance === 'number' &&
              supplierReport.initial_balance !== 0
                ? {
                    valueKey: 'balance',
                    value: supplierReport.initial_balance,
                    align: 'right',
                    color: supplierReport.initial_balance < 0 ? 'red' : 'black',
                  }
                : undefined
            }
          />
        </Page>
      ))}
    </Document>
  );
};

export const generateDebtSupplierPDF = async (
  params: DebtSupplierExportPDFParams
): 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-hutang-supplier-${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;
  }
};
