'use client';

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

import { Icon } from '@iconify/react';
import Table from '@/components/Table';
import Button from '@/components/Button';
import { useModal } from '@/components/Modal';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import CheckboxInput from '@/components/input/CheckboxInput';
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
import RequirePermission from '@/components/helper/RequirePermission';
import PopoverButton from '@/components/popover/PopoverButton';
import Badge from '@/components/Badge';
import PopoverContent from '@/components/popover/PopoverContent';
import Dropdown from '@/components/Dropdown';
import StatusBadge from '@/components/helper/StatusBadge';
import TransferToLayingFilterModal from '@/components/pages/production/transfer-to-laying/TransferToLayingFilterModal';

import {
  TransferToLaying,
  TransferToLayingFilter,
} from '@/types/api/production/transfer-to-laying';
import { TransferToLayingApi } from '@/services/api/production/transfer-to-laying';
import { cn, formatDate } from '@/lib/helper';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { Color } from '@/types/theme';

const RowOptionsMenu = ({
  props,
  popoverPosition = 'bottom',
  approveClickHandler,
  rejectClickHandler,
  deleteClickHandler,
}: {
  props: CellContext<TransferToLaying, unknown>;
  popoverPosition: 'bottom' | 'top';
  approveClickHandler: () => void;
  rejectClickHandler: () => void;
  deleteClickHandler: () => void;
}) => {
  const showEditButton =
    props.row.original.approval.action !== 'APPROVED' &&
    props.row.original.approval.action !== 'REJECTED';

  const showDeleteButton = showEditButton;

  // const showApproveButton = showEditButton;
  // const showRejectButton = showEditButton;

  const popoverId = `transferToLaying#${props.row.original.id}`;
  const popoverAnchorName = `--anchor-transferToLaying#${props.row.original.id}`;

  return (
    <div className='relative'>
      <PopoverButton
        tabIndex={0}
        variant='ghost'
        color='none'
        popoverTarget={popoverId}
        anchorName={popoverAnchorName}
      >
        <Icon icon='material-symbols:more-vert' width={16} height={16} />
      </PopoverButton>

      <PopoverContent
        id={popoverId}
        anchorName={popoverAnchorName}
        position={popoverPosition === 'bottom' ? 'bottom-start' : 'left'}
        className='w-full max-w-40 rounded-xl border border-base-content/5 shadow-sm'
      >
        <div className='flex flex-col bg-base-100 rounded-xl'>
          <RequirePermission permissions='lti.production.transfer_to_laying.detail'>
            <Button
              href={`/production/transfer-to-laying/detail/?transferToLayingId=${props.row.original.id}`}
              variant='ghost'
              color='none'
              className='p-3 justify-start text-sm font-semibold w-full'
            >
              <Icon icon='heroicons:eye' width={20} height={20} />
              View Details
            </Button>
          </RequirePermission>

          {showEditButton && (
            <RequirePermission permissions='lti.production.transfer_to_laying.update'>
              <Button
                href={`/production/transfer-to-laying/detail/edit/?transferToLayingId=${props.row.original.id}`}
                variant='ghost'
                color='none'
                className='p-3 justify-start text-sm font-semibold w-full'
              >
                <Icon icon='heroicons:pencil-square' width={20} height={20} />
                Edit
              </Button>
            </RequirePermission>
          )}

          {/* {showApproveButton && (
            <RequirePermission permissions='lti.production.transfer_to_laying.approve'>
              <Button
                variant='ghost'
                color='success'
                onClick={approveClickHandler}
                className='p-3 justify-start text-sm font-semibold w-full'
              >
                <Icon icon='heroicons:check' width={20} height={20} />
                Approve
              </Button>
            </RequirePermission>
          )}

          {showRejectButton && (
            <RequirePermission permissions='lti.production.transfer_to_laying.approve'>
              <Button
                variant='ghost'
                color='error'
                onClick={rejectClickHandler}
                className='p-3 justify-start text-sm font-semibold w-full'
              >
                <Icon icon='heroicons:x-mark' width={20} height={20} />
                Reject
              </Button>
            </RequirePermission>
          )} */}

          {showDeleteButton && (
            <RequirePermission permissions='lti.production.transfer_to_laying.delete'>
              <hr className='mx-3 border-base-content/10 h-px' />
              <Button
                onClick={deleteClickHandler}
                variant='ghost'
                color='error'
                className='p-3 justify-start text-sm font-semibold w-full'
              >
                <Icon icon='heroicons:trash' width={20} height={20} />
                Delete
              </Button>
            </RequirePermission>
          )}
        </div>
      </PopoverContent>
    </div>
  );
};

