'use client';

import Button from '@/components/Button';
import CheckboxInput from '@/components/input/CheckboxInput';
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
import SelectInput, { OptionType } from '@/components/input/SelectInput';
import { useModal } from '@/components/Modal';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
import Table from '@/components/Table';
import RowCollapseOptions from '@/components/table/RowCollapseOptions';
import RowDropdownOptions from '@/components/table/RowDropdownOptions';
import { ROWS_OPTIONS } from '@/config/constant';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { cn } from '@/lib/helper';
import { AreaApi, KandangApi, LocationApi } from '@/services/api/master-data';
import { ProjectFlockApi } from '@/services/api/production/project-flock';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { BaseApiResponse } from '@/types/api/api-general';
import { Kandang } from '@/types/api/master-data/kandang';
import {
  ProjectFlockApprovalPayload,
  ProjectFlock,
} from '@/types/api/production/project-flock';
import { Icon } from '@iconify/react';
import { CellContext, SortingState } from '@tanstack/react-table';
import { ChangeEventHandler, useState } from 'react';
import toast from 'react-hot-toast';
import useSWR from 'swr';

const RowOptionsMenu = ({
  type = 'dropdown',
  props,
  deleteClickHandler,
}: {
  type: 'dropdown' | 'collapse';
  props: CellContext<ProjectFlock, unknown>;
  deleteClickHandler: () => void;
}) => {
  return (
    <div
      tabIndex={type == 'dropdown' ? 0 : undefined}
      className={cn(
        {
          'dropdown-content': type === 'dropdown',
          'mt-2': type === 'collapse',
        },
        'p-2.5 mr-2 bg-base-100 rounded-box z-10 border border-black/10 shadow'
      )}
    >
      <div className='flex flex-col gap-1'>
        <Button
          href={`/production/project-flock/detail?projectFlockId=${props.row.original.id}`}
          variant='ghost'
          color='primary'
          className='justify-start text-sm'
        >
          <Icon icon='mdi:eye-outline' width={16} height={16} />
          Detail
        </Button>
        {props.row.original.approval.step_name === 'Aktif' && (
          <Button
            href={`/production/project-flock/chickin/add?projectFlockId=${props.row.original.id}`}
            variant='ghost'
            color='success'
            className='justify-start text-sm'
          >
            <Icon icon='mdi:home-import-outline' width={16} height={16} />
            Chickin
          </Button>
        )}
        {props.row.original.approval.step_name === 'Pengajuan' && (
          <Button
            href={`/production/project-flock/detail/edit?projectFlockId=${props.row.original.id}`}
            variant='ghost'
            color='warning'
            className='justify-start text-sm'
          >
            <Icon icon='mdi:pencil-outline' width={16} height={16} />
            Edit
          </Button>
        )}
        <Button
          onClick={deleteClickHandler}
          variant='ghost'
          color='error'
          className='text-error hover:text-inherit justify-start text-sm'
        >
          <Icon
            icon='material-symbols:delete-outline-rounded'
            width={16}
            height={16}
          />
          Delete
        </Button>
      </div>
    </div>
  );
};

