'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 } 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 } 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, 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 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'>
        <RequirePermission permissions='lti.production.project_flocks.detail'>
          <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>
        </RequirePermission>
        {props.row.original.approval.step_name === 'Aktif' && (
          <RequirePermission permissions='lti.production.chickins.create'>
            <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>
          </RequirePermission>
        )}
        {props.row.original.approval.step_name === 'Pengajuan' && (
          <RequirePermission permissions='lti.production.project_flocks.update'>
            <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>
          </RequirePermission>
        )}
        <RequirePermission permissions='lti.production.project_flocks.delete'>
          <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>
        </RequirePermission>
      </div>
    </div>
  );
};

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 [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,
    { revalidateOnMount: true }
  );

  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);

    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]);

  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 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;

                  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;

                  return (
                    <Badge
                      variant='soft'
                      className={{
                        badge:
                          'rounded-lg px-2 w-full flex flex-row justify-start',
                      }}
                      color={
                        approval.step_number == 1
                          ? 'neutral'
                          : approval.step_number == 2
                            ? 'success'
                            : 'error'
                      }
                    >
                      <Icon
                        icon='mdi:circle'
                        width={12}
                        height={12}
                        color={
                          approval.step_number == 1
                            ? 'neutral'
                            : approval.step_number == 2
                              ? 'success'
                              : 'error'
                        }
                      />
                      {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'),
              },
            ]}
            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>

      <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;
