'use client';

import Badge from '@/components/Badge';
import Button from '@/components/Button';
import SelectInput, { OptionType } from '@/components/input/SelectInput';
import Table from '@/components/Table';
import RequirePermission from '@/components/helper/RequirePermission';
import { ROWS_OPTIONS } from '@/config/constant';
import { isResponseSuccess } from '@/lib/api-helper';
import { cn } from '@/lib/helper';
import { InventoryAdjustmentApi } from '@/services/api/inventory';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { InventoryAdjustment } from '@/types/api/inventory/adjustment';
import { Icon } from '@iconify/react';
import { ColumnDef, ColumnSort, SortingState } from '@tanstack/react-table';
import { useCallback, useEffect, useState } from 'react';
import useSWR from 'swr';
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';

const InventoryAdjustmentTable = () => {
  const {
    state: tableFilterState,
    updateFilter,
    setPage,
    setPageSize,
    toQueryString: getTableFilterQueryString,
  } = useTableFilter({
    initial: {
      search: '',
      productCategorySort: '',
      productSort: '',
      warehouseSort: '',
      stockSort: '',
    },
    paramMap: {
      page: 'page',
      pageSize: 'limit',
      productCategorySort: 'sort_product_category',
      productSort: 'sort_product',
      warehouseSort: 'sort_warehouse',
      stockSort: 'sort_stock',
    },
  });

  // Fetch Data
  const { data: inventoryAdjustments, isLoading } = useSWR(
    `${InventoryAdjustmentApi.basePath}${getTableFilterQueryString()}`,
    InventoryAdjustmentApi.getAllFetcher
  );

  // State
  const [sorting, setSorting] = useState<SortingState>([]);

  // Columns
  const inventoryAdjustmentsColumns: ColumnDef<InventoryAdjustment>[] = [
    {
      header: '#',
      cell: (props) =>
        tableFilterState.pageSize * (tableFilterState.page - 1) +
        props.row.index +
        1,
    },
    {
      id: 'product_name',
      header: 'Nama Produk',
      accessorFn: (row) => row.product_warehouse?.product?.name ?? '-',
    },
    {
      id: 'warehouse_name',
      header: 'Gudang',
      accessorFn: (row) => row.product_warehouse?.warehouse?.name ?? '-',
    },
    {
      id: 'created_at',
      header: 'Tanggal',
      accessorFn: (row) =>
        new Date(row.created_at).toLocaleDateString('id-ID', {
          day: '2-digit',
          month: 'short',
          year: 'numeric',
        }),
    },
    {
      id: 'quantity',
      header: 'Kuantitas',
      accessorFn: (row) => formatNumber(String(row.increase + row.decrease)),
    },
    {
      id: 'transaction_type',
      header: 'Tipe Transaksi',
      accessorFn: (row) => {
        if (row.increase > 0) return 'Peningkatan';
        if (row.decrease > 0) return 'Penurunan';
        return '-';
      },
      cell: (props) => {
        const type = props.row.original.increase;
        const label = type > 0 ? 'Peningkatan' : type <= 0 ? 'Penurunan' : '-';

        return (
          <Badge variant='soft' color={type > 0 ? 'success' : 'error'}>
            {label}
          </Badge>
        );
      },
    },
    {
      id: 'created_by',
      header: 'Oleh',
      accessorFn: (row) => row.created_user?.name ?? '-',
    },
  ];

  // Handler
  const pageSizeChangeHandler = (val: OptionType | OptionType[] | null) => {
    const newVal = val as OptionType;
    setPageSize(newVal.value as number);
  };

  const updateSortingFilter = useCallback(
    (
      sortName: Exclude<keyof typeof tableFilterState, 'page' | 'pageSize'>,
      sortFilter: ColumnSort | undefined
    ) => {
      if (!sortFilter) {
        updateFilter(sortName, '');
      } else {
        updateFilter(sortName, sortFilter.desc ? 'desc' : 'asc');
      }
    },
    [updateFilter]
  );

  // Effect
  useEffect(() => {
    const productCategorySortFilter = sorting.find(
      (sortItem) => sortItem.id === 'productCategory'
    );
    const productSortFilter = sorting.find(
      (sortItem) => sortItem.id === 'product'
    );
    const warehouseSortFilter = sorting.find(
      (sortItem) => sortItem.id === 'warehouse'
    );
    const stockSortFilter = sorting.find((sortItem) => sortItem.id === 'stock');

    updateSortingFilter('productCategorySort', productCategorySortFilter);
    updateSortingFilter('productSort', productSortFilter);
    updateSortingFilter('warehouseSort', warehouseSortFilter);
    updateSortingFilter('stockSort', stockSortFilter);
  }, [sorting, updateSortingFilter]);

  // Utils Function
  const formatNumber = (value: string) => {
    const numericValue = value.replace(/[^0-9.]/g, '');
    const [integer, decimal] = numericValue.split('.');
    const formattedInteger = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    return decimal ? `${formattedInteger}.${decimal}` : formattedInteger;
  };

  // Render
  return (
    <>
      <div className='w-full p-0 sm:p-4'>
        <div className='flex flex-col gap-2 mb-4'>
          <div className='w-full flex flex-col sm:flex-row justify-between items-end sm:items-center gap-2'>
            <div className='w-full flex flex-row'>
              <RequirePermission permissions='lti.inventory.create'>
                <Button
                  href='/inventory/adjustment/add'
                  variant='outline'
                  color='primary'
                  className='w-full sm:w-fit'
                >
                  <Icon icon='ic:round-plus' width={24} height={24} />
                  Tambah
                </Button>
              </RequirePermission>
            </div>

            <div className='flex flex-row justify-end'>
              <SelectInput
                label='Baris'
                options={ROWS_OPTIONS}
                value={{
                  label: String(tableFilterState.pageSize),
                  value: tableFilterState.pageSize,
                }}
                onChange={pageSizeChangeHandler}
                className={{ wrapper: 'min-w-28' }}
              />
            </div>
          </div>

          <Table<InventoryAdjustment>
            data={
              isResponseSuccess(inventoryAdjustments)
                ? inventoryAdjustments?.data
                : []
            }
            columns={inventoryAdjustmentsColumns}
            pageSize={tableFilterState.pageSize}
            page={
              isResponseSuccess(inventoryAdjustments)
                ? inventoryAdjustments?.meta?.page
                : 0
            }
            totalItems={
              isResponseSuccess(inventoryAdjustments)
                ? inventoryAdjustments?.meta?.total_results
                : 0
            }
            onPageChange={setPage}
            isLoading={isLoading}
            sorting={sorting}
            setSorting={setSorting}
            className={{
              containerClassName: cn({
                'mb-20':
                  isResponseSuccess(inventoryAdjustments) &&
                  inventoryAdjustments?.data?.length === 0,
              }),
              tableWrapperClassName: 'overflow-x-auto min-h-full!',
              tableClassName: 'font-inter w-full table-auto min-h-full!',
              headerRowClassName: 'border-b border-b-gray-200',
              headerColumnClassName:
                'px-6 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end',
              bodyRowClassName: 'border-b border-b-gray-200',
              bodyColumnClassName:
                'px-6 py-3 last:flex last:flex-row last:justify-end',
            }}
          />
        </div>
      </div>
    </>
  );
};

export default InventoryAdjustmentTable;
