'use client';

import { ChangeEventHandler, useCallback, useMemo, useState } from 'react';
import useSWR from 'swr';
import {
  CellContext,
  ColumnDef,
  Row,
  SortingState,
  Updater,
} from '@tanstack/react-table';
import toast from 'react-hot-toast';

import { Icon } from '@iconify/react';
import Table from '@/components/Table';
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
import DateInput from '@/components/input/DateInput';
import SelectInput, { OptionType } from '@/components/input/SelectInput';
import TextArea from '@/components/input/TextArea';
import Button from '@/components/Button';
import Modal, { useModal } from '@/components/Modal';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import PopoverButton from '@/components/popover/PopoverButton';
import PopoverContent from '@/components/popover/PopoverContent';
import RealizationStatusBadge from '@/components/pages/expense/RealizationStatusBadge';
import ExpenseStatusBadge from '@/components/pages/expense/ExpenseStatusBadge';
import CheckboxInput from '@/components/input/CheckboxInput';
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
import RequirePermission from '@/components/helper/RequirePermission';
import ButtonFilter from '@/components/helper/ButtonFilter';
import ExpensesFilterModal from '@/components/pages/expense/filter/ExpensesFilterModal';
import ExpenseTableSkeleton from '@/components/pages/expense/skeleton/ExpenseTableSkeleton';
import Dropdown from '@/components/dropdown/Dropdown';
import StatusBadge from '@/components/helper/StatusBadge';