const TransferToLayingsTable = () => {
  const {
    state: tableFilterState,
    updateFilter,
    setPage,
    setPageSize,
    toQueryString: getTableFilterQueryString,
  } = useTableFilter({
    initial: {
      search: '',
      startDate: '',
      endDate: '',
      flockSource: '',
      flockDestination: '',
      status: '',
      filter_by: '',
      sort_by: '',
    },
    paramMap: {
      page: 'page',
      pageSize: 'limit',
      startDate: 'start_date',
      endDate: 'end_date',
      flockSource: 'flock_source',
      flockDestination: 'flock_destination',
      status: 'status',
      filter_by: 'filter_by',
      sort_by: 'sort_by',
    },
  });

  const {
    data: transferToLayings,
    isLoading,
    mutate: refreshTransferToLayings,
  } = useSWR(
    `${TransferToLayingApi.basePath}${getTableFilterQueryString()}`,
    TransferToLayingApi.getAllFetcher
  );

  const filterCount = useMemo(() => {
    let count = 0;

    if (tableFilterState.startDate && tableFilterState.endDate) {
      count += 1;
    }

    if (tableFilterState.flockSource.length > 0) {
      count += 1;
    }

    if (tableFilterState.flockDestination.length > 0) {
      count += 1;
    }

    if (tableFilterState.status.length > 0) {
      count += 1;
    }

    return count;
  }, [tableFilterState]);

  const isFilterActive = filterCount > 0;

  // Modal hooks
  const filterModal = useModal();
  const deleteModal = useModal();
  const approveModal = useModal();
  const rejectModal = useModal();

  const [selectedTransferToLaying, setSelectedTransferToLaying] = useState<
    TransferToLaying | undefined
  >(undefined);

  // Modal loading state
  const [isDeleteLoading, setIsDeleteLoading] = useState(false);
  const [isApproveLoading, setIsApproveLoading] = useState(false);
  const [isRejectLoading, setIsRejectLoading] = useState(false);

  const [sorting, setSorting] = useState<SortingState>([]);
  const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
  const selectedRowIds = Object.keys(rowSelection).map((item) =>
    parseInt(item)
  );

  const transferToLayingsColumns: ColumnDef<TransferToLaying>[] = [
    {
      id: 'select',
      header: ({ table }) => (
        <div className='w-full flex flex-row justify-center'>
          <CheckboxInput
            name='allRow'
            checked={table.getIsAllRowsSelected()}
            indeterminate={table.getIsSomeRowsSelected()}
            onChange={table.getToggleAllRowsSelectedHandler()}
          />
        </div>
      ),
      cell: ({ row }) => {
        const isCheckboxDisabled =
          !row.getCanSelect() ||
          row.original.approval.action === 'APPROVED' ||
          row.original.approval.action === 'REJECTED';

        return (
          <div>
            <CheckboxInput
              name='row'
              checked={row.getIsSelected()}
              disabled={isCheckboxDisabled}
              indeterminate={row.getIsSomeSelected()}
              onChange={row.getToggleSelectedHandler()}
            />
          </div>
        );
      },
    },
    {
      accessorKey: 'transfer_date',
      header: 'Tanggal Transfer',
      cell: (props) => formatDate(props.getValue() as string, 'DD MMM YYYY'),
    },
    {
      accessorKey: 'flock_source',
      header: 'Flock Asal',
      cell: (props) => props.row.original.from_project_flock.flock_name,
    },
    {
      accessorKey: 'flock_destination',
      header: 'Flock Tujuan',
      cell: (props) => props.row.original.to_project_flock.flock_name,
    },
    {
      accessorKey: 'usage_qty',
      header: 'Kuantitas',
      cell: (props) => props.getValue() ?? props.row.original.pending_usage_qty,
    },
    {
      accessorKey: 'notes',
      header: 'Alasan Transfer',
      enableSorting: false,
    },
    {
      header: 'Status',
      cell: (props) => {
        const isLatestApprovalRejected =
          props.row.original.approval.action === 'REJECTED';
        let latestApprovalStepName = props.row.original.approval.step_name;

        let badgeColor: Color = 'neutral';

        switch (latestApprovalStepName.toLowerCase()) {
          case 'pengajuan':
            badgeColor = 'neutral';
            break;

          case 'disetujui':
            badgeColor = 'success';
            break;
        }

        if (isLatestApprovalRejected) {
          badgeColor = 'error';
          latestApprovalStepName = 'Ditolak';
        }

        return <StatusBadge color={badgeColor} text={latestApprovalStepName} />;
      },
    },
    {
      id: 'actions',
      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 approveClickHandler = () => {
          setSelectedTransferToLaying(props.row.original);

          // Set row selection
          setRowSelection({
            [String(props.row.original.id)]: true,
          });

          approveModal.openModal();
        };

        const rejectClickHandler = () => {
          setSelectedTransferToLaying(props.row.original);

          // Set row selection
          setRowSelection({
            [String(props.row.original.id)]: true,
          });

          rejectModal.openModal();
        };

        const deleteClickHandler = () => {
          setSelectedTransferToLaying(props.row.original);
          deleteModal.openModal();
        };

        return (
          <RowOptionsMenu
            props={props}
            approveClickHandler={approveClickHandler}
            rejectClickHandler={rejectClickHandler}
            deleteClickHandler={deleteClickHandler}
            popoverPosition={isLast2Rows ? 'top' : 'bottom'}
          />
        );
      },
    },
  ];

  const tableEnableRowSelectionHandler: (
    row: Row<TransferToLaying>
  ) => boolean = (row) => {
    return (
      row.original.approval.action !== 'APPROVED' &&
      row.original.approval.action !== 'REJECTED'
    );
  };

  const bulkApproveClickHandler = () => {
    approveModal.openModal();
  };

  const bulkRejectClickHandler = () => {
    rejectModal.openModal();
  };

  // Modal confirm click handler
  const confirmationModalDeleteClickHandler = async () => {
    setIsDeleteLoading(true);

    const deleteResponse = await TransferToLayingApi.delete(
      selectedTransferToLaying?.id as number
    );

    if (isResponseError(deleteResponse)) {
      toast.error(deleteResponse.message);
      setIsDeleteLoading(false);
      return;
    }

    refreshTransferToLayings();

    deleteModal.closeModal();
    toast.success('Berhasil menghapus data transfer ke laying!');
    setIsDeleteLoading(false);
  };

  const confirmationModalApproveClickHandler = async (notes: string) => {
    setIsApproveLoading(true);

    const bulkApproveResponse = await TransferToLayingApi.bulkApprove(
      selectedRowIds,
      notes
    );

    if (isResponseSuccess(bulkApproveResponse)) {
      refreshTransferToLayings();
      approveModal.closeModal();

      toast.success(
        `Berhasil approve ${selectedRowIds.length} data transfer ke laying!`
      );

      setRowSelection({});
    } else {
      approveModal.closeModal();

      toast.error(
        `Gagal approve ${selectedRowIds.length} data transfer ke laying!`
      );
    }

    setIsApproveLoading(false);
  };

  const confirmationModalRejectClickHandler = async (notes: string) => {
    setIsRejectLoading(true);

    const bulkRejectResponse = await TransferToLayingApi.bulkReject(
      selectedRowIds,
      notes
    );

    if (isResponseSuccess(bulkRejectResponse)) {
      refreshTransferToLayings();
      rejectModal.closeModal();

      toast.success(
        `Berhasil reject ${selectedRowIds.length} data transfer ke laying!`
      );
      setRowSelection({});
    } else {
      rejectModal.closeModal();

      toast.error(
        `Gagal reject ${selectedRowIds.length} data transfer ke laying!`
      );
    }

    setIsRejectLoading(false);
  };

  const filterSubmitHandler = (values: TransferToLayingFilter) => {
    updateFilter('startDate', values.startDate);
    updateFilter('endDate', values.endDate);
    updateFilter('flockSource', values.flockSource.join(','));
    updateFilter('flockDestination', values.flockDestination.join(','));
    updateFilter('status', values.status.join(','));
  };

  const filterResetHandler = () => {
    updateFilter('startDate', '');
    updateFilter('endDate', '');
    updateFilter('flockSource', '');
    updateFilter('flockDestination', '');
    updateFilter('status', '');
  };

  // TODO: add export to excel functionality
  const exportToExcelHandler = () => {
    toast.error('Not implemented yet');
  };

  useEffect(() => {
    if (sorting.length === 1) {
      updateFilter('filter_by', sorting[0].id);
      updateFilter('sort_by', sorting[0].desc ? 'desc' : 'asc');
    } else {
      updateFilter('filter_by', '');
      updateFilter('sort_by', '');
    }
  }, [sorting]);

  return (
    <>
      <div className='@container w-full'>
        <div className='w-full p-3 flex flex-row justify-between gap-3 flex-wrap border-b border-base-content/10'>
          <div className='w-fit flex flex-row gap-3 flex-wrap'>
            <RequirePermission permissions='lti.production.transfer_to_laying.create'>
              <Button
                href='/production/transfer-to-laying/add'
                color='primary'
                className='px-3 py-2.5 w-fit text-sm text-base-100 rounded-lg shadow-sm'
              >
                <Icon icon='heroicons:plus' width={20} height={20} />
                Add Transfer to Laying
              </Button>
            </RequirePermission>

            {selectedRowIds.length > 0 && (
              <>
                <hr className='w-px h-full border-none bg-base-content/10 hidden @sm:block' />

                <RequirePermission permissions='lti.production.transfer_to_laying.approve'>
                  <Button
                    variant='outline'
                    color='none'
                    onClick={bulkRejectClickHandler}
                    disabled={selectedRowIds.length === 0}
                    className='px-3 py-2.5 gap-1.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
                  >
                    <Icon
                      icon='heroicons:x-mark'
                      width={20}
                      height={20}
                      className='text-error'
                    />
                    Reject
                  </Button>
                </RequirePermission>

                <RequirePermission permissions='lti.production.transfer_to_laying.approve'>
                  <Button
                    variant='outline'
                    color='none'
                    onClick={bulkApproveClickHandler}
                    disabled={selectedRowIds.length === 0}
                    className='px-3 py-2.5 gap-1.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
                  >
                    <Icon
                      icon='heroicons:check'
                      width={20}
                      height={20}
                      className='text-success'
                    />
                    Approve
                  </Button>
                </RequirePermission>
              </>
            )}
          </div>

          <div className='flex flex-row justify-center items-center gap-3'>
            <Button
              variant='outline'
              color='none'
              onClick={filterModal.openModal}
              className={cn(
                'px-3 py-2.5 gap-1.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft transition-all duration-1000',
                {
                  'border-primary-gradient text-primary': isFilterActive,
                }
              )}
            >
              <Icon icon='heroicons:funnel' width={20} height={20} />
              Filter
              {isFilterActive && (
                <Badge
                  className={{
                    badge:
                      'p-1.5 bg-[#FF3535] text-xs text-base-100 border border-base-300 rounded-lg',
                  }}
                >
                  {filterCount}
                </Badge>
              )}
            </Button>

            <Dropdown
              align='end'
              direction='bottom'
              className={{
                content:
                  'mt-1 rounded-xl border border-base-content/5 shadow-sm overflow-hidden',
              }}
              trigger={
                <Button
                  variant='outline'
                  color='none'
                  className='px-3 py-2.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
                >
                  <div className='flex flex-row items-center gap-1.5'>
                    <Icon
                      icon='heroicons:cloud-arrow-down'
                      width={20}
                      height={20}
                    />

                    <span>Export</span>

                    <div className='w-px self-stretch bg-base-content/10' />

                    <Icon
                      icon='heroicons:chevron-down'
                      width={14}
                      height={14}
                    />
                  </div>
                </Button>
              }
            >
              <Button
                variant='ghost'
                color='none'
                onClick={exportToExcelHandler}
                className='w-full p-3 justify-start text-sm text-base-content/50 font-semibold text-nowrap'
              >
                <Icon icon='heroicons:table-cells' width={20} height={20} />
                Export to Excel
              </Button>
            </Dropdown>
          </div>
        </div>

        <Table<TransferToLaying>
          data={
            isResponseSuccess(transferToLayings) ? transferToLayings?.data : []
          }
          columns={transferToLayingsColumns}
          pageSize={tableFilterState.pageSize}
          page={
            isResponseSuccess(transferToLayings)
              ? transferToLayings?.meta?.page
              : 0
          }
          totalItems={
            isResponseSuccess(transferToLayings)
              ? transferToLayings?.meta?.total_results
              : 0
          }
          onPageChange={setPage}
          onPageSizeChange={setPageSize}
          isLoading={isLoading}
          sorting={sorting}
          setSorting={setSorting}
          rowSelection={rowSelection}
          setRowSelection={setRowSelection}
          enableRowSelection={tableEnableRowSelectionHandler}
          withCheckbox
          className={{
            containerClassName: cn('p-3', {
              'w-full mb-20':
                isResponseSuccess(transferToLayings) &&
                transferToLayings?.data?.length === 0,
            }),
            headerColumnClassName: 'text-nowrap',
          }}
        />
      </div>

      <TransferToLayingFilterModal
        ref={filterModal.ref}
        onSubmit={filterSubmitHandler}
        onReset={filterResetHandler}
      />

      <ConfirmationModal
        ref={deleteModal.ref}
        iconPosition='left'
        type='error'
        text='Delete This Data?'
        subtitleText='Are you sure you want to delete this data? '
        secondaryButton={{
          text: 'Cancel',
        }}
        primaryButton={{
          text: 'Delete',
          color: 'error',
          isLoading: isDeleteLoading,
          onClick: confirmationModalDeleteClickHandler,
        }}
      />

      <ConfirmationModalWithNotes
        ref={approveModal.ref}
        type='success'
        iconPosition='left'
        text='Approve This Submission?'
        subtitleText='Are you sure you want to approve this submission?'
        secondaryButton={{
          text: 'Cancel',
        }}
        primaryButton={{
          text: 'Approve',
          color: 'success',
          isLoading: isApproveLoading,
          onClick: confirmationModalApproveClickHandler,
        }}
      />

      <ConfirmationModalWithNotes
        ref={rejectModal.ref}
        type='error'
        iconPosition='left'
        text='Reject This Submission?'
        subtitleText='Are you sure you want to reject this submission?'
        secondaryButton={{
          text: 'Cancel',
        }}
        primaryButton={{
          text: 'Reject',
          color: 'error',
          isLoading: isRejectLoading,
          onClick: confirmationModalRejectClickHandler,
        }}
      />
    </>
  );
};

export default TransferToLayingsTable;
