'use client';

import { ChangeEventHandler, useEffect, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';

import { Icon } from '@iconify/react';
import Table from '@/components/Table';
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
import Button from '@/components/Button';
import SelectInput, {
  OptionType,
  useSelect,
} from '@/components/input/SelectInput';
import RowDropdownOptions from '@/components/table/RowDropdownOptions';
import RowCollapseOptions from '@/components/table/RowCollapseOptions';
import RowOptionsMenuWrapper from '@/components/table/RowOptionsMenuWrapper';
import RequirePermission from '@/components/helper/RequirePermission';

import { cn, formatCurrency, formatDate } from '@/lib/helper';
import { isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { LocationApi } from '@/services/api/master-data';
import { Location } from '@/types/api/master-data/location';
import { ClosingApi } from '@/services/api/closing';
import { Closing } from '@/types/api/closing';

const PROJECT_STATUS_OPTIONS = [
  {
    value: 1,
    label: 'Pengajuan',
  },
  {
    value: 2,
    label: 'Aktif',
  },
];

const RowOptionsMenu = ({
  type = 'dropdown',
  props,
}: {
  type: 'dropdown' | 'collapse';
  props: CellContext<Closing, unknown>;
}) => {
  return (
    <RowOptionsMenuWrapper type={type}>
      <div className='w-full max-h-40 overflow-auto flex flex-col gap-1'>
        <RequirePermission permissions='lti.closing.detail'>
          <Button
            href={`/closing/detail/?closingId=${props.row.original.id}`}
            variant='ghost'
            color='primary'
            className='justify-start text-sm'
          >
            <Icon icon='mdi:eye-outline' width={16} height={16} />
            Detail
          </Button>
        </RequirePermission>
      </div>
    </RowOptionsMenuWrapper>
  );
};

const ClosingsTable = () => {
  const {
    state: tableFilterState,
    updateFilter,
    setPage,
    setPageSize,
    toQueryString: getTableFilterQueryString,
  } = useTableFilter({
    initial: {
      search: '',
      nameSort: '',
      transactionDate: '',
      realizationDate: '',
      locationId: '',
      projectStatus: '',
      userId: '',
    },
    paramMap: {
      page: 'page',
      pageSize: 'limit',
      nameSort: 'sort_name',
      transactionDate: 'transaction_date',
      realizationDate: 'realization_date',
      locationId: 'location_id',
      projectStatus: 'project_status',
      userId: 'user_id',
    },
  });

  const { data: closings, isLoading: isLoadingClosings } = useSWR(
    `${ClosingApi.basePath}${getTableFilterQueryString()}`,
    ClosingApi.getAllFetcher
  );

  const [sorting, setSorting] = useState<SortingState>([]);
  const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});

  const closingsColumns: ColumnDef<Closing>[] = [
    {
      header: '#',
      cell: (props) => props.row.index + 1,
    },
    {
      accessorKey: 'location_name',
      header: 'Lokasi',
    },
    {
      accessorKey: 'project_category',
      header: 'Kategori',
    },
    {
      accessorKey: 'period',
      header: 'Periode',
    },
    {
      accessorKey: 'closing_date',
      header: 'Periode',
      cell: (props) =>
        formatDate(props.row.original.closing_date, 'DD MMM YYYY'),
    },
    {
      accessorKey: 'shed_label',
      header: 'Jumlah Kandang',
    },
    {
      accessorKey: 'project_status',
      header: 'Status',
    },
    {
      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 - 3;

        return (
          <>
            {currentPageSize > 3 && (
              <RowDropdownOptions isLast2Rows={isLast2Rows}>
                <RowOptionsMenu type='dropdown' props={props} />
              </RowDropdownOptions>
            )}

            {currentPageSize <= 3 && (
              <RowCollapseOptions>
                <RowOptionsMenu type='collapse' props={props} />
              </RowCollapseOptions>
            )}
          </>
        );
      },
    },
  ];

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

  const [selectedLocation, setSelectedLocation] = useState<OptionType | null>(
    null
  );

  const locationChangeHandler = (val: OptionType | OptionType[] | null) => {
    setSelectedLocation(val as OptionType);
    updateFilter(
      'locationId',
      val ? ((val as OptionType).value as string) : ''
    );
  };

  const [selectedProjectStatus, setSelectedProjectStatus] =
    useState<OptionType | null>(null);

  const projectStatusChangeHandler = (
    val: OptionType | OptionType[] | null
  ) => {
    setSelectedProjectStatus(val as OptionType);
    updateFilter(
      'projectStatus',
      val ? ((val as OptionType).value as string) : ''
    );
  };

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

  // track sorting
  useEffect(() => {
    const isNameSorted = sorting.find((sortItem) => sortItem.id === 'name');

    if (!isNameSorted) {
      updateFilter('nameSort', '');
    } else {
      updateFilter('nameSort', isNameSorted.desc ? 'desc' : 'asc');
    }
  }, [sorting, updateFilter]);

  return (
    <>
      <div className='w-full p-0 sm:p-4'>
        <div className='flex flex-col gap-2 mb-4'>
          <div className='flex flex-col gap-2 mb-4'>
            <div className='w-full flex flex-col sm:flex-row justify-end items-end sm:items-center gap-4'>
              <DebouncedTextInput
                name='search'
                placeholder='Cari Closing'
                value={tableFilterState.search}
                onChange={searchChangeHandler}
                className={{ wrapper: 'sm:max-w-3xs' }}
              />
            </div>

            <div className='grid grid-cols-12 justify-end gap-2'>
              <SelectInput
                label='Lokasi'
                options={locationOptions}
                isLoading={isLoadingLocationOptions}
                value={selectedLocation}
                onChange={locationChangeHandler}
                onInputChange={setLocationInputValue}
                onMenuScrollToBottom={loadMoreLocations}
                isClearable
                className={{
                  wrapper: 'col-span-12 sm:col-span-6',
                }}
              />

              <SelectInput
                label='Status Project'
                placeholder='Pilih Status'
                options={PROJECT_STATUS_OPTIONS}
                value={selectedProjectStatus}
                onChange={projectStatusChangeHandler}
                isClearable
                className={{
                  wrapper: 'col-span-12 sm:col-span-6',
                }}
              />
            </div>
          </div>
        </div>

        <Table<Closing>
          data={isResponseSuccess(closings) ? closings?.data : []}
          columns={closingsColumns}
          pageSize={tableFilterState.pageSize}
          onPageSizeChange={setPageSize}
          rowOptions={[10, 20, 50, 100]}
          page={isResponseSuccess(closings) ? closings?.meta?.page : 0}
          totalItems={
            isResponseSuccess(closings) ? closings?.meta?.total_results : 0
          }
          onPageChange={setPage}
          isLoading={isLoadingClosings}
          sorting={sorting}
          setSorting={setSorting}
          rowSelection={rowSelection}
          setRowSelection={setRowSelection}
          className={{
            containerClassName: cn({
              'w-full mb-20':
                isResponseSuccess(closings) && closings?.data?.length === 0,
            }),
          }}
        />
      </div>
    </>
  );
};

export default ClosingsTable;