import { Expense } from '@/types/api/expense';
import { ExpenseApi } from '@/services/api/expense';
import { cn, formatCurrency, formatDate } from '@/lib/helper';
import { getErrorMessage, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { BaseApiResponse } from '@/types/api/api-general';

type ExpenseTableFilters = {
  search: string;
  sort_by: string;
  order_by: string;
  transactionDate: string;
  realizationDate: string;
  locationId: string;
  locationName: string;
  vendorId: string;
  vendorName: string;
  category: string;
  approvalStatus: string;
  realizationStatus: string;
  projectFlockId: string;
  projectFlockName: string;
  projectFlockKandangId: string;
  projectFlockKandangName: string;
  userId: string;
};

const approvalStatusOptions = [
  { value: 'HEAD_AREA', label: 'Approval Head Area' },
  { value: 'UNIT_VICE_PRESIDENT', label: 'Approval Unit Vice President' },
  { value: 'FINANCE', label: 'Approval Finance' },
  { value: 'REALISASI', label: 'Realisasi' },
  { value: 'SELESAI', label: 'Selesai' },
] as const satisfies OptionType<
  'HEAD_AREA' | 'UNIT_VICE_PRESIDENT' | 'FINANCE' | 'REALISASI' | 'SELESAI'
>[];

type ApprovalStatusValue =
  | 'HEAD_AREA'
  | 'UNIT_VICE_PRESIDENT'
  | 'FINANCE'
  | 'REALISASI'
  | 'SELESAI';

const isApprovalDateRequired = (status?: ApprovalStatusValue) =>
  status === 'REALISASI' || status === 'SELESAI';

const RowOptionsMenu = ({
  popoverPosition = 'bottom',
  props,
  deleteClickHandler,
  paidOffClickHandler,
}: {
  popoverPosition: 'bottom' | 'top';
  props: CellContext<Expense, unknown>;
  deleteClickHandler: () => void;
  paidOffClickHandler: () => void;
}) => {
  const popoverId = `expense#${props.row.original.id}`;
  const popoverAnchorName = `--anchor-expense#${props.row.original.id}`;

  const closePopover = () => {
    document.getElementById(popoverId)?.hidePopover();
  };

  const showEditButton = props.row.original.latest_approval
    ? props.row.original.latest_approval.step_number !== 6 &&
      (props.row.original.latest_approval.step_number === 1 ||
        props.row.original.latest_approval.step_number === 2 ||
        props.row.original.latest_approval.step_number === 3 ||
        props.row.original.latest_approval.step_number === 4)
    : false;

  const showRealizationButton = props.row.original.latest_approval
    ? props.row.original.latest_approval.action !== 'REJECTED' &&
      props.row.original.latest_approval.step_number === 4
    : false;

  const showPaidOffButton = props.row.original.latest_approval
    ? props.row.original.latest_approval.step_number >= 4 &&
      !props.row.original.is_paid
    : false;

  return (
    <div className='relative'>
      <PopoverButton
        tabIndex={0}
        variant='ghost'
        color='none'
        popoverTarget={popoverId}
        anchorName={popoverAnchorName}
      >
        <Icon icon='material-symbols:more-vert' width={16} height={16} />
      </PopoverButton>

      <PopoverContent
        id={popoverId}
        anchorName={popoverAnchorName}
        position={popoverPosition === 'bottom' ? 'bottom-start' : 'left'}
        className='w-full max-w-40 rounded-xl border border-base-content/5 shadow-sm'
      >
        <div className='flex flex-col bg-base-100 rounded-xl'>
          <RequirePermission permissions='lti.expense.detail'>
            <Button
              href={`/expense/detail/?expenseId=${props.row.original.id}`}
              variant='ghost'
              color='none'
              className='p-3 justify-start text-sm font-semibold w-full'
              onClick={closePopover}
            >
              <Icon icon='heroicons:eye' width={20} height={20} />
              Detail
            </Button>
          </RequirePermission>

          {showEditButton && (
            <RequirePermission permissions='lti.expense.update'>
              <Button
                href={`/expense/detail/edit/?expenseId=${props.row.original.id}`}
                variant='ghost'
                color='none'
                className='p-3 justify-start text-sm font-semibold w-full'
                onClick={closePopover}
              >
                <Icon icon='mdi:pencil-outline' width={20} height={20} />
                Edit
              </Button>
            </RequirePermission>
          )}

          {showRealizationButton && (
            <RequirePermission permissions='lti.expense.create.realization'>
              <Button
                href={`/expense/realization/?expenseId=${props.row.original.id}`}
                variant='ghost'
                color='none'
                className='p-3 justify-start text-sm font-semibold w-full'
                onClick={closePopover}
              >
                <Icon
                  icon='material-symbols:money-bag-rounded'
                  width={20}
                  height={20}
                  className='text-info'
                />
                Realisasi
              </Button>
            </RequirePermission>
          )}

          {showPaidOffButton && (
            <RequirePermission permissions='lti.expense.create.realization'>
              <Button
                onClick={() => {
                  paidOffClickHandler();
                  closePopover();
                }}
                variant='ghost'
                color='none'
                className='p-3 justify-start text-sm font-semibold w-full'
              >
                <Icon
                  icon='material-symbols:check-circle-outline'
                  width={20}
                  height={20}
                  className='text-success'
                />
                Tandai Lunas
              </Button>
            </RequirePermission>
          )}

          <RequirePermission permissions='lti.expense.delete'>
            <Button
              onClick={() => {
                deleteClickHandler();
                closePopover();
              }}
              variant='ghost'
              color='error'
              className='p-3 justify-start text-sm font-semibold w-full focus-visible:text-error-content hover:text-error-content'
            >
              <Icon icon='mdi:delete-outline' width={20} height={20} />
              Delete
            </Button>
          </RequirePermission>
        </div>
      </PopoverContent>
    </div>
  );
};

const ExpensesTable = () => {
  const {
    state: tableFilterState,
    updateFilter,
    setPage,
    setPageSize,
    toQueryString: getTableFilterQueryString,
    reset: resetFilter,
  } = useTableFilter<ExpenseTableFilters>({
    initial: {
      page: 1,
      pageSize: 10,
      search: '',
      sort_by: '',
      order_by: '',
      transactionDate: '',
      realizationDate: '',
      locationId: '',
      locationName: '',
      vendorId: '',
      vendorName: '',
      category: '',
      approvalStatus: '',
      realizationStatus: '',
      projectFlockId: '',
      projectFlockName: '',
      projectFlockKandangId: '',
      projectFlockKandangName: '',
      userId: '',
    },
    paramMap: {
      page: 'page',
      pageSize: 'limit',
      sort_by: 'sort_by',
      order_by: 'sort_order',
      transactionDate: 'transaction_date',
      realizationDate: 'realization_date',
      locationId: 'location_id',
      locationName: 'location_name',
      vendorId: 'vendor_id',
      vendorName: 'vendor_name',
      category: 'category',
      approvalStatus: 'approval_status',
      realizationStatus: 'realization_status',
      projectFlockId: 'project_flock_id',
      projectFlockName: 'project_flock_name',
      projectFlockKandangId: 'project_flock_kandang_id',
      projectFlockKandangName: 'project_flock_kandang_name',
      userId: 'user_id',
    },

    persist: true,
    storeName: 'expense-table',
  });

  const {
    data: expenses,
    isLoading,
    mutate: refreshExpenses,
  } = useSWR(
    `${ExpenseApi.basePath}${getTableFilterQueryString()}`,
    ExpenseApi.getAllFetcher
  );

  const deleteModal = useModal();
  const approveModal = useModal();
  const rejectModal = useModal();
  const paidOffModal = useModal();
  const bulkApproveFormModal = useModal();
  const exportProgressInputModal = useModal();

  // ===== FILTER MODAL STATE =====
  const filterModal = useModal();

  const [selectedExpense, setSelectedExpense] = useState<Expense | undefined>(
    undefined
  );
  const [isDeleteLoading, setIsDeleteLoading] = useState(false);
  const [isApproveLoading, setIsApproveLoading] = useState(false);
  const [isRejectLoading, setIsRejectLoading] = useState(false);
  const [isPaidOffLoading, setIsPaidOffLoading] = useState(false);
  const [isLoadingExportingToExcel, setIsLoadingExportingToExcel] =
    useState(false);
  const [isExportProgressLoading, setIsExportProgressLoading] = useState(false);
  const [, setApprovalNotes] = useState('');
  const [bulkApprovalStatus, setBulkApprovalStatus] =
    useState<OptionType<ApprovalStatusValue> | null>(null);
  const [bulkApprovalDate, setBulkApprovalDate] = useState('');
  const [bulkApprovalNotes, setBulkApprovalNotes] = useState('');
  const [exportProgressStartDate, setExportProgressStartDate] = useState('');
  const [exportProgressEndDate, setExportProgressEndDate] = useState('');

  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 [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
  const selectedRowIds = Object.keys(rowSelection).map((item) =>
    parseInt(item)
  );

  const isAllSelectedRowLatestApprovalOnHeadArea = useMemo(() => {
    return selectedRowIds.every((rowId) => {
      if (!isResponseSuccess(expenses)) return false;

      const expenseItem = expenses.data.find((item) => item.id === rowId);

      const isLatestApprovalRejected =
        expenseItem?.latest_approval.action === 'REJECTED';

      const isCurrentApprovalOnHeadArea =
        !isLatestApprovalRejected &&
        expenseItem?.latest_approval.step_number === 1;

      return isCurrentApprovalOnHeadArea;
    });
  }, [expenses, selectedRowIds]);

  const isAllSelectedRowLatestApprovalOnUnitVicePresident = useMemo(() => {
    return selectedRowIds.every((rowId) => {
      if (!isResponseSuccess(expenses)) return false;

      const expenseItem = expenses.data.find((item) => item.id === rowId);

      const isLatestApprovalRejected =
        expenseItem?.latest_approval.action === 'REJECTED';

      const isCurrentApprovalOnUnitVicePresident =
        !isLatestApprovalRejected &&
        expenseItem?.latest_approval.step_number === 2;

      return isCurrentApprovalOnUnitVicePresident;
    });
  }, [expenses, selectedRowIds]);

  const isAllSelectedRowLatestApprovalOnFinance = useMemo(() => {
    return selectedRowIds.every((rowId) => {
      if (!isResponseSuccess(expenses)) return false;

      const expenseItem = expenses.data.find((item) => item.id === rowId);

      const isLatestApprovalRejected =
        expenseItem?.latest_approval.action === 'REJECTED';

      const isCurrentApprovalOnFinance =
        !isLatestApprovalRejected &&
        expenseItem?.latest_approval.step_number === 3;

      return isCurrentApprovalOnFinance;
    });
  }, [expenses, selectedRowIds]);

  const expensesColumns: ColumnDef<Expense>[] = [
    {
      id: 'select',
      header: ({ table }) => (
        <div className='w-full flex flex-row justify-center'>
          <CheckboxInput
            name='allRow'
            checked={table.getIsAllRowsSelected()}
            indeterminate={table.getIsSomeRowsSelected()}
            onChange={table.getToggleAllRowsSelectedHandler()}
          />
        </div>
      ),
      cell: ({ row }) => {
        const isCheckboxDisabled =
          !row.getCanSelect() ||
          !row.original.latest_approval ||
          row.original.latest_approval.action === 'REJECTED';

        return (
          <div>
            <CheckboxInput
              name='row'
              checked={row.getIsSelected()}
              disabled={isCheckboxDisabled}
              indeterminate={row.getIsSomeSelected()}
              onChange={row.getToggleSelectedHandler()}
            />
          </div>
        );
      },
    },
    {
      accessorKey: 'reference_number',
      header: 'Nomor Referensi',
      cell: (props) => {
        return props.row.original.reference_number ?? '-';
      },
    },
    {
      accessorKey: 'transaction_date',
      header: 'Tanggal Pengajuan',
      cell: (props) =>
        props.row.original.transaction_date
          ? formatDate(props.row.original.transaction_date, 'DD MMM YYYY')
          : '-',
    },
    {
      accessorKey: 'realization_date',
      header: 'Tanggal Realisasi',
      cell: (props) =>
        props.row.original.realization_date
          ? formatDate(props.row.original.realization_date, 'DD MMM YYYY')
          : '-',
    },
    {
      accessorKey: 'location',
      header: 'Lokasi',
      cell: (props) => props.row.original.location?.name ?? '-',
    },
    {
      accessorKey: 'created_user',
      accessorFn: (row) => row.created_user.name ?? '-',
      header: 'Nama Pengaju',
    },
    {
      accessorKey: 'supplier',
      accessorFn: (row) => row.supplier.name ?? '-',
      header: 'Uraian',
    },
    {
      accessorKey: 'grand_total',
      header: 'Nominal',
      cell: (props) =>
        props.row.original.grand_total
          ? formatCurrency(props.row.original.grand_total)
          : '-',
    },
    {
      header: 'Status Pencairan',
      enableSorting: false,
      cell: (props) => (
        <RealizationStatusBadge approval={props.row.original.latest_approval} />
      ),
    },
    {
      header: 'Status BOP',
      enableSorting: false,
      cell: (props) => (
        <ExpenseStatusBadge approval={props.row.original.latest_approval} />
      ),
    },
    {
      accessorKey: 'is_paid',
      header: 'Status Lunas',
      cell: (props) => {
        return (
          <StatusBadge
            color={props.row.original.is_paid ? 'primary' : 'warning'}
            text={props.row.original.is_paid ? 'Lunas' : 'Belum Lunas'}
            className={{
              badge: 'w-fit whitespace-nowrap',
            }}
          />
        );
      },
    },
    {
      accessorKey: 'created_at',
      header: 'Tanggal Dibuat',
      cell: (props) =>
        props.row.original.created_at
          ? formatDate(props.row.original.created_at, 'DD MMM YYYY')
          : '-',
    },
    {
      header: 'Aksi',
      cell: (props) => {
        const currentPageSize = props.table.getPaginationRowModel().rows.length;
        const currentPageRows = props.table.getPaginationRowModel().flatRows;
        const currentRowRelativeIndex =
          currentPageRows.findIndex((r) => r.id === props.row.id) + 1;

        const isLast2Rows = currentRowRelativeIndex > currentPageSize - 2;

        const deleteClickHandler = () => {
          setSelectedExpense(props.row.original);
          deleteModal.openModal();
        };

        const paidOffClickHandler = () => {
          setSelectedExpense(props.row.original);
          paidOffModal.openModal();
        };

        return (
          <RowOptionsMenu
            popoverPosition={isLast2Rows ? 'top' : 'bottom'}
            props={props}
            deleteClickHandler={deleteClickHandler}
            paidOffClickHandler={paidOffClickHandler}
          />
        );
      },
    },
  ];

  const tableEnableRowSelectionHandler: (row: Row<Expense>) => boolean = (
    row
  ) => {
    if (!row.original.latest_approval) return false;

    return (
      row.original.latest_approval.action !== 'REJECTED' &&
      row.original.latest_approval.step_number !== 6
    );
  };

  const resetBulkApproveForm = useCallback(() => {
    setBulkApprovalStatus(null);
    setBulkApprovalDate('');
    setBulkApprovalNotes('');
  }, []);

  const openBulkApproveForm = useCallback(
    (presetStatus?: ApprovalStatusValue) => {
      resetBulkApproveForm();

      if (presetStatus) {
        const selectedStatus = approvalStatusOptions.find(
          (option) => option.value === presetStatus
        );

        if (selectedStatus) {
          setBulkApprovalStatus(selectedStatus);
        }
      }

      bulkApproveFormModal.openModal();
    },
    [bulkApproveFormModal, resetBulkApproveForm]
  );

  const bulkApproveClickHandler = () => {
    openBulkApproveForm();
  };

  const bulkApproveHeadAreaClickHandler = () => {
    openBulkApproveForm('HEAD_AREA');
  };

  const bulkApproveUnitVicePresidentClickHandler = () => {
    openBulkApproveForm('UNIT_VICE_PRESIDENT');
  };

  const bulkApproveFinanceClickHandler = () => {
    openBulkApproveForm('FINANCE');
  };

  const bulkRejectClickHandler = () => {
    setApprovalNotes('');
    rejectModal.openModal();
  };

  const bulkApprovalDateChangeHandler: ChangeEventHandler<HTMLInputElement> = (
    e
  ) => {
    setBulkApprovalDate(e.target.value);
  };

  const bulkApprovalNotesChangeHandler: ChangeEventHandler<
    HTMLTextAreaElement
  > = (e) => {
    setBulkApprovalNotes(e.target.value);
  };

  const resetExportProgressForm = useCallback(() => {
    setExportProgressStartDate('');
    setExportProgressEndDate('');
  }, []);

  const exportProgressStartDateChangeHandler: ChangeEventHandler<
    HTMLInputElement
  > = (e) => {
    setExportProgressStartDate(e.target.value);
  };

  const exportProgressEndDateChangeHandler: ChangeEventHandler<
    HTMLInputElement
  > = (e) => {
    setExportProgressEndDate(e.target.value);
  };

  const exportProgressInputToExcelClickHandler = () => {
    resetExportProgressForm();
    exportProgressInputModal.openModal();
  };

  const submitExportProgressInputHandler = async () => {
    if (!exportProgressStartDate || !exportProgressEndDate) {
      return;
    }

    setIsExportProgressLoading(true);

    try {
      await ExpenseApi.exportInputProgressToExcel(
        exportProgressStartDate,
        exportProgressEndDate
      );

      exportProgressInputModal.closeModal();
      resetExportProgressForm();
      toast.success('Ekspor berhasil');
    } catch (error) {
      toast.error(
        await getErrorMessage(error, 'Gagal mengekspor input progress')
      );
    } finally {
      setIsExportProgressLoading(false);
    }
  };

  const confirmationModalDeleteClickHandler = async () => {
    setIsDeleteLoading(true);

    const deleteResponse = await ExpenseApi.delete(
      selectedExpense?.id as number
    );

    if (isResponseSuccess(deleteResponse)) {
      refreshExpenses();
      deleteModal.closeModal();
      toast.success('Berhasil menghapus biaya operasional!');
    } else {
      deleteModal.closeModal();
      toast.error('Gagal menghapus biaya operasional!');
    }

    setIsDeleteLoading(false);
  };

  const confirmationModalPaidOffClickHandler = async () => {
    setIsPaidOffLoading(true);

    const paidOffResponse = await ExpenseApi.setExpensePaidOff(
      selectedExpense?.id as number
    );

    if (isResponseSuccess(paidOffResponse)) {
      refreshExpenses();
      paidOffModal.closeModal();
      toast.success('Berhasil menandai biaya operasional sebagai lunas!');
      refreshExpenses();
    } else {
      paidOffModal.closeModal();
      toast.error(
        'Gagal menandai biaya operasional sebagai lunas!: ' +
          paidOffResponse?.message
      );
    }

    setIsPaidOffLoading(false);
  };

  const confirmationModalApproveClickHandler = async (notes: string) => {
    setIsApproveLoading(true);

    let bulkApproveResponse: BaseApiResponse<Expense> | undefined = undefined;

    if (isAllSelectedRowLatestApprovalOnHeadArea) {
      bulkApproveResponse = await ExpenseApi.bulkApproveHeadArea(
        selectedRowIds,
        notes
      );
    } else if (isAllSelectedRowLatestApprovalOnUnitVicePresident) {
      bulkApproveResponse = await ExpenseApi.bulkApproveUnitVicePresident(
        selectedRowIds,
        notes
      );
    } else if (isAllSelectedRowLatestApprovalOnFinance) {
      bulkApproveResponse = await ExpenseApi.bulkApproveFinance(
        selectedRowIds,
        notes
      );
    }

    if (isResponseSuccess(bulkApproveResponse)) {
      refreshExpenses();
      approveModal.closeModal();

      toast.success(
        `Berhasil approve ${selectedRowIds.length} data biaya operasional!`
      );

      setApprovalNotes('');
      setRowSelection({});
    } else {
      approveModal.closeModal();

      toast.error(
        `Gagal approve ${selectedRowIds.length} data biaya operasional!`
      );
    }

    setIsApproveLoading(false);
  };

  const bulkApproveSubmitHandler = async () => {
    if (!bulkApprovalStatus) {
      return;
    }

    if (isApprovalDateRequired(bulkApprovalStatus.value) && !bulkApprovalDate) {
      toast.error('Tanggal realisasi wajib diisi.');
      return;
    }

    if (!bulkApprovalNotes.trim()) {
      toast.error('Catatan wajib diisi.');
      return;
    }

    setIsApproveLoading(true);

    const bulkApproveResponse = await ExpenseApi.bulkApprovals(
      selectedRowIds,
      bulkApprovalStatus.value,
      isApprovalDateRequired(bulkApprovalStatus.value) ? bulkApprovalDate : '',
      bulkApprovalNotes
    );

    if (isResponseSuccess(bulkApproveResponse)) {
      refreshExpenses();
      bulkApproveFormModal.closeModal();
      toast.success(
        `Berhasil approve ${selectedRowIds.length} data biaya operasional!`
      );
      resetBulkApproveForm();
      setRowSelection({});
    } else {
      toast.error(
        bulkApproveResponse?.message ??
          `Gagal approve ${selectedRowIds.length} data biaya operasional!`
      );
    }

    setIsApproveLoading(false);
  };

  const confirmationModalRejectClickHandler = async (notes: string) => {
    setIsRejectLoading(true);

    let bulkRejectResponse: BaseApiResponse<Expense> | undefined = undefined;

    if (isAllSelectedRowLatestApprovalOnHeadArea) {
      bulkRejectResponse = await ExpenseApi.bulkRejectHeadArea(
        selectedRowIds,
        notes
      );
    } else if (isAllSelectedRowLatestApprovalOnUnitVicePresident) {
      bulkRejectResponse = await ExpenseApi.bulkRejectUnitVicePresident(
        selectedRowIds,
        notes
      );
    } else if (isAllSelectedRowLatestApprovalOnFinance) {
      bulkRejectResponse = await ExpenseApi.bulkRejectFinance(
        selectedRowIds,
        notes
      );
    }

    if (isResponseSuccess(bulkRejectResponse)) {
      refreshExpenses();
      rejectModal.closeModal();

      toast.success(
        `Berhasil reject ${selectedRowIds.length} data biaya operasional!`
      );
      setApprovalNotes('');
      setRowSelection({});
    } else {
      rejectModal.closeModal();

      toast.error(
        `Gagal reject ${selectedRowIds.length} data biaya operasional!`
      );
    }

    setIsRejectLoading(false);
  };

  const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
    updateFilter('search', e.target.value, true);
  };

  // ===== FILTER MODAL HANDLERS =====
  const handleFilterModalOpen = () => {
    filterModal.openModal();
  };

  const handleFilterSubmit = (values: {
    transaction_date?: string | null;
    realization_date?: string | null;
    location?: { value: number; label: string } | null;
    vendor?: { value: number; label: string } | null;
    category?: OptionType<string> | null;
    approval_status?: OptionType<string> | null;
    realization_status?: OptionType<string> | null;
    project_flock?: OptionType<number> | null;
    project_flock_kandang?: OptionType<number> | null;
  }) => {
    updateFilter('transactionDate', values.transaction_date || '', true);
    updateFilter('realizationDate', values.realization_date || '', true);
    updateFilter(
      'locationId',
      values.location?.value ? String(values.location?.value) : '',
      true
    );
    updateFilter(
      'locationName',
      values.location?.label ? String(values.location?.label) : '',
      true
    );
    updateFilter(
      'vendorId',
      values.vendor?.value ? String(values.vendor?.value) : '',
      true
    );
    updateFilter(
      'vendorName',
      values.vendor?.label ? String(values.vendor?.label) : '',
      true
    );
    updateFilter('category', values.category?.value || '', true);
    updateFilter('approvalStatus', values.approval_status?.value || '', true);
    updateFilter(
      'realizationStatus',
      values.realization_status?.value || '',
      true
    );
    updateFilter(
      'projectFlockId',
      values.project_flock?.value ? String(values.project_flock.value) : '',
      true
    );
    updateFilter('projectFlockName', values.project_flock?.label || '', true);
    updateFilter(
      'projectFlockKandangId',
      values.project_flock_kandang?.value
        ? String(values.project_flock_kandang.value)
        : '',
      true
    );
    updateFilter(
      'projectFlockKandangName',
      values.project_flock_kandang?.label || '',
      true
    );
  };

  const handleFilterReset = () => {
    resetFilter();
  };

  const exportToExcel = useCallback(async () => {
    setIsLoadingExportingToExcel(true);

    try {
      await ExpenseApi.exportToExcel(getTableFilterQueryString());
    } catch (error) {
      toast.error(
        await getErrorMessage(error, 'Gagal mengekspor data pengeluaran')
      );
    } finally {
      setIsLoadingExportingToExcel(false);
    }
  }, [getTableFilterQueryString]);

  return (
    <>
      <div className='w-full'>
        <div className='w-full p-3 flex flex-row justify-between gap-3 flex-wrap border-b border-base-content/10'>
          {/* Action Buttons */}
          <div className='w-fit flex flex-col gap-3 flex-wrap'>
            <RequirePermission permissions='lti.expense.create'>
              <Button
                href='/expense/add'
                color='primary'
                className='px-3 py-2.5 w-fit text-sm text-base-100 rounded-xl shadow-button-soft'
              >
                <Icon icon='heroicons:plus' width={20} height={20} />
                Add Expense
              </Button>
            </RequirePermission>

            {selectedRowIds.length > 0 && (
              <div className='flex flex-row gap-3 flex-wrap'>
                <RequirePermission
                  permissions={[
                    'lti.expense.approve.head_area',
                    'lti.expense.approve.unit_vice_president',
                    'lti.expense.approve.finance',
                    'lti.expense.create.realization',
                  ]}
                >
                  <Button
                    variant='outline'
                    color='none'
                    onClick={bulkApproveClickHandler}
                    className='px-3 py-2.5 gap-1.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
                  >
                    <Icon
                      icon='lucide-lab:farm'
                      width={20}
                      height={20}
                      className='text-success'
                    />
                    Bulk Approve
                  </Button>
                </RequirePermission>

                <RequirePermission permissions='lti.expense.approve.head_area'>
                  <Button
                    variant='outline'
                    color='none'
                    onClick={bulkApproveHeadAreaClickHandler}
                    disabled={!isAllSelectedRowLatestApprovalOnHeadArea}
                    className='px-3 py-2.5 gap-1.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
                  >
                    <Icon
                      icon='lucide-lab:farm'
                      width={20}
                      height={20}
                      className='text-success'
                    />
                    Approve Head Area
                  </Button>
                </RequirePermission>

                <RequirePermission permissions='lti.expense.approve.unit_vice_president'>
                  <Button
                    variant='outline'
                    color='none'
                    onClick={bulkApproveUnitVicePresidentClickHandler}
                    disabled={
                      !isAllSelectedRowLatestApprovalOnUnitVicePresident
                    }
                    className='px-3 py-2.5 gap-1.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
                  >
                    <Icon
                      icon='tdesign:money'
                      width={20}
                      height={20}
                      className='text-success'
                    />
                    Approve Unit Vice President
                  </Button>
                </RequirePermission>

                <RequirePermission permissions='lti.expense.approve.finance'>
                  <Button
                    variant='outline'
                    color='none'
                    onClick={bulkApproveFinanceClickHandler}
                    disabled={!isAllSelectedRowLatestApprovalOnFinance}
                    className='px-3 py-2.5 gap-1.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
                  >
                    <Icon
                      icon='tdesign:money'
                      width={20}
                      height={20}
                      className='text-success'
                    />
                    Approve Finance
                  </Button>
                </RequirePermission>

                <RequirePermission
                  permissions={[
                    'lti.expense.approve.head_area',
                    'lti.expense.approve.unit_vice_president',
                    'lti.expense.approve.finance',
                  ]}
                >
                  <Button
                    variant='outline'
                    color='none'
                    onClick={bulkRejectClickHandler}
                    disabled={
                      !isAllSelectedRowLatestApprovalOnHeadArea &&
                      !isAllSelectedRowLatestApprovalOnUnitVicePresident &&
                      !isAllSelectedRowLatestApprovalOnFinance
                    }
                    className='px-3 py-2.5 gap-1.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
                  >
                    <Icon
                      icon='material-symbols:close'
                      width={20}
                      height={20}
                      className='text-error'
                    />
                    Reject
                  </Button>
                </RequirePermission>
              </div>
            )}
          </div>

          {/* Search and Filter */}
          <div className='flex flex-1 flex-row justify-start sm:justify-end items-start gap-3 flex-wrap'>
            <DebouncedTextInput
              name='search'
              placeholder='Search'
              value={tableFilterState.search ?? ''}
              onChange={searchChangeHandler}
              startAdornment={
                <Icon
                  icon='heroicons:magnifying-glass'
                  width={20}
                  height={20}
                />
              }
              className={{
                wrapper: 'w-full min-w-24 max-w-3xs',
                inputWrapper: 'rounded-xl! shadow-button-soft',
                input:
                  'placeholder:font-semibold placeholder:text-base-content/50',
              }}
            />

            <ButtonFilter
              values={tableFilterState}
              excludeFields={[
                'page',
                'pageSize',
                'search',
                'sort_by',
                'order_by',
                'userId',
                'locationName',
                'vendorName',
                'projectFlockName',
                'projectFlockKandangName',
              ]}
              onClick={handleFilterModalOpen}
              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'
                  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={exportToExcel}
                isLoading={isLoadingExportingToExcel}
                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>

              <Button
                variant='ghost'
                color='none'
                onClick={exportProgressInputToExcelClickHandler}
                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 Input Progress (Excel)
              </Button>
            </Dropdown>
          </div>
        </div>

        {/* Table Section */}
        <div className='flex flex-col mb-4'>
          {isLoading ? (
            <div className='w-full flex flex-row justify-center items-center p-4'>
              <span className='loading loading-spinner loading-xl' />
            </div>
          ) : !isResponseSuccess(expenses) || expenses.data?.length === 0 ? (
            <div className='p-3'>
              <ExpenseTableSkeleton
                columns={expensesColumns}
                icon={
                  <Icon
                    icon='heroicons:document-text'
                    className='text-white'
                    width={20}
                    height={20}
                  />
                }
              />
            </div>
          ) : (
            <Table<Expense>
              data={isResponseSuccess(expenses) ? expenses?.data : []}
              columns={expensesColumns}
              pageSize={tableFilterState.pageSize}
              page={isResponseSuccess(expenses) ? expenses?.meta?.page : 0}
              totalItems={
                isResponseSuccess(expenses) ? expenses?.meta?.total_results : 0
              }
              onPageChange={setPage}
              onPageSizeChange={setPageSize}
              isLoading={isLoading}
              sorting={sorting}
              setSorting={handleSortingChange}
              manualSorting
              rowSelection={rowSelection}
              setRowSelection={setRowSelection}
              enableRowSelection={tableEnableRowSelectionHandler}
              className={{
                containerClassName: cn('p-3 mb-0'),
                headerColumnClassName: 'text-nowrap',
              }}
            />
          )}
        </div>
      </div>

      <ConfirmationModal
        ref={deleteModal.ref}
        type='error'
        text='Apakah anda yakin ingin menghapus data biaya operasional ini?'
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: 'error',
          isLoading: isDeleteLoading,
          onClick: confirmationModalDeleteClickHandler,
        }}
      />

      <ConfirmationModal
        ref={paidOffModal.ref}
        type='success'
        text='Apakah anda yakin ingin menandai biaya operasional ini sebagai lunas?'
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: 'success',
          isLoading: isPaidOffLoading,
          onClick: confirmationModalPaidOffClickHandler,
        }}
      />

      <ConfirmationModalWithNotes
        ref={approveModal.ref}
        type='success'
        text='Apakah anda yakin ingin approve data biaya operasional ini?'
        secondaryButton={{
          text: 'Tidak',
          onClick: () => {
            setApprovalNotes('');
            approveModal.closeModal();
          },
        }}
        primaryButton={{
          text: 'Ya',
          color: 'success',
          isLoading: isApproveLoading,
          onClick: confirmationModalApproveClickHandler,
        }}
      />

      <ConfirmationModalWithNotes
        ref={rejectModal.ref}
        type='error'
        text='Apakah anda yakin ingin reject data biaya operasional ini?'
        secondaryButton={{
          text: 'Tidak',
          onClick: () => {
            setApprovalNotes('');
            rejectModal.closeModal();
          },
        }}
        primaryButton={{
          text: 'Ya',
          color: 'error',
          isLoading: isRejectLoading,
          onClick: confirmationModalRejectClickHandler,
        }}
      />

      <Modal
        ref={bulkApproveFormModal.ref}
        className={{
          modalBox: 'max-w-lg rounded-lg p-0',
        }}
        closeOnBackdrop
      >
        <div className='flex flex-col'>
          <div className='flex items-center justify-between border-b border-base-content/10 p-4'>
            <h4 className='text-sm font-semibold text-base-content'>
              Bulk Approve Expense
            </h4>
            <Button
              variant='ghost'
              color='none'
              onClick={() => {
                bulkApproveFormModal.closeModal();
                resetBulkApproveForm();
              }}
              className='p-1'
            >
              <Icon icon='mdi:close' width={20} height={20} />
            </Button>
          </div>

          <div className='flex flex-col gap-4 p-4'>
            <SelectInput
              label='Status Approval'
              options={approvalStatusOptions as OptionType[]}
              value={bulkApprovalStatus}
              onChange={(val) => {
                const nextValue = val as OptionType<ApprovalStatusValue> | null;
                setBulkApprovalStatus(nextValue);

                if (!isApprovalDateRequired(nextValue?.value)) {
                  setBulkApprovalDate('');
                }
              }}
              placeholder='Pilih status approval'
              isClearable
            />

            {isApprovalDateRequired(bulkApprovalStatus?.value) && (
              <DateInput
                name='bulk_approval_date'
                label='Tanggal Realisasi'
                value={bulkApprovalDate}
                onChange={bulkApprovalDateChangeHandler}
                isNestedModal
                required
              />
            )}

            <TextArea
              name='bulk_approval_notes'
              label='Catatan'
              value={bulkApprovalNotes}
              onChange={bulkApprovalNotesChangeHandler}
              placeholder='Masukkan catatan approval...'
              rows={4}
              required
            />
          </div>

          <div className='flex justify-end gap-3 border-t border-base-content/10 p-4'>
            <Button
              variant='outline'
              color='none'
              onClick={() => {
                bulkApproveFormModal.closeModal();
                resetBulkApproveForm();
              }}
              className='px-3 py-2.5'
            >
              Batal
            </Button>
            <Button
              color='success'
              onClick={bulkApproveSubmitHandler}
              isLoading={isApproveLoading}
              disabled={
                !bulkApprovalStatus ||
                !bulkApprovalNotes.trim() ||
                (isApprovalDateRequired(bulkApprovalStatus.value) &&
                  !bulkApprovalDate)
              }
              className='px-3 py-2.5'
            >
              Submit
            </Button>
          </div>
        </div>
      </Modal>

      <Modal
        ref={exportProgressInputModal.ref}
        className={{
          modalBox: 'max-w-lg rounded-lg p-0',
        }}
        closeOnBackdrop
      >
        <div className='flex flex-col'>
          <div className='flex items-center justify-between border-b border-base-content/10 p-4'>
            <h4 className='text-sm font-semibold text-base-content'>
              Ekspor Input Progress
            </h4>
            <Button
              variant='ghost'
              color='none'
              onClick={() => {
                exportProgressInputModal.closeModal();
                resetExportProgressForm();
              }}
              className='p-1'
            >
              <Icon icon='mdi:close' width={20} height={20} />
            </Button>
          </div>

          <div className='flex flex-col gap-4 p-4'>
            <DateInput
              name='export_progress_start_date'
              label='Tanggal Mulai'
              value={exportProgressStartDate}
              onChange={exportProgressStartDateChangeHandler}
              isNestedModal
              required
            />

            <DateInput
              name='export_progress_end_date'
              label='Tanggal Selesai'
              value={exportProgressEndDate}
              onChange={exportProgressEndDateChangeHandler}
              isNestedModal
              required
            />
          </div>

          <div className='flex justify-end gap-3 border-t border-base-content/10 p-4'>
            <Button
              variant='outline'
              color='none'
              onClick={() => {
                exportProgressInputModal.closeModal();
                resetExportProgressForm();
              }}
              className='px-3 py-2.5'
            >
              Batal
            </Button>
            <Button
              color='success'
              onClick={submitExportProgressInputHandler}
              isLoading={isExportProgressLoading}
              disabled={!exportProgressStartDate || !exportProgressEndDate}
              className='px-3 py-2.5'
            >
              Submit
            </Button>
          </div>
        </div>
      </Modal>

      <ExpensesFilterModal
        ref={filterModal.ref}
        onSubmit={handleFilterSubmit}
        onReset={handleFilterReset}
        initialValues={{
          location:
            tableFilterState.locationId && tableFilterState.locationName
              ? {
                  value: Number(tableFilterState.locationId),
                  label: tableFilterState.locationName,
                }
              : null,
          vendor:
            tableFilterState.vendorId && tableFilterState.vendorName
              ? {
                  value: Number(tableFilterState.vendorId),
                  label: tableFilterState.vendorName,
                }
              : null,
          realization_date: tableFilterState.realizationDate,
          transaction_date: tableFilterState.transactionDate,
          category: tableFilterState.category
            ? {
                value: tableFilterState.category,
                label: tableFilterState.category,
              }
            : null,
          approval_status: tableFilterState.approvalStatus
            ? approvalStatusOptions.find(
                (item) => item.value === tableFilterState.approvalStatus
              ) || null
            : null,
          realization_status: tableFilterState.realizationStatus
            ? [
                { value: 'NOT_REALIZED', label: 'Belum Realisasi' },
                { value: 'REALIZED', label: 'Sudah Realisasi' },
                { value: 'REJECTED', label: 'Ditolak' },
              ].find(
                (item) => item.value === tableFilterState.realizationStatus
              ) || null
            : null,
          project_flock:
            tableFilterState.projectFlockId && tableFilterState.projectFlockName
              ? {
                  value: Number(tableFilterState.projectFlockId),
                  label: tableFilterState.projectFlockName,
                }
              : null,
          project_flock_kandang:
            tableFilterState.projectFlockKandangId &&
            tableFilterState.projectFlockKandangName
              ? {
                  value: Number(tableFilterState.projectFlockKandangId),
                  label: tableFilterState.projectFlockKandangName,
                }
              : null,
        }}
      />
    </>
  );
};

export default ExpensesTable;
