'use client';

import React, {
  useState,
  useCallback,
  useEffect,
  useMemo,
  useRef,
} from 'react';
import useSWR from 'swr';
import { Icon } from '@iconify/react';
import Button from '@/components/Button';
import Dropdown from '@/components/dropdown/Dropdown';
import SelectInput, { useSelect } from '@/components/input/SelectInput';
import DateInput from '@/components/input/DateInput';
import { useFormik } from 'formik';
import {
  ReportExpenseFilterSchema,
  type ReportExpenseFilterValues,
} from '@/components/pages/report/expense/filter/ReportExpenseFilter';
import ExpenseStatusBadge from '@/components/pages/expense/ExpenseStatusBadge';
import RealizationStatusBadge from '@/components/pages/expense/RealizationStatusBadge';
import Table from '@/components/Table';
import { formatCurrency, formatDate } from '@/lib/helper';
import { ReportExpense } from '@/types/api/report/report-expense';
import { ReportExpenseApi } from '@/services/api/report/expense-report';
import { getErrorMessage, isResponseSuccess } from '@/lib/api-helper';
import { useTabActionsStore } from '@/stores/tab-actions/tab-actions.store';
import Modal, { useModal } from '@/components/Modal';
import Pagination from '@/components/Pagination';
import ReportExpenseSkeleton from '@/components/pages/report/expense/skeleton/ReportExpenseSkeleton';
import { generateReportExpensePDF } from '../export/ReportExpenseExportPDF';
import { generateReportExpenseExcel } from '../export/ReportExpenseExportXLSX';
import toast from 'react-hot-toast';
import {
  LocationApi,
  NonstockApi,
  SupplierApi,
} from '@/services/api/master-data';
import { Supplier } from '@/types/api/master-data/supplier';
import { Nonstock } from '@/types/api/master-data/nonstock';
import { ColumnDef, SortingState, Updater } from '@tanstack/react-table';
import { httpClient } from '@/services/http/client';
import { BaseApiResponse } from '@/types/api/api-general';
import ButtonFilter from '@/components/helper/ButtonFilter';
import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang';
import { ProjectFlockKandangApi } from '@/services/api/production/project-flock-kandang';

interface ReportExpenseTabProps {
  tabId: string;
}

interface FilterParams {
  location_id?: string;
  supplier_id?: string;
  kandang_id?: string;
  nonstock_id?: string;
  realization_date?: string;
  category?: string;
  search?: string;
}

