import { useState, useMemo, useCallback } from 'react';
import { ChangeEventHandler } from 'react';
import useSWR from 'swr';
import { Icon } from '@iconify/react';
import Card from '@/components/Card';
import SelectInput, {
  useSelect,
  OptionType,
} from '@/components/input/SelectInput';
import DateInput from '@/components/input/DateInput';
import { CustomerApi } from '@/services/api/master-data';
import { FinanceApi } from '@/services/api/report/finance-report';
import Table from '@/components/Table';
import { ColumnDef } from '@tanstack/react-table';
import { formatCurrency, formatDate, formatNumber } from '@/lib/helper';
import {
  CustomerPaymentReport,
  CustomerPaymentSummary,
} from '@/types/api/report/customer-payment';
import { isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import Pagination from '@/components/Pagination';
import Button from '@/components/Button';
import Dropdown from '@/components/Dropdown';
import MenuItem from '@/components/menu/MenuItem';
import Menu from '@/components/menu/Menu';
import Modal from '@/components/Modal';
import { useModal } from '@/components/Modal';
import toast from 'react-hot-toast';
import { generateCustomerPaymentExcel } from '@/components/pages/report/finance/export/CustomerPaymentExportXLSX';
import { generateCustomerPaymentPDF } from '@/components/pages/report/finance/export/CustomerPaymentExportPDF';

const CustomerPaymentTab = () => {
  // ===== STATE MANAGEMENT =====
  const [isPdfExportLoading, setIsPdfExportLoading] = useState(false);
  const [isExcelExportLoading, setIsExcelExportLoading] = useState(false);
  const isAnyExportLoading = isPdfExportLoading || isExcelExportLoading;

  // ===== PAGINATION STATE =====
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(10);

  // ===== SUBMISSION STATE =====
  const [isSubmitted, setIsSubmitted] = useState(false);

  // ===== FILTER STATE =====
  const [filterCustomer, setFilterCustomer] = useState<OptionType[]>([]);
  const [filterSales, setFilterSales] = useState<OptionType[]>([]);
  const [filterDateType, setFilterDateType] = useState<OptionType | null>(null);
  const [filterStartDate, setFilterStartDate] = useState('');
  const [filterEndDate, setFilterEndDate] = useState('');
  const [filterErrors, setFilterErrors] = useState<Record<string, string>>({});

  // Filter Modal
  const filterModal = useModal();

  const { options: customerOptions, isLoadingOptions: isLoadingCustomers } =
    useSelect(CustomerApi.basePath, 'id', 'name', 'search');

  const salesOptions = useMemo(
    () => [
      { value: 'Sales A', label: 'Sales A' },
      { value: 'Sales B', label: 'Sales B' },
      { value: 'Sales C', label: 'Sales C' },
      // TODO: Fetch sales options from API
    ],
    []
  );

  const dataTypeOptions = useMemo(
    () => [
      { value: 'do_date', label: 'Tanggal Jual' },
      { value: 'payment_date', label: 'Tanggal Bayar' },
    ],
    []
  );

  // ===== FILTER HANDLERS =====
  const handleResetFilters = useCallback(() => {
    setIsSubmitted(false);
    setFilterCustomer([]);
    setFilterSales([]);
    setFilterDateType(null);
    setFilterStartDate('');
    setFilterEndDate('');
    setFilterErrors({});
  }, []);

  const handleApplyFilters = useCallback(() => {
    const errors: Record<string, string> = {};

    if (!filterStartDate) {
      errors.start_date = 'Tanggal mulai wajib diisi';
    }
    if (!filterEndDate) {
      errors.end_date = 'Tanggal akhir wajib diisi';
    }

    setFilterErrors(errors);

    if (Object.keys(errors).length === 0) {
      setIsSubmitted(true);
      setCurrentPage(1);
      filterModal.closeModal();
    }
  }, [filterModal, filterStartDate, filterEndDate]);

  // ===== DATA FETCHING =====
  const { data: customerPayment, isLoading } = useSWR(
    isSubmitted
      ? () => {
          const params = {
            customer_id:
              filterCustomer.length > 0
                ? filterCustomer.map((v) => String(v.value)).join(',')
                : undefined,
            sales:
              filterSales.length > 0
                ? filterSales.map((v) => String(v.value)).join(',')
                : undefined,
            date_type: filterDateType?.value as
              | 'do_date'
              | 'payment_date'
              | undefined,
            start_date: filterStartDate || undefined,
            end_date: filterEndDate || undefined,
            page: currentPage,
            limit: pageSize,
          };

          return ['customer-payment-report', params];
        }
      : null,
    ([, params]) =>
      FinanceApi.getCustomerPaymentReport(
        params.customer_id,
        params.sales,
        params.date_type,
        params.start_date,
        params.end_date,
        params.page,
        params.limit
      )
  );

  const data: CustomerPaymentReport[] = useMemo(
    () =>
      isResponseSuccess(customerPayment)
        ? (customerPayment?.data as unknown as CustomerPaymentReport[]) || []
        : [],
    [customerPayment]
  );

  const meta =
    isResponseSuccess(customerPayment) && customerPayment?.meta
      ? customerPayment.meta
      : null;

  // ===== EXPORT DATA FETCHER =====
  const customerPaymentExport = useCallback(async (): Promise<
    CustomerPaymentReport[] | null
  > => {
    const params = {
      customer_id:
        filterCustomer.length > 0
          ? filterCustomer.map((v) => String(v.value)).join(',')
          : undefined,
      sales:
        filterSales.length > 0
          ? filterSales.map((v) => String(v.value)).join(',')
          : undefined,
      date_type: filterDateType?.value as
        | 'do_date'
        | 'payment_date'
        | undefined,
      start_date: filterStartDate || undefined,
      end_date: filterEndDate || undefined,
      limit: 100,
      page: 1,
    };

    const response = await FinanceApi.getCustomerPaymentReport(
      params.customer_id,
      params.sales,
      params.date_type,
      params.start_date,
      params.end_date,
      params.page,
      params.limit
    );

    return isResponseSuccess(response)
      ? (response.data as unknown as CustomerPaymentReport[])
      : null;
  }, [
    filterCustomer,
    filterSales,
    filterDateType,
    filterStartDate,
    filterEndDate,
  ]);

  // ===== EXPORT HANDLERS =====
  const handleExportExcel = useCallback(async () => {
    setIsExcelExportLoading(true);
    try {
      const allDataForExport = await customerPaymentExport();

      if (
        !allDataForExport ||
        !Array.isArray(allDataForExport) ||
        allDataForExport.length === 0
      ) {
        toast.error('Tidak ada data untuk diekspor.');
        return;
      }

      generateCustomerPaymentExcel({ data: allDataForExport });
      toast.success('Excel berhasil dibuat dan diunduh.');
    } catch {
      toast.error('Gagal membuat Excel. Silakan coba lagi.');
    } finally {
      setIsExcelExportLoading(false);
    }
  }, [customerPaymentExport]);

  const handleExportPdf = useCallback(async () => {
    setIsPdfExportLoading(true);
    try {
      const allDataForExport = await customerPaymentExport();

      if (
        !allDataForExport ||
        !Array.isArray(allDataForExport) ||
        allDataForExport.length === 0
      ) {
        toast.error('Tidak ada data untuk diekspor.');
        return;
      }

      await generateCustomerPaymentPDF({ data: allDataForExport });
      toast.success('PDF berhasil dibuat dan diunduh.');
    } catch {
      toast.error('Gagal membuat PDF. Silakan coba lagi.');
    } finally {
      setIsPdfExportLoading(false);
    }
  }, [customerPaymentExport]);

  // ===== PAGINATION HANDLERS =====
  const handlePageChange = (page: number) => {
    setCurrentPage(page);
  };

  const handleRowChange = (pageSize: number) => {
    setPageSize(pageSize);
  };

  const handleNextPage = () => {
    if (meta && currentPage < meta.total_pages) {
      setCurrentPage(currentPage + 1);
    }
  };

  const handlePrevPage = () => {
    if (currentPage > 1) {
      setCurrentPage(currentPage - 1);
    }
  };

  const getTableColumns = (
    summary: CustomerPaymentSummary
  ): ColumnDef<CustomerPaymentReport['rows'][0]>[] => {
    const tableColumns: ColumnDef<CustomerPaymentReport['rows'][0]>[] = [
      {
        id: 'no',
        header: 'No',
        cell: (props) => props.row.index + 1,
        footer: () => <div className='font-semibold text-gray-900'>Total</div>,
      },
      {
        id: 'do_date_or_payment_date',
        header: 'Tanggal DO/Bayar',
        accessorKey: 'do_date',
        cell: (props) => {
          const value = props.row.original.do_date;
          return formatDate(value, 'DD MMM YYYY');
        },
      },
      {
        id: 'realization_date',
        header: 'Tanggal Realisasi',
        accessorKey: 'realization_date',
        cell: (props) => {
          const value = props.row.original.realization_date;
          return formatDate(value, 'DD MMM YYYY');
        },
      },
      {
        id: 'aging',
        header: 'Aging',
        accessorKey: 'aging',
        cell: (props) => {
          const value = props.row.original.aging;
          return <div className='text-center'>{formatNumber(value)} hari</div>;
        },
      },
      {
        id: 'reference',
        header: 'Referensi',
        accessorKey: 'reference',
        cell: (props) => {
          const value = props.row.original.reference;
          return value || '-';
        },
      },
      {
        id: 'vehicle_plate',
        header: 'Nomor Polisi',
        accessorKey: 'vehicle_plate',
        cell: (props) => {
          const value = props.row.original.vehicle_plate;
          return value || '-';
        },
      },
      {
        id: 'qty',
        header: 'Ekor/Qty',
        accessorKey: 'qty',
        cell: (props) => {
          const value = props.row.original.qty;
          return <div className='text-right'>{formatNumber(value)}</div>;
        },
        footer: () => (
          <div className='text-right font-semibold text-gray-900'>
            {formatNumber(summary.total_qty) || '-'}
          </div>
        ),
      },
      {
        id: 'weight',
        header: 'Berat (Kg)',
        accessorKey: 'weight',
        cell: (props) => {
          const value = props.row.original.weight;
          return <div className='text-right'>{formatNumber(value)}</div>;
        },
        footer: () => (
          <div className='text-right font-semibold text-gray-900'>
            {formatNumber(summary.total_weight) || '-'}
          </div>
        ),
      },
      {
        id: 'average_weight',
        header: 'AVG',
        accessorKey: 'average_weight',
        cell: (props) => {
          const value = props.row.original.average_weight;
          return <div className='text-right'>{formatNumber(value)}</div>;
        },
        footer: () => (
          <div className='text-right font-semibold text-gray-900'>-</div>
        ),
      },
      {
        id: 'price',
        header: 'Harga Awal',
        accessorKey: 'price',
        cell: (props) => {
          const value = props.row.original.price;
          return <div className='text-right'>{formatCurrency(value)}</div>;
        },
        footer: () => (
          <div className='text-right font-semibold text-gray-900'>
            {formatCurrency(summary.total_initial_amount) || '-'}
          </div>
        ),
      },
      {
        id: 'credit_note',
        header: 'CN',
        accessorKey: 'credit_note',
        cell: (props) => {
          const value = props.row.original.credit_note;
          return <div className='text-right'>{formatCurrency(value)}</div>;
        },
        footer: () => (
          <div className='text-right font-semibold text-gray-900'>
            {formatCurrency(summary.total_credit_note) || '-'}
          </div>
        ),
      },
      {
        id: 'final_price',
        header: 'Harga Akhir',
        accessorKey: 'final_price',
        cell: (props) => {
          const value = props.row.original.final_price;
          return <div className='text-right'>{formatCurrency(value)}</div>;
        },
        footer: () => (
          <div className='text-right font-semibold text-gray-900'>
            {formatCurrency(summary.total_final_amount) || '-'}
          </div>
        ),
      },
      {
        id: 'ppn',
        header: 'PPN (%)',
        accessorKey: 'ppn',
        cell: (props) => {
          const value = props.row.original.ppn;
          return <div className='text-right'>{formatNumber(value)}%</div>;
        },
        footer: () => (
          <div className='text-right font-semibold text-gray-900'>-</div>
        ),
      },
      {
        id: 'total',
        header: 'Total',
        accessorKey: 'total',
        cell: (props) => {
          const value = props.row.original.total;
          return <div className='text-right'>{formatCurrency(value)}</div>;
        },
        footer: () => (
          <div className='text-right font-semibold text-gray-900'>
            {formatCurrency(summary.total_grand_amount) || '-'}
          </div>
        ),
      },
      {
        id: 'payment',
        header: 'Pembayaran',
        accessorKey: 'payment',
        cell: (props) => {
          const value = props.row.original.payment;
          return <div className='text-right'>{formatCurrency(value)}</div>;
        },
        footer: () => (
          <div className='text-right font-semibold text-gray-900'>
            {formatCurrency(summary.total_payment) || '-'}
          </div>
        ),
      },
      {
        id: 'accounts_receivable',
        header: 'Saldo Piutang',
        accessorKey: 'accounts_receivable',
        cell: (props) => {
          const value = props.row.original.accounts_receivable;
          return <div className='text-right'>{formatCurrency(value)}</div>;
        },
        footer: () => (
          <div className='text-right font-semibold text-gray-900'>
            {formatCurrency(summary.total_accounts_receivable) || '-'}
          </div>
        ),
      },
      {
        id: 'notes',
        header: 'Keterangan',
        accessorKey: 'notes',
        cell: (props) => {
          const value = props.row.original.notes;
          return value || '-';
        },
      },
      {
        id: 'pickup_info',
        header: 'Pengambilan',
        accessorKey: 'pickup_info',
        cell: (props) => {
          const value = props.row.original.pickup_info;
          return value || '-';
        },
      },
      {
        id: 'sales_marketing',
        header: 'Sales/Marketing',
        accessorKey: 'sales_marketing',
        cell: (props) => {
          const value = props.row.original.sales_marketing;
          return value || '-';
        },
      },
    ];
    return tableColumns;
  };

  return (
    <div className='w-full p-0 sm:p-4'>
      <Card
        subtitle='Laporan > Kontrol Pembayaran Customer'
        className={{ wrapper: 'w-full', body: 'p-1!' }}
      >
        <div className='mb-4 flex justify-end gap-2 [&_button]:px-4'>
          <Button variant='outline' onClick={filterModal.openModal}>
            <Icon icon='heroicons:funnel' width={18} height={18} />
            Filter
          </Button>

          <Dropdown
            trigger={
              <Button variant='outline' isLoading={isAnyExportLoading}>
                <Icon
                  icon='heroicons:cloud-arrow-down'
                  width={18}
                  height={18}
                />
                Export
              </Button>
            }
            align='end'
          >
            <Menu>
              <MenuItem title='Excel' onClick={handleExportExcel} />
              <MenuItem title='PDF' onClick={handleExportPdf} />
            </Menu>
          </Dropdown>
        </div>

        {/* Filter Modal */}
        <Modal
          ref={filterModal.ref}
          className={{
            modal: 'p-0',
            modalBox: 'p-0 rounded-2xl xl:max-w-4/12 max-w-sm',
          }}
        >
          <div className='space-y-6'>
            {/* Modal Header */}
            <div className='flex items-center justify-between gap-2 py-3 border-b border-gray-300 px-4'>
              <div className='flex items-center gap-2 text-primary'>
                <Icon icon='heroicons:funnel' width={20} height={20} />
                <h3 className='font-semibold'>Filter Data</h3>
              </div>
              <Button
                variant='link'
                onClick={filterModal.closeModal}
                className='text-gray-500 hover:text-gray-700 transition-colors cursor-pointer'
              >
                <Icon icon='heroicons:x-mark' width={20} height={20} />
              </Button>
            </div>
            <div className='space-y-4 px-4'>
              <div className='grid grid-cols-1 sm:grid-cols-2 sm:gap-4'>
                <div>
                  <DateInput
                    label='Tanggal'
                    name='start_date'
                    value={filterStartDate}
                    onChange={(e) => {
                      setFilterStartDate(e.target.value);
                      setFilterErrors((prev) => ({ ...prev, start_date: '' }));
                    }}
                    className={{ wrapper: 'w-full' }}
                  />
                  {filterErrors.start_date && (
                    <p className='text-red-500 text-sm mt-1'>
                      {filterErrors.start_date}
                    </p>
                  )}
                </div>

                <div>
                  <DateInput
                    label='‎ '
                    name='end_date'
                    value={filterEndDate}
                    onChange={(e) => {
                      setFilterEndDate(e.target.value);
                      setFilterErrors((prev) => ({ ...prev, end_date: '' }));
                    }}
                    className={{ wrapper: 'w-full' }}
                  />
                  {filterErrors.end_date && (
                    <p className='text-red-500 text-sm mt-1'>
                      {filterErrors.end_date}
                    </p>
                  )}
                </div>
              </div>

              <div>
                <SelectInput
                  label='Customer'
                  placeholder='Pilih Customer'
                  isMulti
                  options={customerOptions}
                  value={filterCustomer}
                  onChange={(val) => {
                    setFilterCustomer(
                      Array.isArray(val) ? val : val ? [val] : []
                    );
                  }}
                  isLoading={isLoadingCustomers}
                  isClearable
                  className={{ wrapper: 'w-full' }}
                />
              </div>

              <div>
                <SelectInput
                  label='Sales'
                  placeholder='Pilih Sales'
                  isMulti
                  options={salesOptions}
                  value={filterSales}
                  onChange={(val) => {
                    setFilterSales(Array.isArray(val) ? val : val ? [val] : []);
                  }}
                  isClearable
                  className={{ wrapper: 'w-full' }}
                />
              </div>

              <div>
                <SelectInput
                  label='Filter Berdasarkan'
                  placeholder='Pilih Filter Berdasarkan'
                  options={dataTypeOptions}
                  value={filterDateType}
                  onChange={(val) => {
                    setFilterDateType(val as OptionType | null);
                  }}
                  isClearable={false}
                  className={{ wrapper: 'w-full' }}
                />
              </div>
            </div>

            {/* Action Buttons */}
            <div className='flex justify-between gap-4 py-4 mt-8 border-t border-gray-300 bg-gray-100'>
              <Button
                variant='soft'
                className='ms-4 min-w-36 rounded-lg'
                onClick={handleResetFilters}
              >
                Reset Filter
              </Button>
              <Button
                className='me-4 min-w-36 rounded-lg'
                onClick={handleApplyFilters}
              >
                Apply Filter
              </Button>
            </div>
          </div>
        </Modal>

        {!isSubmitted ? (
          <div className='mt-6 text-center text-gray-500'>
            Silakan klik tombol Filter untuk mengatur filter dan menampilkan
            data.
          </div>
        ) : isLoading ? (
          <div className='w-full flex flex-row justify-center items-center p-4'>
            <span className='loading loading-spinner loading-xl' />
          </div>
        ) : data.length === 0 ? (
          <div className='mt-6 text-center text-gray-500'>
            Tidak ada data yang dapat ditampilkan...
          </div>
        ) : (
          data.map((customerReport) => {
            const summary = customerReport.summary || {
              total_qty: 0,
              total_weight: 0,
              total_initial_amount: 0,
              total_credit_note: 0,
              total_final_amount: 0,
              total_ppn: 0,
              total_grand_amount: 0,
              total_payment: 0,
              total_accounts_receivable: 0,
            };

            const totalAccountsReceivable = summary.total_accounts_receivable;
            const tableColumns = getTableColumns(summary);

            return (
              <Card
                key={customerReport.customer.id}
                title={customerReport.customer.name}
                subtitle={`NPWP: ${customerReport.customer_npwp || '-'} | ${customerReport.customer_address || ''}\nSaldo Piutang: ${formatCurrency(totalAccountsReceivable)}`}
                className={{ wrapper: 'w-full' }}
                variant='bordered'
                collapsible={true}
              >
                <Table
                  data={customerReport.rows}
                  columns={tableColumns}
                  pageSize={10}
                  renderFooter={customerReport.rows.length > 0}
                  className={{
                    containerClassName: 'w-full',
                    tableWrapperClassName: 'overflow-x-auto mt-4',
                    tableClassName: 'w-full table-auto text-sm',
                    headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
                    headerColumnClassName:
                      'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
                    bodyRowClassName:
                      'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
                    bodyColumnClassName:
                      'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
                    tableFooterClassName:
                      'bg-gray-100 font-semibold border border-gray-200',
                    footerRowClassName: 'border-t-2 border-gray-300',
                    footerColumnClassName:
                      'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
                    paginationClassName: 'hidden',
                  }}
                />
              </Card>
            );
          })
        )}
      </Card>
      {meta && data.length > 0 && (
        <div className='mt-6'>
          <Pagination
            currentPage={meta.page}
            totalItems={meta.total_results}
            onPageChange={handlePageChange}
            onRowChange={handleRowChange}
            onNextPage={handleNextPage}
            onPrevPage={handlePrevPage}
            rowOptions={[10, 25, 50, 100]}
            itemsPerPage={meta.limit}
          />
        </div>
      )}
    </div>
  );
};

export default CustomerPaymentTab;
