'use client';

import { useState, useMemo, useEffect, useCallback } from 'react';
import useSWR from 'swr';
import { Icon } from '@iconify/react';
import { useFormik } from 'formik';
import toast from 'react-hot-toast';
import { ColumnDef } from '@tanstack/react-table';
import { AxiosError } from 'axios';
import { FinanceApi } from '@/services/api/report/finance-report';
import { CustomerApi } from '@/services/api/master-data';
import { UserApi } from '@/services/api/user';
import { useSelect, OptionType } from '@/components/input/SelectInput';
import { httpClientFetcher, SWRHttpKey } from '@/services/http/client';
import { BaseApiResponse } from '@/types/api/api-general';
import SelectInputCheckbox from '@/components/input/SelectInputCheckbox';
import SelectInputRadio from '@/components/input/SelectInputRadio';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { useTabActionsStore } from '@/stores/tab-actions/tab-actions.store';
import ButtonFilter from '@/components/helper/ButtonFilter';
import { formatCurrency, formatNumber } from '@/lib/helper';
import { isResponseSuccess } from '@/lib/api-helper';
import { BalanceMonitoringRow } from '@/types/api/report/balance-monitoring';
import { CustomerPaymentRow } from '@/types/api/report/customer-payment';
import Modal, { useModal } from '@/components/Modal';
import Button from '@/components/Button';
import Dropdown from '@/components/Dropdown';
import DateInput from '@/components/input/DateInput';
import Table from '@/components/Table';
import CustomerSupplierSkeleton from '@/components/pages/report/finance/skeleton/CustomerSupplierSkeleton';

interface BalanceMonitoringTabProps {
  tabId: string;
}

const filterByOptions: OptionType<string>[] = [
  { label: 'Tanggal Penjualan (SO Date)', value: 'sold_at' },
  { label: 'Tanggal Realisasi (Delivery Date)', value: 'realized_at' },
];

