'use client';

import Button from '@/components/Button';
import CheckboxInput from '@/components/input/CheckboxInput';
import SelectInput, {
  OptionType,
  useSelect,
} from '@/components/input/SelectInput';
import Modal, { 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 { TableRowSizeSelector } from '@/components/table/TableRowSizeSelector';
import { TableToolbar } from '@/components/table/TableToolbar';
import { ROWS_OPTIONS } from '@/config/constant';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { cn, formatCurrency, formatDate } from '@/lib/helper';
import {
  MarketingApi,
  SalesOrderApi,
} from '@/services/api/marketing/marketing';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { BaseSalesOrder, Marketing } from '@/types/api/marketing/marketing';
import { Icon } from '@iconify/react';
import { CellContext, Row } from '@tanstack/react-table';
import { useRouter } from 'next/navigation';
import { useCallback, useState } from 'react';
import toast from 'react-hot-toast';
import useSWR from 'swr';
import RequirePermission from '@/components/helper/RequirePermission';
import { useAuth } from '@/services/hooks/useAuth';
import { CustomerApi, ProductApi } from '@/services/api/master-data';
import { MARKETING_APPROVAL_LINE } from '@/config/approval-line';

const RowsOptionsMenu = ({
  type = 'dropdown',
  props,
  deleteClickHandler,
  deliveryClickHandler,
}: {
  type: 'dropdown' | 'collapse';
  props: CellContext<Marketing, unknown>;
  deleteClickHandler: () => void;
  deliveryClickHandler?: () => 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.marketing.delivery_order.detail'>
          <Button
            href={`/marketing/detail?marketingId=${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.latest_approval.step_number != 1 && (
          <>
            <RequirePermission
              permissions={
                props.row.original.latest_approval.step_number == 3
                  ? 'lti.marketing.delivery_order.update'
                  : 'lti.marketing.delivery_order.create'
              }
            >
              <Button
                href={
                  props.row.original.latest_approval.step_number == 3
                    ? `/marketing/detail/delivery-orders/edit?marketingId=${props.row.original.id}`
                    : props.row.original.latest_approval.step_number == 2
                      ? `/marketing/add/delivery-orders?marketingId=${props.row.original.id}`
                      : undefined
                }
                onClick={() => {
                  if (props.row.original.latest_approval.step_number == 2) {
                    deliveryClickHandler?.();
                  }
                }}
                variant='ghost'
                color='success'
                className='justify-start text-sm'
              >
                <Icon icon='mdi:truck' width={16} height={16} />
                Deliver
              </Button>
            </RequirePermission>
          </>
        )}
        {props.row.original.latest_approval.step_number != 3 && (
          <>
            <RequirePermission permissions='lti.marketing.sales_order.update'>
              <Button
                href={`/marketing/detail/sales-orders/edit?marketingId=${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.marketing.sales_order.delete'>
          <Button
            onClick={deleteClickHandler}
            variant='ghost'
            color='error'
            className='text-error hover:text-inherit justify-start text-sm'
          >
            <Icon icon='mdi:delete-outline' width={16} height={16} />
            Delete
          </Button>
        </RequirePermission>
      </div>
    </div>
  );
};

const MarketingTable = () => {
  const [search, setSearch] = useState('');

  const [approveAction, setApproveAction] = useState<'APPROVED' | 'REJECTED'>(
    'APPROVED'
  );
  const [selectedItem, setSelectedItem] = useState<Marketing | null>(null);
  const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
  const { permissionCheck } = useAuth();

  const router = useRouter();
  const deleteModal = useModal();
  const confirmationModal = useModal();
  const productsModal = useModal();
  const deliveryModal = useModal();
  const {
    state: tableFilterState,
    updateFilter,
    setPage,
    setPageSize,
    toQueryString: getTableFilterToQueryString,
  } = useTableFilter({
    initial: {
      search: '',
      product_ids: '',
      status: '',
      customer_id: '',
      page: 1,
      limit: 10,
    },
    paramMap: {
      page: 'page',
      pageSize: 'limit',
      product_ids: 'product_ids',
      status: 'status',
      customer_id: 'customer_id',
    },
  });

  // ===== FETCH DATA =====
  const {
    data: marketing,
    isLoading: isLoadingMarketing,
    mutate: refreshMarketing,
  } = useSWR(
    `${MarketingApi.basePath}${getTableFilterToQueryString()}`,
    MarketingApi.getAllFetcher
  );

  // ===== OPTIONS =====
  const {
    options: productsOptions,
    isLoadingOptions: isLoadingProductsOptions,
  } = useSelect(ProductApi.basePath, 'id', 'name', '', {
    limit: 'limit',
  });

  const {
    options: customersOptions,
    isLoadingOptions: isLoadingCustomersOptions,
  } = useSelect(CustomerApi.basePath, 'id', 'name', '', {
    limit: 'limit',
  });
  const statusOptions = MARKETING_APPROVAL_LINE.map((item) => ({
    value: item.step_number,
    label: item.step_name,
  }));

  // ===== HANDLER =====
  const searchChangeHandler = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      setSearch(e.target.value);
      setPage(1);
    },
    []
  );
  const pageSizeChangeHandler = useCallback(
    (val: OptionType | OptionType[] | null) => {
      const newVal = val as OptionType;
      setPageSize(newVal.value as number);
      updateFilter('page', 1);
      updateFilter('limit', newVal.value as number);
    },
    []
  );

  const approveClickHandler = () => {
    setApproveAction('APPROVED');
    confirmationModal.openModal();
  };

  const rejectClickHandler = () => {
    setApproveAction('REJECTED');
    confirmationModal.openModal();
  };

  const productsClickHandler = (item: Marketing) => {
    setSelectedItem(item);
    productsModal.openModal();
  };

  const deleteMarketingHandler = async () => {
    const deleteMarketingRes = await MarketingApi.delete(
      selectedItem?.id as number
    );
    if (isResponseSuccess(deleteMarketingRes)) {
      confirmationModal.closeModal();
      toast.success(deleteMarketingRes?.message as string);
    }
    if (isResponseError(deleteMarketingRes)) {
      confirmationModal.closeModal();
      toast.error(deleteMarketingRes?.message as string);
    }
    refreshMarketing();
    deleteModal.closeModal();
  };

  const allData = isResponseSuccess(marketing) ? marketing.data : [];
  const selectedRowsData = allData.filter(
    (row) => rowSelection[row.id.toString()]
  );

  const hasApprovable = selectedRowsData.some(
    (row) =>
      row.latest_approval.step_number === 1 &&
      row.latest_approval.action !== 'REJECTED'
  );
  const hasRejectable = selectedRowsData.some(
    (row) =>
      row.latest_approval.step_number === 1 &&
      row.latest_approval.action !== 'REJECTED'
  );

  const disableApprove = !hasApprovable;
  const disableReject = !hasRejectable;

  const idsToProcess =
    approveAction === 'APPROVED'
      ? selectedRowsData
          .filter((row) => row.latest_approval.step_number === 1)
          .map((row) => row.id)
      : selectedRowsData
          .filter((row) => row.latest_approval.step_number === 2)
          .map((row) => row.id);

  const approveMarketingHandler = async (notes: string) => {
    let idsToProcess: number[] = [];

    idsToProcess = selectedRowsData
      .filter((row) => row.latest_approval.step_number === 1)
      .map((row) => row.id);

    if (idsToProcess.length === 0) {
      toast.error(`Tidak ada data yang valid untuk di ${approveAction}.`);
      confirmationModal.closeModal();
      return;
    }

    const approveMarketingRes = await SalesOrderApi.bulkApprovals(
      idsToProcess,
      approveAction,
      notes
    );

    if (isResponseSuccess(approveMarketingRes)) {
      confirmationModal.closeModal();
      toast.success(approveMarketingRes?.message as string);
      setRowSelection({});
    }
    if (isResponseError(approveMarketingRes)) {
      confirmationModal.closeModal();
      toast.error(approveMarketingRes?.message as string);
    }
    refreshMarketing();
  };

  const confirmationModalDeliveryClickHandler = async (notes: string) => {
    const res = await SalesOrderApi.delivery(selectedItem?.id as number, notes);
    deliveryModal.closeModal();
    toast.success(res?.message as string);
    refreshMarketing?.();
    router.push(
      `/marketing/detail/delivery-orders/edit?marketingId=${selectedItem?.id}`
    );
  };

  const getRowCanSelect = (row: Row<Marketing>): boolean => {
    const approval = row.original.latest_approval;
    return approval?.step_number === 1 && approval?.action !== 'REJECTED';
  };

  return (
    <>
      <div className='flex flex-col gap-4'>
        <div className='flex flex-col gap-2 mb-4'>
          <TableToolbar
            addButton={
              permissionCheck('lti.marketing.sales_order.create')
                ? {
                    href: '/marketing/add/sales-orders',
                    label: 'Tambah Sales Order',
                  }
                : undefined
            }
            search={{
              value: search,
              onChange: searchChangeHandler,
              placeholder: 'Cari Sales Order',
            }}
          />
          <div className='flex flex-row gap-2'>
            <RequirePermission permissions='lti.marketing.sales_order.approve'>
              <Button
                color='success'
                onClick={approveClickHandler}
                className='justify-start text-sm'
                disabled={disableApprove}
              >
                <Icon icon='material-symbols:check' width={24} height={24} />
                Approve
              </Button>
            </RequirePermission>

            <RequirePermission permissions='lti.marketing.sales_order.approve'>
              <Button
                color='error'
                onClick={rejectClickHandler}
                className='justify-start text-sm'
                disabled={disableReject}
              >
                <Icon icon='material-symbols:close' width={24} height={24} />
                Reject
              </Button>
            </RequirePermission>
          </div>
          <TableRowSizeSelector
            value={tableFilterState.pageSize}
            onChange={pageSizeChangeHandler}
            options={ROWS_OPTIONS}
            className='flex sm:flex-row flex-col gap-3 items-end justify-end'
          >
            {/* select multiple product */}
            <SelectInput
              label='Product'
              isClearable
              placeholder='Pilih product'
              options={productsOptions}
              isLoading={isLoadingProductsOptions}
              value={
                tableFilterState.product_ids
                  ?.split(',')
                  .map((id) =>
                    productsOptions.find(
                      (option) => option.value === Number(id)
                    )
                  )
                  .filter(
                    (option): option is { value: number; label: string } =>
                      option !== undefined
                  ) ?? null
              }
              onChange={(value: OptionType | OptionType[] | null) =>
                updateFilter(
                  'product_ids',
                  (value as OptionType[])
                    ?.map((item: OptionType) => item.value.toString())
                    .join(',') || ''
                )
              }
              isMulti
            />
            {/* select status */}
            <SelectInput
              label='Status'
              isClearable
              placeholder='Pilih status'
              options={statusOptions}
              value={
                tableFilterState.status
                  ? statusOptions.find(
                      (option) =>
                        option.value === Number(tableFilterState.status)
                    )
                  : null
              }
              onChange={(value: OptionType | OptionType[] | null) =>
                updateFilter(
                  'status',
                  (value as OptionType)?.value.toString() || ''
                )
              }
            />
            {/* select customer */}
            <SelectInput
              label='Customer'
              isClearable
              placeholder='Pilih customer'
              options={customersOptions}
              isLoading={isLoadingCustomersOptions}
              value={
                tableFilterState.customer_id
                  ? customersOptions.find(
                      (option) =>
                        option.value === Number(tableFilterState.customer_id)
                    )
                  : null
              }
              onChange={(value: OptionType | OptionType[] | null) =>
                updateFilter(
                  'customer_id',
                  (value as OptionType)?.value.toString() || ''
                )
              }
            />
          </TableRowSizeSelector>
        </div>
        <Table
          rowSelection={rowSelection}
          setRowSelection={setRowSelection}
          data={allData}
          columns={[
            {
              id: 'select',
              header: ({ table }) => {
                const allRows = table.getRowModel().rows;
                const selectableRows = allRows.filter(getRowCanSelect);

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

                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={selectableRows.length === 0}
                    />
                  </div>
                );
              },
              cell: ({ row }) => {
                const canSelect = getRowCanSelect(row);
                return (
                  <div>
                    <CheckboxInput
                      name='row'
                      checked={row.getIsSelected()}
                      disabled={!canSelect}
                      indeterminate={row.getIsSomeSelected()}
                      onChange={row.getToggleSelectedHandler()}
                    />
                  </div>
                );
              },
            },
            {
              accessorKey: 'so_number',
              header: 'No. Order',
            },
            {
              accessorKey: 'so_date',
              header: 'Tanggal',
              cell: (props) => {
                return formatDate(props.row.original.so_date, 'DD MMM yyyy');
              },
            },
            {
              accessorKey: 'latest_approval.step_name',
              header: 'Status',
            },
            {
              accessorKey: 'customer.name',
              header: 'Customer',
            },
            {
              accessorFn: (row) =>
                row.sales_order
                  ?.map((product) => product.total_price)
                  .reduce((a, b) => a + b, 0) ?? 0,
              header: 'Grand Total',
              cell: (props) => {
                return formatCurrency(
                  props.row.original?.sales_order
                    ?.map((product) => product.total_price)
                    .reduce((a, b) => a + b, 0) ?? 0
                );
              },
            },
            {
              accessorKey: 'marketing_products.length',
              header: 'Product Details',
              cell: (props) => {
                if (props?.row?.original?.sales_order?.length) {
                  if (props?.row?.original?.sales_order?.length > 1) {
                    return (
                      <Button
                        variant='link'
                        color='success'
                        className='p-0 text-none'
                        onClick={() => {
                          productsClickHandler(props?.row?.original);
                        }}
                      >
                        Lihat {props?.row?.original?.sales_order?.length} Produk
                      </Button>
                    );
                  } else {
                    const product = props?.row?.original?.sales_order[0];
                    return <>{product?.product_warehouse?.product?.name}</>;
                  }
                }
              },
            },
            {
              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 = () => {
                  setSelectedItem(props.row.original);
                  deleteModal.openModal();
                };

                const deliveryClickHandler = () => {
                  setSelectedItem(props.row.original);
                  deliveryModal.openModal();
                };

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

                    {currentPageSize <= 2 && (
                      <RowCollapseOptions>
                        <RowsOptionsMenu
                          type='collapse'
                          props={props}
                          deleteClickHandler={deleteClickHandler}
                          deliveryClickHandler={deliveryClickHandler}
                        />
                      </RowCollapseOptions>
                    )}
                  </>
                );
              },
            },
          ]}
          pageSize={tableFilterState.pageSize}
          page={tableFilterState.page}
          onPageChange={setPage}
          className={{
            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>
      <ConfirmationModal
        ref={deleteModal.ref}
        type='error'
        text={`Apakah anda yakin ingin menghapus data Project Flock ini?`}
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: 'error',
        }}
      />

      <ConfirmationModalWithNotes
        ref={confirmationModal.ref}
        type={approveAction === 'APPROVED' ? 'success' : 'error'}
        text={`Apakah anda yakin ingin ${approveAction == 'APPROVED' ? 'approve' : 'reject'} data penjualan (${idsToProcess.length} data)?`}
        secondaryButton={{
          text: 'Tidak',
          onClick: confirmationModal.closeModal,
        }}
        primaryButton={{
          text: 'Ya',
          color: approveAction === 'APPROVED' ? 'success' : 'error',
          onClick: approveMarketingHandler,
        }}
      />
      <ConfirmationModal
        ref={deleteModal.ref}
        type='error'
        text={`Apakah anda yakin ingin menghapus data penjualan ini?`}
        secondaryButton={{
          text: 'Tidak',
          onClick: deleteModal.closeModal,
        }}
        primaryButton={{
          text: 'Ya',
          color: 'error',
          onClick: deleteMarketingHandler,
        }}
      />
      <ConfirmationModalWithNotes
        ref={deliveryModal.ref}
        type={'success'}
        text={`Apakah anda yakin ingin deliver penjualan ${selectedItem?.so_number}?`}
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: 'success',
          onClick: confirmationModalDeliveryClickHandler,
        }}
      />

      <Modal
        ref={productsModal.ref}
        className={{
          modalBox: 'max-w-2/5 z-100',
        }}
        closeOnBackdrop
      >
        <div className='flex flex-row justify-between items-center mb-3'>
          <h4 className='text-xl font-semibold'>Daftar Produk</h4>
          <Button
            variant='ghost'
            color='error'
            onClick={productsModal.closeModal}
            className='justify-start text-sm rounded-full'
          >
            <Icon icon='mdi:close' width={16} height={16} />
          </Button>
        </div>
        <Table<BaseSalesOrder>
          data={
            isResponseSuccess(marketing) && selectedItem
              ? (selectedItem?.sales_order ?? [])
              : []
          }
          columns={[
            {
              header: 'Kandang',
              accessorFn(row) {
                return row.product_warehouse.warehouse.name;
              },
            },
            {
              header: 'Produk',
              accessorFn(row) {
                return row.product_warehouse.product.name;
              },
            },
            {
              header: 'Harga Satuan (Rp)',
              accessorFn(row) {
                return formatCurrency(row.unit_price);
              },
            },
          ]}
          className={{
            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',
            paginationClassName: 'hidden',
          }}
        />
      </Modal>
    </>
  );
};
export default MarketingTable;