const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => {
  // ===== STATE MANAGEMENT =====
  const [isPdfExportLoading, setIsPdfExportLoading] = useState(false);
  const [isExcelExportLoading, setIsExcelExportLoading] = useState(false);
  const isAnyExportLoading = isPdfExportLoading || isExcelExportLoading;

  // ===== SUBMISSION STATE =====
  const [filterParams, setFilterParams] = useState<FilterParams>({});

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

  // ===== SORTING STATE =====
  const [sortBy, setSortBy] = useState('');
  const [orderBy, setOrderBy] = useState('');

  const sorting: SortingState = sortBy
    ? [{ id: sortBy, desc: orderBy === 'desc' }]
    : [];

  const handleSortingChange = (updater: Updater<SortingState>) => {
    const next = typeof updater === 'function' ? updater(sorting) : updater;
    if (next.length > 0) {
      setSortBy(next[0].id);
      setOrderBy(next[0].desc ? 'desc' : 'asc');
    } else {
      setSortBy('');
      setOrderBy('');
    }
  };

  const handleFilterModalOpenRef = useRef(() => {});

  const filterModal = useModal();

  const categoryOptions = useMemo(
    () => [
      { value: 'BOP', label: 'BOP' },
      { value: 'NON-BOP', label: 'Non BOP' },
    ],
    []
  );

  // ===== FORMIK SETUP =====
  const formik = useFormik<ReportExpenseFilterValues>({
    initialValues: {
      location_id: null,
      supplier_id: null,
      kandang_id: null,
      nonstock_id: null,
      realization_date: null,
      category: null,
    },
    validationSchema: ReportExpenseFilterSchema,
    onSubmit: (values) => {
      setFilterParams({
        location_id: values.location_id?.value
          ? String(values.location_id.value)
          : undefined,
        supplier_id: values.supplier_id?.value
          ? String(values.supplier_id.value)
          : undefined,
        kandang_id: values.kandang_id?.value
          ? String(values.kandang_id.value)
          : undefined,
        nonstock_id: values.nonstock_id?.value
          ? String(values.nonstock_id.value)
          : undefined,
        realization_date: values.realization_date || undefined,
        category: values.category?.value
          ? String(values.category.value)
          : undefined,
      });
      filterModal.closeModal();
      setPage(1);
    },
    onReset: () => {
      setFilterParams({});
      setPage(1);
      filterModal.closeModal();
    },
  });

  handleFilterModalOpenRef.current = () => {
    const restoredLocation = filterParams.location_id
      ? locationOptions.find(
          (opt) => String(opt.value) === filterParams.location_id
        ) || {
          value: filterParams.location_id,
          label: filterParams.location_id,
        }
      : null;
    const restoredSupplier = filterParams.supplier_id
      ? supplierOptions.find(
          (opt) => String(opt.value) === filterParams.supplier_id
        ) || {
          value: filterParams.supplier_id,
          label: filterParams.supplier_id,
        }
      : null;
    const restoredKandang = filterParams.kandang_id
      ? projectFlockKandangOptions.find(
          (opt) => String(opt.value) === filterParams.kandang_id
        ) || { value: filterParams.kandang_id, label: filterParams.kandang_id }
      : null;
    const restoredNonstock = filterParams.nonstock_id
      ? nonstockOptions.find(
          (opt) => String(opt.value) === filterParams.nonstock_id
        ) || {
          value: filterParams.nonstock_id,
          label: filterParams.nonstock_id,
        }
      : null;
    const restoredCategory = filterParams.category
      ? categoryOptions.find((opt) => opt.value === filterParams.category) ||
        null
      : null;

    formik.setValues({
      location_id: restoredLocation,
      supplier_id: restoredSupplier,
      kandang_id: restoredKandang,
      nonstock_id: restoredNonstock,
      realization_date: filterParams.realization_date || null,
      category: restoredCategory,
    });
    filterModal.openModal();
  };

  // ===== OPTIONS =====
  const {
    setInputValue: setLocationInputValue,
    options: locationOptions,
    isLoadingOptions: isLoadingLocations,
    loadMore: loadMoreLocations,
  } = useSelect<Location>(LocationApi.basePath, 'id', 'name', 'search');

  const {
    setInputValue: setSupplierInputValue,
    options: supplierOptions,
    isLoadingOptions: isLoadingSuppliers,
    loadMore: loadMoreSuppliers,
  } = useSelect<Supplier>(SupplierApi.basePath, 'id', 'name', 'search');

  const {
    setInputValue: setProjectFlockKandangInputValue,
    options: projectFlockKandangOptions,
    isLoadingOptions: isLoadingProjectFlockKandangs,
    loadMore: loadMoreProjectFlockKandangs,
  } = useSelect<ProjectFlockKandang>(
    ProjectFlockKandangApi.basePath,
    'id',
    'name_with_period',
    'search',
    formik.values.location_id?.value
      ? { location_id: String(formik.values.location_id.value) }
      : undefined
  );

  const {
    setInputValue: setNonstockInputValue,
    options: nonstockOptions,
    isLoadingOptions: isLoadingNonstocks,
    loadMore: loadMoreNonstocks,
  } = useSelect<Nonstock>(NonstockApi.basePath, 'id', 'name', 'search');

  // ===== FILTER VALUES =====
  const locationValue = useMemo(
    () => formik.values.location_id,
    [formik.values.location_id]
  );
  const supplierValue = useMemo(
    () => formik.values.supplier_id,
    [formik.values.supplier_id]
  );
  const kandangValue = useMemo(
    () => formik.values.kandang_id,
    [formik.values.kandang_id]
  );
  const nonstockValue = useMemo(
    () => formik.values.nonstock_id,
    [formik.values.nonstock_id]
  );
  const categoryValue = useMemo(
    () => formik.values.category,
    [formik.values.category]
  );

  const buildReportExpenseQueryString = useCallback(
    (extraParams?: Record<string, string>) => {
      const params = new URLSearchParams();

      if (filterParams.location_id) {
        params.append('location_id', filterParams.location_id);
      }
      if (filterParams.supplier_id) {
        params.append('supplier_id', filterParams.supplier_id);
      }
      if (filterParams.kandang_id) {
        params.append('project_flock_kandang_id', filterParams.kandang_id);
      }
      if (filterParams.nonstock_id) {
        params.append('nonstock_id', filterParams.nonstock_id);
      }
      if (filterParams.realization_date) {
        params.append('realization_date', filterParams.realization_date);
      }
      if (filterParams.category) {
        params.append('category', filterParams.category);
      }
      if (sortBy) params.append('sort_by', sortBy);
      if (orderBy) params.append('sort_order', orderBy);

      Object.entries(extraParams ?? {}).forEach(([key, value]) => {
        params.set(key, value);
      });

      return params.toString();
    },
    [filterParams, sortBy, orderBy]
  );

  // ===== DATA FETCHING =====
  const { data: reportExpenseResponse, isLoading } = useSWR(
    () => {
      const queryString = buildReportExpenseQueryString({
        page: String(page),
        limit: String(pageSize),
      });

      return [`${ReportExpenseApi.basePath}?${queryString}`];
    },
    ([url]: string[]) => httpClient<BaseApiResponse<ReportExpense[]>>(url)
  );

  const data: ReportExpense[] = useMemo(
    () =>
      isResponseSuccess(reportExpenseResponse)
        ? (reportExpenseResponse.data as ReportExpense[]) || []
        : [],
    [reportExpenseResponse]
  );

  const meta = useMemo(
    () =>
      isResponseSuccess(reportExpenseResponse) && reportExpenseResponse.meta
        ? reportExpenseResponse.meta
        : null,
    [reportExpenseResponse]
  );

  // ===== EXPORT DATA FETCHER =====
  const reportExpenseExport = useCallback(async (): Promise<
    ReportExpense[] | null
  > => {
    const queryString = buildReportExpenseQueryString({
      page: '1',
      limit: '100',
    });

    const response = await httpClient<BaseApiResponse<ReportExpense[]>>(
      `${ReportExpenseApi.basePath}?${queryString}`
    );

    return isResponseSuccess(response) ? response.data : null;
  }, [buildReportExpenseQueryString]);

  // ===== EXPORT HANDLERS =====
  const handleExportExcel = useCallback(async () => {
    setIsExcelExportLoading(true);
    try {
      await ReportExpenseApi.exportToExcel(buildReportExpenseQueryString());
    } catch (error) {
      toast.error(
        await getErrorMessage(error, 'Gagal mengekspor data pengeluaran')
      );
    } finally {
      setIsExcelExportLoading(false);
    }
  }, [buildReportExpenseQueryString]);

  const handleExportPDF = useCallback(async () => {
    setIsPdfExportLoading(true);
    try {
      const allData = await reportExpenseExport();
      if (!allData || allData.length === 0) {
        toast.error('Tidak ada data untuk diekspor.');
        return;
      }

      await generateReportExpensePDF(allData);

      toast.success('PDF berhasil dibuat dan diunduh.');
    } catch {
      toast.error('Gagal membuat PDF. Silakan coba lagi.');
    } finally {
      setIsPdfExportLoading(false);
    }
  }, [reportExpenseExport]);

  // ===== TAB ACTIONS COMPONENT =====
  const TabActions = useMemo(() => {
    return function TabActionsComponent() {
      const setTabActions = useTabActionsStore((state) => state.setTabActions);
      const clearTabActions = useTabActionsStore(
        (state) => state.clearTabActions
      );

      useEffect(() => {
        setTabActions(
          tabId,
          <div className='flex flex-row gap-3'>
            <ButtonFilter
              values={filterParams}
              onClick={() => handleFilterModalOpenRef.current()}
              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={isAnyExportLoading}
                  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} />
                Export to Excel
              </Button>
              <Button
                variant='ghost'
                color='none'
                onClick={handleExportPDF}
                isLoading={isPdfExportLoading}
                className='w-full p-3 justify-start text-sm text-base-content/50 font-semibold text-nowrap'
              >
                <Icon icon='heroicons:document' width={20} height={20} />
                Export to PDF
              </Button>
            </Dropdown>
          </div>
        );
      }, [setTabActions]);

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

      return null;
    };
  }, [
    tabId,
    filterParams,
    isAnyExportLoading,
    handleExportExcel,
    handleExportPDF,
    isExcelExportLoading,
    isPdfExportLoading,
  ]);

  const TabActionsElement = useMemo(() => <TabActions />, [TabActions]);

  // ===== TABLE COLUMNS DEFINITION =====
  const columns = useMemo((): ColumnDef<ReportExpense>[] => {
    return [
      {
        header: 'No',
        enableSorting: false,
        cell: (props) => (page - 1) * pageSize + props.row.index + 1,
      },
      {
        header: 'No. PO',
        accessorKey: 'po_number',
        enableSorting: true,
      },
      {
        header: 'No. Referensi',
        accessorKey: 'reference_number',
        enableSorting: true,
      },
      {
        header: 'Tanggal Realisasi',
        accessorKey: 'realization_date',
        enableSorting: true,
        cell: ({ row }) => {
          return formatDate(row.original?.realization_date, 'DD MMM, YYYY');
        },
      },
      {
        header: 'Tanggal Transaksi',
        accessorKey: 'transaction_date',
        enableSorting: true,
        cell: ({ row }) => {
          return formatDate(row.original?.transaction_date, 'DD MMM, YYYY');
        },
      },
      {
        header: 'Kategori',
        accessorKey: 'category',
        enableSorting: true,
      },
      {
        header: 'Produk',
        accessorKey: 'product',
        enableSorting: true,
        accessorFn: (row) => row.pengajuan?.nonstock?.name,
      },
      {
        header: 'Supplier',
        accessorKey: 'supplier',
        enableSorting: true,
        accessorFn: (row) => row.supplier?.name,
      },
      {
        header: 'Lokasi',
        accessorKey: 'location',
        enableSorting: true,
        accessorFn: (row) => row.kandang?.location?.name,
      },
      {
        header: 'Kandang',
        accessorKey: 'kandang',
        enableSorting: true,
        accessorFn: (row) => row.kandang?.name,
      },
      {
        header: 'Pengajuan',
        columns: [
          {
            header: 'Qty',
            accessorKey: 'qty_pengajuan',
            cell: ({ row }) =>
              row.original.pengajuan?.qty?.toLocaleString('id-ID') || '0',
          },
          {
            header: 'Harga',
            accessorKey: 'price_pengajuan',
            cell: ({ row }) =>
              formatCurrency(row.original.pengajuan?.price || 0),
          },
          {
            header: 'Total',
            accessorKey: 'total_pengajuan',
            cell: ({ row }) => {
              const total =
                (row.original.pengajuan?.qty || 0) *
                (row.original.pengajuan?.price || 0);
              return formatCurrency(total);
            },
          },
        ],
      },
      {
        header: 'Realisasi',
        columns: [
          {
            header: 'Qty',
            accessorKey: 'qty_realisasi',
            cell: ({ row }) =>
              row.original.realisasi?.qty?.toLocaleString('id-ID') || '0',
          },
          {
            header: 'Harga',
            accessorKey: 'price_realisasi',
            cell: ({ row }) =>
              formatCurrency(row.original.realisasi?.price || 0),
          },
          {
            header: 'Total',
            accessorKey: 'total_realisasi',
            cell: ({ row }) => {
              const total =
                (row.original.realisasi?.qty || 0) *
                (row.original.realisasi?.price || 0);
              return formatCurrency(total);
            },
          },
        ],
      },
      {
        id: 'realization_status',
        header: 'Status Pencairan',
        cell: (props) => (
          <RealizationStatusBadge
            approval={props.row.original?.latest_approval}
          />
        ),
      },
      {
        id: 'bop_status',
        header: 'Status BOP',
        cell: (props) => (
          <ExpenseStatusBadge approval={props.row.original?.latest_approval} />
        ),
      },
    ];
  }, [page, pageSize]);

  return (
    <>
      {TabActionsElement}
      <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 && (!data || data.length === 0) && (
          <ReportExpenseSkeleton
            columns={columns}
            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 && data.length > 0 && (
          <>
            <Table
              data={data}
              columns={columns}
              pageSize={pageSize}
              page={meta?.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',
                paginationClassName: 'hidden',
              }}
            />
            {meta && (
              <div className='max-w-sm ml-auto'>
                <Pagination
                  totalItems={meta.total_results || 0}
                  itemsPerPage={meta.limit || 0}
                  currentPage={meta.page || 0}
                  onPrevPage={() =>
                    setPage((currPage) =>
                      currPage > 1 ? currPage - 1 : currPage
                    )
                  }
                  onNextPage={() =>
                    setPage((currPage) =>
                      meta && meta.total_pages && currPage < meta.total_pages
                        ? currPage + 1
                        : currPage
                    )
                  }
                  onPageChange={(pageNumber) => setPage(pageNumber)}
                  rowOptions={[10, 20, 50, 100]}
                  onRowChange={setPageSize}
                />
              </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={formik.handleReset}>
          {/* Modal Body */}
          <div className='p-4 flex flex-col gap-3'>
            <SelectInput
              label='Lokasi'
              placeholder='Pilih Lokasi'
              options={locationOptions}
              isLoading={isLoadingLocations}
              value={locationValue}
              onChange={(val) => {
                formik.setFieldValue('location_id', val);
                formik.setFieldValue('kandang_id', null);
              }}
              onInputChange={setLocationInputValue}
              onMenuScrollToBottom={loadMoreLocations}
              isClearable
              className={{ wrapper: 'w-full' }}
            />

            <SelectInput
              label='Kandang'
              placeholder='Pilih Kandang'
              options={projectFlockKandangOptions}
              isLoading={isLoadingProjectFlockKandangs}
              value={kandangValue}
              onChange={(val) => {
                formik.setFieldValue('kandang_id', val);
              }}
              onInputChange={setProjectFlockKandangInputValue}
              onMenuScrollToBottom={loadMoreProjectFlockKandangs}
              isClearable
              isDisabled={!formik.values.location_id}
              className={{ wrapper: 'w-full' }}
            />

            <SelectInput
              label='Supplier'
              placeholder='Pilih Supplier'
              options={supplierOptions}
              isLoading={isLoadingSuppliers}
              value={supplierValue}
              onChange={(val) => {
                formik.setFieldValue('supplier_id', val);
              }}
              onInputChange={setSupplierInputValue}
              onMenuScrollToBottom={loadMoreSuppliers}
              isClearable
              className={{ wrapper: 'w-full' }}
            />

            <SelectInput
              label='Produk'
              placeholder='Pilih Produk'
              options={nonstockOptions}
              isLoading={isLoadingNonstocks}
              value={nonstockValue}
              onChange={(val) => {
                formik.setFieldValue('nonstock_id', val);
              }}
              onInputChange={setNonstockInputValue}
              onMenuScrollToBottom={loadMoreNonstocks}
              isClearable
              className={{ wrapper: 'w-full' }}
            />

            <SelectInput
              label='Kategori'
              placeholder='Pilih Kategori'
              options={categoryOptions}
              value={categoryValue}
              onChange={(val) => {
                formik.setFieldValue('category', val);
              }}
              isClearable
              className={{ wrapper: 'w-full' }}
            />

            <DateInput
              label='Tanggal Realisasi'
              name='realization_date'
              value={formik.values.realization_date || ''}
              onChange={(e) => {
                formik.setFieldValue(
                  'realization_date',
                  e.target.value || null
                );
              }}
              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'
            >
              Apply Filter
            </Button>
          </div>
        </form>
      </Modal>
    </>
  );
};

export default ReportExpenseTab;