const BalanceMonitoringTab = ({ tabId }: BalanceMonitoringTabProps) => {
  const [hasDateError, setHasDateError] = useState(false);
  const [dateErrorShown, setDateErrorShown] = useState(false);
  const [isExcelExportLoading, setIsExcelExportLoading] = useState(false);

  const filterModal = useModal();

  const setTabActions = useTabActionsStore((state) => state.setTabActions);
  const clearTabActions = useTabActionsStore((state) => state.clearTabActions);

  const {
    state: tableFilterState,
    updateFilter,
    setPage,
    setPageSize,
    toQueryString: getTableFilterQueryString,
    reset: resetFilter,
  } = useTableFilter<{
    start_date: string;
    end_date: string;
    customers: OptionType<number>[];
    salesPersons: OptionType<number>[];
    filterBy?: OptionType<string>;
    sort_by: string;
    order_by: string;
  }>({
    initial: {
      start_date: '',
      end_date: '',
      customers: [],
      salesPersons: [],
      filterBy: undefined,
      sort_by: '',
      order_by: '',
    },
    paramMap: {
      page: 'page',
      pageSize: 'limit',
      start_date: 'start_date',
      end_date: 'end_date',
      customers: 'customer_ids',
      salesPersons: 'sales_ids',
      filterBy: 'filter_by',
      sort_by: 'sort_by',
      order_by: 'sort_order',
    },
    persist: true,
    storeName: 'balance-monitoring-table',
  });

  // const sorting: SortingState = tableFilterState.sort_by
  //   ? [
  //       {
  //         id: tableFilterState.sort_by,
  //         desc: tableFilterState.order_by === 'desc',
  //       },
  //     ]
  //   : [];

  // const handleSortingChange = (updater: Updater<SortingState>) => {
  //   const next = typeof updater === 'function' ? updater(sorting) : updater;
  //   if (next.length > 0) {
  //     updateFilter('sort_by', next[0].id, true);
  //     updateFilter('order_by', next[0].desc ? 'desc' : 'asc', true);
  //   } else {
  //     updateFilter('sort_by', '', true);
  //     updateFilter('order_by', '', true);
  //   }
  // };

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

  const {
    options: salesOptions,
    setInputValue: setSalesInput,
    isLoadingOptions: isLoadingSales,
    loadMore: loadMoreSales,
  } = useSelect(UserApi.basePath, 'id', 'name', 'search');

  const formik = useFormik({
    initialValues: {
      start_date: tableFilterState.start_date,
      end_date: tableFilterState.end_date,
      customers: tableFilterState.customers,
      salesPersons: tableFilterState.salesPersons,
      filterBy: tableFilterState.filterBy,
    },
    onSubmit: (values) => {
      updateFilter('start_date', values.start_date, true);
      updateFilter('end_date', values.end_date, true);
      updateFilter('customers', values.customers, true);
      updateFilter('salesPersons', values.salesPersons, true);
      updateFilter('filterBy', values.filterBy, true);
      filterModal.closeModal();
    },
  });

  const formikResetHandler = () => {
    resetFilter();

    setHasDateError(false);
    if (dateErrorShown) {
      toast.dismiss();
      setDateErrorShown(false);
    }

    formik.resetForm({
      values: {
        start_date: '',
        end_date: '',
        customers: [],
        salesPersons: [],
        filterBy: undefined,
      },
    });

    filterModal.closeModal();
  };

  const handleStartDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    formik.setFieldValue('start_date', value);

    if (value && formik.values.end_date) {
      if (new Date(formik.values.end_date) < new Date(value)) {
        setHasDateError(true);
        if (!dateErrorShown) {
          toast.error('Tanggal akhir tidak boleh masa lampau', {
            duration: Infinity,
          });
          setDateErrorShown(true);
        }
      } else {
        setHasDateError(false);
        if (dateErrorShown) {
          toast.dismiss();
          setDateErrorShown(false);
        }
      }
    } else {
      setHasDateError(false);
    }
  };

  const handleEndDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    formik.setFieldValue('end_date', value);

    if (value && formik.values.start_date) {
      if (new Date(value) < new Date(formik.values.start_date)) {
        setHasDateError(true);
        if (!dateErrorShown) {
          toast.error('Tanggal akhir tidak boleh masa lampau', {
            duration: Infinity,
          });
          setDateErrorShown(true);
        }
        return;
      }
    }

    setHasDateError(false);
    if (dateErrorShown) {
      toast.dismiss();
      setDateErrorShown(false);
    }
  };

  const { data: balanceMonitoringsResponse, isLoading } = useSWR<
    BaseApiResponse<BalanceMonitoringRow[]>,
    AxiosError<BaseApiResponse>,
    SWRHttpKey
  >(
    `${FinanceApi.basePath}/balance-monitoring${getTableFilterQueryString()}`,
    httpClientFetcher
  );

  const balanceMonitorings: BalanceMonitoringRow[] = isResponseSuccess(
    balanceMonitoringsResponse
  )
    ? ((balanceMonitoringsResponse.data as BalanceMonitoringRow[]) ?? [])
    : [];

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

  const handleExportExcel = useCallback(async () => {
    setIsExcelExportLoading(true);
    try {
      const customer_ids =
        tableFilterState.customers.length > 0
          ? tableFilterState.customers.map((o) => String(o.value)).join(',')
          : undefined;
      const sales_ids =
        tableFilterState.salesPersons.length > 0
          ? tableFilterState.salesPersons.map((o) => String(o.value)).join(',')
          : undefined;

      await FinanceApi.exportBalanceMonitoringToExcel(
        customer_ids,
        sales_ids,
        tableFilterState.filterBy?.value,
        tableFilterState.start_date || undefined,
        tableFilterState.end_date || undefined
      );
      toast.success('Excel berhasil dibuat dan diunduh.');
    } catch {
      toast.error('Gagal membuat Excel. Silakan coba lagi.');
    } finally {
      setIsExcelExportLoading(false);
    }
  }, [tableFilterState]);

  // Inject tab actions directly — no nested component, no remount cycle
  useEffect(() => {
    setTabActions(
      tabId,
      <div className='flex flex-row gap-3'>
        <ButtonFilter
          values={{
            start_date: tableFilterState.start_date,
            end_date: tableFilterState.end_date,
            customers: tableFilterState.customers,
            salesPersons: tableFilterState.salesPersons,
            filterBy: tableFilterState.filterBy,
          }}
          fieldGroups={[['start_date', 'end_date']]}
          onClick={filterModal.openModal}
          variant='outline'
          className='px-3 py-2.5'
        />

        <Dropdown
          align='end'
          direction='bottom'
          className={{
            content:
              'mt-1 rounded-xl border border-base-content/5 shadow-sm overflow-hidden',
          }}
          trigger={
            <Button
              variant='outline'
              color='none'
              isLoading={isExcelExportLoading}
              className='px-3 py-2.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
            >
              <div className='flex flex-row items-center gap-1.5'>
                <Icon
                  icon='heroicons:cloud-arrow-down'
                  width={20}
                  height={20}
                />
                <span>Export</span>
                <div className='w-px self-stretch bg-base-content/10' />
                <Icon icon='heroicons:chevron-down' width={14} height={14} />
              </div>
            </Button>
          }
        >
          <Button
            variant='ghost'
            color='none'
            onClick={handleExportExcel}
            isLoading={isExcelExportLoading}
            className='w-full p-3 justify-start text-sm text-base-content/50 font-semibold text-nowrap'
          >
            <Icon icon='heroicons:table-cells' width={20} height={20} />
            Ekspor ke Excel
          </Button>
        </Dropdown>
      </div>
    );
  }, [
    tabId,
    setTabActions,
    tableFilterState,
    filterModal.openModal,
    isExcelExportLoading,
    handleExportExcel,
  ]);

  useEffect(() => {
    return () => clearTabActions(tabId);
  }, [tabId, clearTabActions]);

  const columns = useMemo(
    (): ColumnDef<BalanceMonitoringRow>[] => [
      {
        header: 'No',
        enableSorting: false,
        cell: (props) =>
          (tableFilterState.page - 1) * tableFilterState.pageSize +
          props.row.index +
          1,
      },
      {
        header: 'Customer',
        accessorKey: 'customer.name',
        enableSorting: true,
        id: 'customer_name',
        cell: ({ row }) => row.original.customer.name,
      },
      {
        header: 'Saldo Awal',
        accessorKey: 'saldo_awal',
        id: 'saldo_awal',
        enableSorting: true,
        cell: ({ row }) => (
          <div className='text-right'>
            {formatCurrency(row.original.saldo_awal)}
          </div>
        ),
      },
      {
        header: 'Penjualan Ayam',
        columns: [
          {
            header: 'Ekor',
            accessorKey: 'penjualan_ayam.ekor',
            id: 'penjualan_ayam_ekor',
            enableSorting: true,
            cell: ({ row }) => (
              <div className='text-right'>
                {formatNumber(row.original.penjualan_ayam.ekor)}
              </div>
            ),
          },
          {
            header: 'Kg',
            accessorKey: 'penjualan_ayam.kg',
            id: 'penjualan_ayam_kg',
            enableSorting: true,
            cell: ({ row }) => (
              <div className='text-right'>
                {formatNumber(row.original.penjualan_ayam.kg)}
              </div>
            ),
          },
          {
            header: 'Nominal',
            accessorKey: 'penjualan_ayam.nominal',
            id: 'penjualan_ayam_nominal',
            enableSorting: true,
            cell: ({ row }) => (
              <div className='text-right'>
                {formatCurrency(row.original.penjualan_ayam.nominal)}
              </div>
            ),
          },
        ],
      },
      {
        header: 'Penjualan Telur',
        columns: [
          {
            header: 'Butir',
            accessorKey: 'penjualan_telur.butir',
            id: 'penjualan_telur_butir',
            enableSorting: true,
            cell: ({ row }) => (
              <div className='text-right'>
                {formatNumber(row.original.penjualan_telur.butir)}
              </div>
            ),
          },
          {
            header: 'Kg',
            accessorKey: 'penjualan_telur.kg',
            id: 'penjualan_telur_kg',
            enableSorting: true,
            cell: ({ row }) => (
              <div className='text-right'>
                {formatNumber(row.original.penjualan_telur.kg)}
              </div>
            ),
          },
          {
            header: 'Nominal',
            accessorKey: 'penjualan_telur.nominal',
            id: 'penjualan_telur_nominal',
            enableSorting: true,
            cell: ({ row }) => (
              <div className='text-right'>
                {formatCurrency(row.original.penjualan_telur.nominal)}
              </div>
            ),
          },
        ],
      },
      {
        header: 'Penjualan Trading',
        accessorKey: 'penjualan_trading.nominal',
        id: 'penjualan_trading',
        enableSorting: true,
        cell: ({ row }) => (
          <div className='text-right'>
            {formatCurrency(row.original.penjualan_trading.nominal)}
          </div>
        ),
      },
      {
        header: 'Pembayaran',
        accessorKey: 'pembayaran',
        id: 'pembayaran',
        enableSorting: true,
        cell: ({ row }) => (
          <div className='text-right'>
            {formatCurrency(row.original.pembayaran)}
          </div>
        ),
      },
      {
        header: 'Aging',
        accessorKey: 'aging',
        id: 'aging',
        enableSorting: true,
        cell: ({ row }) => (
          <div className='text-center'>
            {formatNumber(row.original.aging)} hari
          </div>
        ),
      },
      {
        header: 'Aging Rata-Rata',
        accessorKey: 'aging_rata_rata',
        id: 'aging_rata_rata',
        enableSorting: true,
        cell: ({ row }) => (
          <div className='text-center'>
            {formatNumber(row.original.aging_rata_rata)} hari
          </div>
        ),
      },
      {
        header: 'Saldo Akhir',
        accessorKey: 'saldo_akhir',
        id: 'saldo_akhir',
        enableSorting: true,
        cell: ({ row }) => (
          <div
            className={`text-right font-semibold ${row.original.saldo_akhir < 0 ? 'text-error' : ''}`}
          >
            {formatCurrency(row.original.saldo_akhir)}
          </div>
        ),
      },
    ],
    [tableFilterState.page, tableFilterState.pageSize]
  );

  return (
    <>
      <div className='w-full p-0 sm:p-3 flex flex-col gap-3'>
        {isLoading && (
          <div className='w-full flex flex-row justify-center items-center p-4'>
            <span className='loading loading-spinner loading-xl' />
          </div>
        )}

        {!isLoading && balanceMonitorings.length === 0 && (
          <CustomerSupplierSkeleton
            columns={columns as unknown as ColumnDef<CustomerPaymentRow>[]}
            icon={
              <Icon
                icon='heroicons:chart-bar'
                className='text-white'
                width={20}
                height={20}
              />
            }
            title='Data Not Yet Available'
            subtitle='Please change your filters to get the data.'
          />
        )}

        {!isLoading && balanceMonitorings.length > 0 && (
          <>
            <div className='w-full overflow-x-auto'>
              <Table
                data={balanceMonitorings}
                columns={columns}
                pageSize={tableFilterState.pageSize || 10}
                page={tableFilterState.page || 1}
                totalItems={meta?.total_results || 0}
                onPageChange={setPage}
                onPageSizeChange={setPageSize}
                // sorting={sorting}
                // setSorting={handleSortingChange}
                // manualSorting
                className={{
                  containerClassName: 'w-full mb-0!',
                  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 text-nowrap',
                  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',
                }}
              />
            </div>
          </>
        )}
      </div>

      {/* Filter Modal */}
      <Modal
        ref={filterModal.ref}
        className={{
          modal: 'p-0',
          modalBox: 'p-0 rounded-[0.875rem] xl:max-w-4/12 max-w-sm',
        }}
      >
        {/* Modal Header */}
        <div className='flex items-center justify-between gap-2 border-b border-base-content/10 p-4'>
          <div className='flex items-center gap-2 text-primary'>
            <Icon icon='heroicons:funnel' width={20} height={20} />
            <h3 className='font-medium text-sm'>Filter Data</h3>
          </div>
          <Button
            variant='link'
            onClick={filterModal.closeModal}
            className='text-base-content/50 hover:text-base-content transition-colors cursor-pointer'
          >
            <Icon icon='heroicons:x-mark' width={20} height={20} />
          </Button>
        </div>

        <form onSubmit={formik.handleSubmit} onReset={formikResetHandler}>
          <div className='p-4 flex flex-col gap-3'>
            <div>
              <label className='block text-xs font-semibold text-base-content py-2'>
                Tanggal
              </label>
              <div className='flex flex-row gap-1.5 items-center justify-between'>
                <DateInput
                  name='start_date'
                  value={formik.values.start_date || ''}
                  onChange={handleStartDateChange}
                  className={{ wrapper: 'w-full' }}
                  isNestedModal
                />
                <hr className='w-full max-w-3 h-px border-base-content/10' />
                <DateInput
                  name='end_date'
                  value={formik.values.end_date || ''}
                  onChange={handleEndDateChange}
                  className={{ wrapper: 'w-full' }}
                  isNestedModal
                  isError={hasDateError}
                />
              </div>
            </div>

            <SelectInputCheckbox
              label='Customer'
              placeholder='Pilih Customer'
              options={customerOptions}
              value={formik.values.customers}
              onChange={(val) =>
                formik.setFieldValue('customers', Array.isArray(val) ? val : [])
              }
              onInputChange={setCustomerInput}
              isLoading={isLoadingCustomers}
              isClearable
              onMenuScrollToBottom={loadMoreCustomers}
              className={{ wrapper: 'w-full' }}
            />

            <SelectInputCheckbox
              label='Sales'
              placeholder='Pilih Sales'
              options={salesOptions}
              value={formik.values.salesPersons}
              onChange={(val) =>
                formik.setFieldValue(
                  'salesPersons',
                  Array.isArray(val) ? val : []
                )
              }
              onInputChange={setSalesInput}
              isLoading={isLoadingSales}
              isClearable
              onMenuScrollToBottom={loadMoreSales}
              className={{ wrapper: 'w-full' }}
            />

            <SelectInputRadio
              label='Filter Berdasarkan'
              placeholder='Pilih Filter Berdasarkan'
              options={filterByOptions}
              value={formik.values.filterBy ?? null}
              onChange={(val) =>
                formik.setFieldValue(
                  'filterBy',
                  !Array.isArray(val) ? (val ?? undefined) : undefined
                )
              }
              isClearable
              className={{ wrapper: 'w-full' }}
            />
          </div>

          {/* Modal Footer */}
          <div className='flex justify-between items-center gap-4 p-4 border-t border-base-content/10 bg-gray-50'>
            <Button
              type='reset'
              variant='soft'
              className='rounded-lg text-base-content/65 bg-transparent border-none hover:bg-base-content/10 hover:text-base-content/65 transition-colors px-3 py-2'
            >
              Reset Filter
            </Button>
            <Button
              type='submit'
              className='min-w-40 text-sm rounded-lg py-3 text-white font-semibold'
              disabled={hasDateError}
            >
              Apply Filter
            </Button>
          </div>
        </form>
      </Modal>
    </>
  );
};

export default BalanceMonitoringTab;
