'use client';

import Badge from '@/components/Badge';
import Button from '@/components/Button';
import FloatingActionsButton from '@/components/FloatingActionsButton';
import CheckboxInput from '@/components/input/CheckboxInput';
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
import SelectInput, {
  OptionType,
  useSelect,
} 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 { ROWS_OPTIONS } from '@/config/constant';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { cn, formatDate, formatTitleCase } 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 { Kandang } from '@/types/api/master-data/kandang';
import { ProjectFlock } from '@/types/api/production/project-flock';
import { Icon } from '@iconify/react';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import { useRouter } from 'next/navigation';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import toast from 'react-hot-toast';
import useSWR from 'swr';

import RequirePermission from '@/components/helper/RequirePermission';

const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
  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',
    },
  });
  const router = useRouter();

  // ===== State =====
  const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
  const selectedRowIds = Object.keys(rowSelection)
    .filter((id) => rowSelection[id])
    .map((id) => parseInt(id));
  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 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,
    { revalidateOnMount: true }
  );

  // ===== Fetch Data Select =====
  const {
    options: optionsArea,
    isLoadingOptions: isLoadingArea,
    setInputValue: setAreaSelectInputValue,
    loadMore: loadMoreArea,
  } = useSelect(AreaApi.basePath, 'id', 'name');
  const {
    options: optionsLocation,
    isLoadingOptions: isLoadingLocation,
    setInputValue: setLocationSelectInputValue,
    loadMore: loadMoreLocation,
  } = useSelect(LocationApi.basePath, 'id', 'name');
  const {
    options: optionsKandang,
    isLoadingOptions: isLoadingKandang,
    setInputValue: setKandangSelectInputValue,
    loadMore: loadMoreKandang,
  } = useSelect(KandangApi.basePath, 'id', 'name');

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

    const response = await ProjectFlockApi.delete(
      selectedSingleRow?.id as number
    );
    if (isResponseSuccess(response)) {
      toast.success(response?.message as string);
    }
    if (isResponseError(response)) {
      toast.error(response?.message as string);
    }
    refreshProjectFlocks();

    deleteModal.closeModal();
    setIsDeleteLoading(false);
    setRowSelection({});
  };
  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);
  };

  // ====== EFFECT ======
  useEffect(() => {
    refreshProjectFlocks();
  }, [refresh]);

  // ====== MEMO ======
  const selectedSingleRow: ProjectFlock | null | undefined = useMemo(() => {
    return selectedRowIds.length === 1
      ? isResponseSuccess(projectFlocks)
        ? projectFlocks?.data.find((row) => row.id === selectedRowIds[0])
        : null
      : null;
  }, [rowSelection]);

  const canApprove = useMemo(() => {
    if (!selectedSingleRow || isApproveLoading) return false;

    const isPengajuan = selectedSingleRow.approval?.step_number == 1;
    const isNotRejected = selectedSingleRow.approval?.action != 'REJECTED';

    return isPengajuan && isNotRejected;
  }, [selectedSingleRow, isApproveLoading]);

  // ====== COLUMNS ======
  const columns = useMemo<ColumnDef<ProjectFlock>[]>(
    () => [
      {
        id: 'select',
        header: ({ table }) => {
          const allRows = table.getRowModel().rows;
          const selectableRows = allRows;

          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}
              />
            </div>
          );
        },
        cell: ({ row }) => {
          return (
            <CheckboxInput
              name='row'
              checked={row.getIsSelected()}
              disabled={!row.getCanSelect()}
              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',
        cell: (props) => {
          const approval = props.row.original.approval;
          const isRejected = approval?.action == 'REJECTED';
          const isApproved = approval?.action == 'APPROVED';
          return (
            <Badge
              variant='soft'
              className={{
                badge: 'rounded-lg px-2 w-full flex flex-row justify-start',
              }}
              color={
                isRejected
                  ? 'error'
                  : isApproved
                    ? approval?.step_number == 1
                      ? 'neutral'
                      : approval?.step_number == 2
                        ? 'primary'
                        : approval?.step_number == 3
                          ? 'success'
                          : 'neutral'
                    : 'neutral'
              }
            >
              <Icon
                icon='mdi:circle'
                width={12}
                height={12}
                color={
                  approval?.step_number == 1
                    ? 'neutral'
                    : approval?.step_number == 2
                      ? 'primary'
                      : approval?.step_number == 3
                        ? 'success'
                        : 'neutral'
                }
              />
              {isRejected
                ? 'Ditolak'
                : formatTitleCase(approval?.step_name || '')}
            </Badge>
          );
        },
      },
      {
        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) =>
          formatDate(props.row.original.created_at, 'MMM DD, YYYY'),
      },
    ],
    []
  );

  return (
    <>
      <div className='min-h-screen w-full 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'>
              <RequirePermission permissions='lti.production.project_flocks.create'>
                <Button
                  color='primary'
                  className='w-full sm:w-fit'
                  onClick={() => {
                    setRowSelection({});
                    router.push('/production/project-flock/add');
                  }}
                >
                  <Icon icon='ic:round-plus' width={24} height={24} />
                  Tambah
                </Button>
              </RequirePermission>
              <div className='ms-auto w-full sm:w-auto'>
                <DebouncedTextInput
                  name='search'
                  placeholder='Cari Project Flock'
                  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={isLoadingArea}
                value={selectedArea}
                onChange={(val) => {
                  setSelectedArea(val as OptionType);
                  updateFilter(
                    'areaFilter',
                    (val as OptionType)?.value.toString()
                  );
                }}
                onInputChange={setAreaSelectInputValue}
                onMenuScrollToBottom={loadMoreArea}
                isClearable
              />
              <SelectInput
                label='Lokasi'
                options={optionsLocation}
                isLoading={isLoadingLocation}
                value={selectedLocation}
                onChange={(val) => {
                  setSelectedLocation(val as OptionType);
                  updateFilter(
                    'locationFilter',
                    (val as OptionType)?.value.toString()
                  );
                }}
                onInputChange={setLocationSelectInputValue}
                onMenuScrollToBottom={loadMoreLocation}
                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}
                onMenuScrollToBottom={loadMoreKandang}
                isClearable
              />
              <DebouncedTextInput
                name='period'
                type='number'
                label='Periode'
                placeholder='Masukan periode'
                value={periodInputValue?.toString() ?? ''}
                onChange={(e) => {
                  setPeriodInputValue(parseInt(e.target.value));
                  updateFilter('periodFilter', e.target.value);
                }}
              />
            </div>
          </div>

          <Table<ProjectFlock>
            data={isResponseSuccess(projectFlocks) ? projectFlocks?.data : []}
            columns={columns}
            pageSize={tableFilterState.pageSize}
            page={
              isResponseSuccess(projectFlocks) ? projectFlocks?.meta?.page : 0
            }
            totalItems={
              isResponseSuccess(projectFlocks)
                ? projectFlocks?.meta?.total_results
                : 0
            }
            onPageChange={(page) => {
              setPage(page);
            }}
            onPageSizeChange={(pageSize) => {
              setPageSize(pageSize);
            }}
            isLoading={isLoading}
            sorting={sorting}
            setSorting={setSorting}
            rowSelection={rowSelection}
            setRowSelection={setRowSelection}
            className={{
              containerClassName: cn({
                'mb-40':
                  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>

      <FloatingActionsButton
        actions={[
          {
            action: 'DETAIL',
            icon: 'mdi:eye-outline',
            label: 'Lihat Detail',
            hidden: selectedRowIds.length !== 1,
            onClick() {
              router.push(
                `/production/project-flock/detail?projectFlockId=${selectedRowIds[0]}`
              );
              setRowSelection({});
            },
            permissions: 'lti.production.project_flocks.detail',
          },
          {
            action: 'DELETE',
            icon: 'material-symbols:delete-outline-rounded',
            label: `Hapus data`,
            hidden: selectedRowIds.length !== 1,
            onClick: () => {
              deleteModal.openModal();
            },
            permissions: 'lti.production.project_flocks.delete',
          },
        ]}
        approvals={[
          {
            icon: 'material-symbols:check',
            label: 'Approve',
            action: 'APPROVED',
            onClick: () => {
              setApprovalAction('APPROVED');
              confirmModal.openModal();
            },
            disabled: !canApprove,
            permissions: 'lti.production.project_flocks.approve',
          },
          {
            icon: 'mdi:times',
            label: 'Reject',
            action: 'REJECTED',
            onClick: () => {
              setApprovalAction('REJECTED');
              confirmModal.openModal();
            },
            permissions: 'lti.production.project_flocks.approve',
          },
        ]}
        selectedRowIds={selectedRowIds}
        onClose={() => {
          setRowSelection({});
        }}
      />

      <ConfirmationModal
        ref={deleteModal.ref}
        type='error'
        text={`Apakah anda yakin ingin menghapus data Project Flock ini (${selectedRowIds?.length} data)?`}
        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;
