import { useState, useMemo, useCallback } from 'react';
import useSWR from 'swr';
import { Icon } from '@iconify/react';
import Card from '@/components/Card';
import Badge from '@/components/Badge';
import SelectInput, {
  useSelect,
  OptionType,
} from '@/components/input/SelectInput';
import SelectInputCheckbox from '@/components/input/SelectInputCheckbox';
import DateInput from '@/components/input/DateInput';
import { CustomerApi } from '@/services/api/master-data';
import { FinanceApi } from '@/services/api/report/finance-report';
import { UserApi } from '@/services/api/user';
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 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] = useState(10);

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

  // ===== FILTER STATE =====
  const [filterCustomer, setFilterCustomer] = useState<typeof customerOptions>(
    []
  );
  // TODO: Uncomment when BE is ready
  // const [filterSales, setFilterSales] = useState<typeof salesOptions>([]);
  const [filterSales, setFilterSales] = useState<typeof salesOptions>([]);
  const [filterStartDate, setFilterStartDate] = useState('');
  const [filterEndDate, setFilterEndDate] = useState('');

  const filterModal = useModal();

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

  // TODO: Uncomment when BE is ready
  const {
    options: salesOptions,
    isLoadingOptions: isLoadingSales,
    loadMore: loadMoreSales,
    hasMore: hasMoreSales,
  } = useSelect(UserApi.basePath, 'id', 'name', 'search');

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

  const getPaymentStatusColor = (notes: string) => {
    const normalizedValue = notes.toLowerCase();

    if (normalizedValue === 'lunas') {
      return 'bg-info/10 text-info border-info';
    }

    if (normalizedValue.includes('belum')) {
      return 'bg-warning/10 text-warning border-warning';
    }

    return 'bg-gray-100 text-gray-600 border-gray-300';
  };

  const getPaymentStatusIndicatorColor = (notes: string) => {
    const normalizedValue = notes.toLowerCase();

    if (normalizedValue === 'lunas') {
      return 'bg-info';
    }

    if (normalizedValue.includes('belum')) {
      return 'bg-warning';
    }

    return 'bg-gray-400';
  };

  const getPaymentStatusText = (notes: string) => {
    return notes;
  };

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

  const handleApplyFilters = useCallback(() => {
    setIsSubmitted(true);
    setCurrentPage(1);
    filterModal.closeModal();
  }, [filterModal]);

  // ===== ACTIVE FILTERS COUNT =====
  const activeFiltersCount = useMemo(() => {
    let count = 0;

    // Date filter (start_date + end_date = 1 filter)
    if (filterStartDate || filterEndDate) {
      count += 1;
    }

    // Customer filter
    if (filterCustomer.length > 0) {
      count += 1;
    }

    // TODO: Uncomment when BE is ready
    // // Sales filter
    // if (filterSales.length > 0) {
    //   count += 1;
    // }

    return count;
  }, [
    filterStartDate,
    filterEndDate,
    filterCustomer,
    // filterSales,
  ]);

  const hasFilters = activeFiltersCount > 0;

  // ===== DATA FETCHING =====
  const { data: customerPayment, isLoading } = useSWR(
    isSubmitted
      ? () => {
          const params = {
            customer_id:
              filterCustomer.length > 0
                ? filterCustomer.map((v) => String(v.value)).join(',')
                : undefined,
            // TODO: Uncomment when BE is ready
            // sales_id:
            //   filterSales.length > 0
            //     ? filterSales.map((v) => String(v.value)).join(',')
            //     : undefined,
            // filter_by: 'do_date' as const,
            start_date: filterStartDate || undefined,
            end_date: filterEndDate || undefined,
            page: currentPage,
            limit: pageSize,
          };

          return ['customer-payment-report', params];
        }
      : null,
    ([, params]) =>
      FinanceApi.getCustomerPaymentReport(
        params.customer_id,
        undefined, // TODO: Change to params.sales_id when BE is ready
        undefined, // TODO: Change to params.filter_by when BE is ready
        params.start_date,
        params.end_date,
        params.page,
        params.limit
      )
  );

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

  // ===== 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,
      // TODO: Uncomment when BE is ready
      // sales_id:
      //   filterSales.length > 0
      //     ? filterSales.map((v) => String(v.value)).join(',')
      //     : undefined,
      start_date: filterStartDate || undefined,
      end_date: filterEndDate || undefined,
      limit: 100,
      page: 1,
    };

    const response = await FinanceApi.getCustomerPaymentReport(
      params.customer_id,
      undefined, // TODO: Change to params.sales_id when BE is ready
      undefined, // TODO: Change to params.filter_by when BE is ready
      params.start_date,
      params.end_date,
      params.page,
      params.limit
    );

    return isResponseSuccess(response)
      ? (response.data as unknown as CustomerPaymentReport[])
      : null;
  }, [filterCustomer, filterSales, 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,
        params: {
          customer_name:
            filterCustomer.length > 0
              ? filterCustomer.map((c) => c.label).join(', ')
              : undefined,
          // TODO: Uncomment when BE is ready
          // sales:
          //   filterSales.length > 0
          //     ? filterSales.map((s) => s.label).join(', ')
          //     : undefined,
          start_date: filterStartDate || undefined,
          end_date: filterEndDate || undefined,
          // TODO: Uncomment when BE is ready
          // filter_by: 'do_date' as const,
        },
      });
      toast.success('PDF berhasil dibuat dan diunduh.');
    } catch {
      toast.error('Gagal membuat PDF. Silakan coba lagi.');
    } finally {
      setIsPdfExportLoading(false);
    }
  }, [customerPaymentExport]);

  const getTableColumns = (
    summary: CustomerPaymentSummary
  ): ColumnDef<CustomerPaymentReport['rows'][0]>[] => {
    const tableColumns: ColumnDef<CustomerPaymentReport['rows'][0]>[] = [
      {
        id: 'no',
        header: 'No',
        cell: (props) => props.row.index,
        footer: () => <div className='font-semibold text-gray-900'>Total</div>,
      },
      {
        id: 'do_date_or_payment_date',
        header: 'Tanggal Jual/Bayar',
        accessorKey: 'trans_date',
        enableSorting: false,
        cell: (props) => {
          const value = props.row.original.trans_date;
          return value ? formatDate(value, 'DD MMM YYYY') : '-';
        },
      },
      {
        id: 'realization_date',
        header: 'Tanggal Realisasi',
        accessorKey: 'delivery_date',
        enableSorting: false,
        cell: (props) => {
          const value = props.row.original.delivery_date;
          return value ? formatDate(value, 'DD MMM YYYY') : '-';
        },
      },
      {
        id: 'aging',
        header: 'Aging',
        accessorKey: 'aging_day',
        enableSorting: false,
        cell: (props) => {
          const value = props.row.original.aging_day;
          return (
            <div className='text-center'>
              {value ? formatNumber(value) : '-'} hari
            </div>
          );
        },
      },
      {
        id: 'reference',
        header: 'Referensi',
        accessorKey: 'reference',
        enableSorting: false,
        cell: (props) => {
          const value = props.row.original.reference;
          return value || '-';
        },
      },
      {
        id: 'vehicle_plate',
        header: 'Nomor Polisi',
        accessorKey: 'vehicle_numbers',
        enableSorting: false,
        cell: (props) => {
          const value = props.row.original.vehicle_numbers;
          return value || '-';
        },
      },
      {
        id: 'qty',
        header: 'Qty',
        accessorKey: 'qty',
        enableSorting: false,
        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',
        enableSorting: false,
        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',
        enableSorting: false,
        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',
        enableSorting: false,
        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: 'final_price',
        header: 'Harga Akhir',
        accessorKey: 'final_price',
        enableSorting: false,
        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: 'total',
        header: 'Total',
        accessorKey: 'total_price',
        enableSorting: false,
        cell: (props) => {
          const value = props.row.original.total_price;
          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_amount',
        enableSorting: false,
        cell: (props) => {
          const value = props.row.original.payment_amount;
          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',
        enableSorting: false,
        cell: (props) => {
          const value = props.row.original.accounts_receivable;
          return (
            <div className='text-right text-error'>{formatCurrency(value)}</div>
          );
        },
        footer: () => (
          <div className='text-right font-semibold text-gray-900'>
            {formatCurrency(summary.total_accounts_receivable) || '-'}
          </div>
        ),
      },
      {
        id: 'notes',
        header: 'Keterangan',
        accessorKey: 'status',
        enableSorting: false,
        cell: (props) => {
          const value = props.row.original.status;

          if (!value) {
            return '-';
          }

          return (
            <Badge
              statusIndicator={true}
              variant='soft'
              className={{
                badge: `rounded-xl justify-start border border-gray-200 ${getPaymentStatusColor(value)}`,
                status: getPaymentStatusIndicatorColor(value),
              }}
            >
              {getPaymentStatusText(value)}
            </Badge>
          );
        },
      },
      {
        id: 'pickup_info',
        header: 'Pengambilan',
        accessorKey: 'pickup_info',
        enableSorting: false,
        cell: (props) => {
          const value = props.row.original.pickup_info;
          return value || '-';
        },
      },
      {
        id: 'sales_marketing',
        header: 'Sales/Marketing',
        accessorKey: 'sales_person',
        enableSorting: false,
        cell: (props) => {
          const value = props.row.original.sales_person;
          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}
            className={
              hasFilters
                ? 'bg-linear-to-b from-[#0069E0]/40 to-white text-[#0069E0] rounded-lg'
                : 'rounded-lg'
            }
          >
            <Icon icon='heroicons:funnel' width={18} height={18} />
            Filter
            {hasFilters && (
              <Badge
                variant='default'
                className={{
                  badge:
                    'rounded-lg px-1.5 py-2.5 text-xs font-semibold bg-error text-white',
                }}
              >
                {activeFiltersCount}
              </Badge>
            )}
          </Button>

          <Dropdown
            trigger={
              <Button
                variant='outline'
                isLoading={isAnyExportLoading}
                className='rounded-lg'
              >
                <Icon
                  icon='heroicons:cloud-arrow-down'
                  width={18}
                  height={18}
                />
                Export
              </Button>
            }
            align='end'
          >
            <Menu className={'w-full'}>
              <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);
                    }}
                    className={{ wrapper: 'w-full' }}
                  />
                </div>

                <div>
                  <DateInput
                    label='‎ '
                    name='end_date'
                    value={filterEndDate}
                    onChange={(e) => {
                      setFilterEndDate(e.target.value);
                    }}
                    className={{ wrapper: 'w-full' }}
                  />
                </div>
              </div>

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

              {/* TODO: Uncomment when BE is ready */}
              {/* <div>
                <SelectInputCheckbox
                  label='Sales'
                  placeholder='Pilih Sales'
                  options={salesOptions}
                  value={filterSales}
                  onChange={(val) => {
                    setFilterSales(Array.isArray(val) ? val : val ? [val] : []);
                  }}
                  isLoading={isLoadingSales}
                  isClearable
                  onMenuScrollToBottom={loadMoreSales}
                  className={{ wrapper: 'w-full' }}
                />
              </div> */}

              {/* TODO: Uncomment when BE is ready */}
              {/* <div>
                <SelectInput
                  label='Filter Berdasarkan'
                  placeholder='Pilih Filter Berdasarkan'
                  options={dataTypeOptions}
                  value={dataTypeOptions[0]}
                  isDisabled={true}
                  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 tableColumns = getTableColumns(summary);

            return (
              <Card
                key={customerReport.customer.id}
                title={customerReport.customer.name}
                className={{
                  wrapper: 'w-full rounded-2xl',
                  body: 'p-0',
                  title:
                    'py-1.5 px-3 bg-[#0069E0] text-white text-lg font-normal',
                }}
                variant='bordered'
                collapsible={true}
              >
                <Table
                  data={[
                    {
                      accounts_receivable: customerReport.initial_balance,
                    } as CustomerPaymentReport['rows'][0],
                    ...customerReport.rows,
                  ]}
                  columns={tableColumns}
                  pageSize={customerReport.rows.length + 1}
                  renderFooter={customerReport.rows.length > 0}
                  className={{
                    containerClassName: 'w-full',
                    tableWrapperClassName: 'overflow-x-auto',
                    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',
                  }}
                  renderCustomRow={(row) => {
                    if (row.index === 0) {
                      return (
                        <tr
                          className='hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200'
                          key={row.index}
                        >
                          <td
                            className='px-4 py-3 text-xs text-gray-900 whitespace-nowrap'
                            colSpan={15}
                          ></td>
                          <td className='px-4 py-3 text-xs text-gray-900 whitespace-nowrap'>
                            <div className='text-right text-error'>
                              {formatCurrency(row.original.accounts_receivable)}
                            </div>
                          </td>
                          <td
                            className='px-4 py-3 text-xs text-gray-900 whitespace-nowrap'
                            colSpan={4}
                          ></td>
                        </tr>
                      );
                    }
                  }}
                />
              </Card>
            );
          })
        )}
      </Card>
    </div>
  );
};

export default CustomerPaymentTab;