const ProjectFlockTable = () => {
  const {
    state: tableFilterState,
    updateFilter,
    setPage,
    setPageSize,
    toQueryString: getTableFilterQueryString,
  } = useTableFilter({
    initial: {
      search: '',
      areaFilter: '',
      locationFilter: '',
      kandangFilter: '',
      periodFilter: '',
    },
    paramMap: {
      page: 'page',
      pageSize: 'limit',
      search: 'search',
      areaFilter: 'area_id',
      locationFilter: 'location_id',
      kandangFilter: 'kandang_id',
      periodFilter: 'period',
    },
  });

  // State
  const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
  const selectedRowIds = Object.keys(rowSelection)
    .filter((id) => rowSelection[id])
    .map((id) => parseInt(id));
  const [locationSelectInputValue, setLocationSelectInputValue] = useState('');
  const [areaSelectInputValue, setAreaSelectInputValue] = useState('');
  const [kandangSelectInputValue, setKandangSelectInputValue] = useState('');
  const [selectedArea, setSelectedArea] = useState<OptionType | null>(null);
  const [selectedLocation, setSelectedLocation] = useState<OptionType | null>(
    null
  );
  const [selectedKandang, setSelectedKandang] = useState<OptionType | null>(
    null
  );
  const [periodInputValue, setPeriodInputValue] = useState<number | null>(null);
  const [sorting, setSorting] = useState<SortingState>([]);
  const [selectedProjectFlock, setSelectedProjectFlock] =
    useState<ProjectFlock>();
  const deleteModal = useModal();
  const confirmModal = useModal();
  const [approvalAction, setApprovalAction] = useState<'APPROVED' | 'REJECTED'>(
    'APPROVED'
  );
  const [isDeleteLoading, setIsDeleteLoading] = useState(false);
  const [isApproveLoading, setIsApproveLoading] = useState(false);

  // Fetch Data
  const {
    data: projectFlocks,
    isLoading,
    mutate: refreshProjectFlocks,
  } = useSWR(
    `${ProjectFlockApi.basePath}${getTableFilterQueryString()}`,
    ProjectFlockApi.getAllFetcher
  );

  const areaUrl = `${AreaApi.basePath}?${new URLSearchParams({
    search: areaSelectInputValue,
    limit: '100',
  }).toString()}`;
  const { data: areas, isLoading: isLoadingAreas } = useSWR(
    areaUrl,
    AreaApi.getAllFetcher
  );

  const locationUrl = `${LocationApi.basePath}?${new URLSearchParams({
    search: locationSelectInputValue,
    area_id: selectedArea != null ? selectedArea.value.toString() : '',
    limit: '100',
  }).toString()}`;
  const { data: locations, isLoading: isLoadingLocations } = useSWR(
    locationUrl,
    LocationApi.getAllFetcher
  );

  const kandangUrl = `${KandangApi.basePath}?${new URLSearchParams({
    search: kandangSelectInputValue,
    location_id:
      selectedLocation != null ? selectedLocation.value.toString() : '',
    limit: '100',
  }).toString()}`;
  const { data: kandangs, isLoading: isLoadingKandang } = useSWR(
    kandangUrl,
    KandangApi.getAllFetcher
  );

  // Data to Options Mapping
  const optionsArea = isResponseSuccess(areas)
    ? areas?.data.map((area) => ({
        value: area.id,
        label: area.name,
      }))
    : [];
  const optionsKandang = isResponseSuccess(kandangs)
    ? kandangs?.data.map((kandang) => ({
        value: kandang.id,
        label: kandang.name,
      }))
    : [];
  const optionsLocation = isResponseSuccess(locations)
    ? locations?.data.map((location) => ({
        value: location.id,
        label: location.name,
      }))
    : [];

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

    await ProjectFlockApi.delete(selectedProjectFlock?.id as number);
    refreshProjectFlocks();

    deleteModal.closeModal();
    toast.success('Successfully delete Project Flock!');
    setIsDeleteLoading(false);
  };
  const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
    updateFilter('search', e.target.value);
  };

  const confirmApprovalHandler = async (
    notes: string,
    approvalAction: 'APPROVED' | 'REJECTED'
  ) => {
    setIsApproveLoading(true);
    const approveProjectFlockRes =
      approvalAction === 'APPROVED'
        ? await ProjectFlockApi.bulkApprove(
            selectedRowIds.map((id) => id),
            notes
          )
        : await ProjectFlockApi.bulkReject(
            selectedRowIds.map((id) => id),
            notes
          );

    if (isResponseSuccess(approveProjectFlockRes)) {
      toast.success('Project Flock berhasil di-approve!');
      confirmModal.closeModal();
    }
    if (isResponseError(approveProjectFlockRes)) {
      toast.error(approveProjectFlockRes?.message as string);
      confirmModal.closeModal();
    }
    setRowSelection({});
    refreshProjectFlocks();
    setIsApproveLoading(false);
  };

  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 justify-between items-end gap-2'>
            <div className='flex flex-col sm:flex-row gap-3 w-full'>
              <Button
                href='/production/project-flock/add'
                variant='outline'
                color='primary'
                className='w-full sm:w-fit'
              >
                <Icon icon='ic:round-plus' width={24} height={24} />
                Tambah
              </Button>
              <Button
                variant='outline'
                color='success'
                onClick={() => {
                  setApprovalAction('APPROVED');
                  confirmModal.openModal();
                }}
                disabled={selectedRowIds.length === 0}
                className='w-full sm:w-fit'
              >
                <Icon icon='material-symbols:check' width={24} height={24} />
                Approve
              </Button>
              <Button
                variant='outline'
                color='error'
                onClick={() => {
                  setApprovalAction('REJECTED');
                  confirmModal.openModal();
                }}
                disabled={selectedRowIds.length === 0}
                className='w-full sm:w-fit'
              >
                <Icon icon='mdi:times' width={24} height={24} />
                Reject
              </Button>
              <div className='ms-auto w-full sm:w-auto'>
                <DebouncedTextInput
                  name='search'
                  placeholder='Cari Area'
                  value={tableFilterState.search}
                  onChange={searchChangeHandler}
                  className={{
                    wrapper: 'w-full sm:max-w-3xs',
                    input: 'w-full',
                    inputWrapper: 'w-full',
                  }}
                />
              </div>
            </div>
            <div className='hidden sm:flex flex-row justify-end gap-6 w-full'>
              <SelectInput
                label='Area'
                options={optionsArea}
                isLoading={isLoadingAreas}
                value={selectedArea}
                onChange={(val) => {
                  setSelectedArea(val as OptionType);
                  updateFilter(
                    'areaFilter',
                    (val as OptionType)?.value.toString()
                  );
                }}
                onInputChange={setAreaSelectInputValue}
                isClearable
              />
              <SelectInput
                label='Lokasi'
                options={optionsLocation}
                isLoading={isLoadingLocations}
                value={selectedLocation}
                onChange={(val) => {
                  setSelectedLocation(val as OptionType);
                  updateFilter(
                    'locationFilter',
                    (val as OptionType)?.value.toString()
                  );
                }}
                onInputChange={setLocationSelectInputValue}
                isClearable
              />
              <SelectInput
                label='Kandang'
                options={optionsKandang}
                isLoading={isLoadingKandang}
                value={selectedKandang}
                onChange={(val) => {
                  setSelectedKandang(val as OptionType);
                  updateFilter(
                    'kandangFilter',
                    (val as OptionType)?.value.toString()
                  );
                }}
                onInputChange={setKandangSelectInputValue}
                isClearable
              />
              <DebouncedTextInput
                name='period'
                type='number'
                label='Periode'
                placeholder='Masukan periode'
                value={periodInputValue ?? ''}
                onChange={(e) => {
                  setPeriodInputValue(parseInt(e.target.value));
                  updateFilter('periodFilter', e.target.value);
                }}
              />
              <SelectInput
                label='Baris'
                options={ROWS_OPTIONS}
                value={{
                  label: String(tableFilterState.pageSize),
                  value: tableFilterState.pageSize,
                }}
                onChange={pageSizeChangeHandler}
                className={{ wrapper: 'max-w-28' }}
              />
            </div>
          </div>

          <Table<ProjectFlock>
            data={isResponseSuccess(projectFlocks) ? projectFlocks?.data : []}
            columns={[
              {
                id: 'select',
                header: ({ table }) => {
                  const allRows = table.getRowModel().rows;
                  const selectableRows = allRows.filter(
                    (row) => row.original?.approval?.step_number == 1
                  );

                  const allSelected =
                    selectableRows.every((row) => row.getIsSelected()) &&
                    selectableRows.length != 0;

                  const someSelected =
                    selectableRows.some((row) => row.getIsSelected()) &&
                    !allSelected;

                  const toggleSelectableRows = () => {
                    const shouldSelect = !allSelected;
                    selectableRows.forEach((row) =>
                      row.toggleSelected(shouldSelect)
                    );
                  };

                  return (
                    <div className='w-full flex flex-row justify-center'>
                      <CheckboxInput
                        name='allRow'
                        checked={allSelected}
                        indeterminate={someSelected}
                        onChange={toggleSelectableRows}
                        disabled={
                          isResponseSuccess(projectFlocks) &&
                          projectFlocks?.data?.filter(
                            (flock) => flock.approval.step_number == 1
                          ).length == 0
                        }
                      />
                    </div>
                  );
                },
                cell: ({ row }) => {
                  return (
                    <CheckboxInput
                      name='row'
                      checked={
                        row.getIsSelected() &&
                        row.original.approval.step_number == 1
                      }
                      disabled={
                        !row.getCanSelect() ||
                        row.original.approval.step_number != 1
                      }
                      indeterminate={row.getIsSomeSelected()}
                      onChange={row.getToggleSelectedHandler()}
                    />
                  );
                },
              },

              {
                accessorKey: 'flock_name',
                header: 'Flock',
              },
              {
                accessorKey: 'area.name',
                header: 'Area',
              },
              {
                accessorKey: 'location.name',
                header: 'Lokasi',
              },
              {
                accessorKey: 'fcr.name',
                header: 'FCR',
              },
              {
                accessorKey: 'category',
                header: 'Kategori',
              },
              {
                accessorKey: 'approval.step_name',
                header: 'Status',
              },
              {
                header: 'Kandang',
                cell: (props) => {
                  const kandang = props.row.original.kandangs;
                  if (kandang) {
                    const kandangNames = kandang.map((k: Kandang) => k.name);
                    return (
                      <div>
                        {kandangNames.length > 0
                          ? kandangNames.join(', ')
                          : 'Tidak ada'}
                      </div>
                    );
                  } else {
                    return '-';
                  }
                },
              },
              {
                accessorKey: 'period',
                header: 'Periode',
              },
              {
                accessorKey: 'created_at',
                header: 'Dibuat pada',
                cell: (props) =>
                  new Date(props.row.original.created_at).toLocaleDateString(),
              },
              {
                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 = () => {
                    setSelectedProjectFlock(props.row.original);
                    deleteModal.openModal();
                  };

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

                      {currentPageSize <= 2 && (
                        <RowCollapseOptions>
                          <RowOptionsMenu
                            type='collapse'
                            props={props}
                            deleteClickHandler={deleteClickHandler}
                          />
                        </RowCollapseOptions>
                      )}
                    </>
                  );
                },
              },
            ]}
            pageSize={tableFilterState.pageSize}
            page={
              isResponseSuccess(projectFlocks) ? projectFlocks?.meta?.page : 0
            }
            totalItems={
              isResponseSuccess(projectFlocks)
                ? projectFlocks?.meta?.total_results
                : 0
            }
            onPageChange={setPage}
            isLoading={isLoading}
            sorting={sorting}
            setSorting={setSorting}
            rowSelection={rowSelection}
            setRowSelection={setRowSelection}
            className={{
              containerClassName: cn({
                'mb-20':
                  isResponseSuccess(projectFlocks) &&
                  projectFlocks?.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>

      <ConfirmationModal
        ref={deleteModal.ref}
        type='error'
        text={`Apakah anda yakin ingin menghapus data Project Flock ini (${selectedProjectFlock?.flock_name})?`}
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: 'error',
          isLoading: isDeleteLoading,
          onClick: confirmationModalDeleteClickHandler,
        }}
      />

      <ConfirmationModalWithNotes
        ref={confirmModal.ref}
        type={approvalAction == 'APPROVED' ? 'success' : 'error'}
        text={`Apakah anda yakin ingin ${approvalAction == 'APPROVED' ? 'approve' : 'reject'} data Project Flock ini (${selectedRowIds.length} data)?`}
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: approvalAction == 'APPROVED' ? 'success' : 'error',
          onClick: (notes) => {
            confirmApprovalHandler(notes, approvalAction);
          },
          isLoading: isApproveLoading,
        }}
      />
    </>
  );
};

export default ProjectFlockTable;
