'use client';

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useFormik } from 'formik';

import { Icon } from '@iconify/react';
import Button from '@/components/Button';
import TextInput from '@/components/input/TextInput';
import NumberInput from '@/components/input/NumberInput';
import DateInput from '@/components/input/DateInput';
import SelectInput, {
  OptionType,
  useSelect,
} from '@/components/input/SelectInput';
import {
  CreateMovementPayload,
  Movement,
} from '@/types/api/inventory/movement';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { formatNumber } from '@/lib/helper';
import { useRouter } from 'next/navigation';
import {
  MovementFormSchema,
  MovementFormValues,
  getMovementFormInitialValues,
  ProductSchema,
  DeliverySchema,
} from '@/components/pages/inventory/movement/form/MovementForm.schema';
import { SupplierApi, WarehouseApi } from '@/services/api/master-data';
import { Supplier } from '@/types/api/master-data/supplier';
import { ProductWarehouseApi } from '@/services/api/inventory';
import { toast } from 'react-hot-toast';
import { MovementApi } from '@/services/api/inventory';
import FileInput from '@/components/input/FileInput';
import CheckboxInput from '@/components/input/CheckboxInput';
import Card from '@/components/Card';
import { S3_PUBLIC_BASE_URL } from '@/config/constant';
import { getUniqueFormikErrors } from '@/lib/formik-helper';
import AlertErrorList from '@/components/helper/form/FormErrors';
import { Warehouse } from '@/types/api/master-data/warehouse';
import { ProductWarehouse } from '@/types/api/inventory/product-warehouse';

interface MovementFormProps {
  type?: 'add' | 'edit' | 'detail';
  initialValues?: Movement;
}

const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
  const router = useRouter();

  // ===== STATE MANAGEMENT =====
  const [movementFormErrorMessage, setMovementFormErrorMessage] = useState('');
  const [selectedProducts, setSelectedProducts] = useState<number[]>([]);
  const [selectedDeliveries, setSelectedDeliveries] = useState<number[]>([]);
  const [formErrorList, setFormErrorList] = useState<string[]>([]);
  const [productQtyErrorShown, setProductQtyErrorShown] = useState(false);
  const [deliveryQtyErrorShown, setDeliveryQtyErrorShown] = useState(false);
  const [isInitialized, setIsInitialized] = useState(false);
  const productStockCacheRef = useRef<
    Map<number, { quantity: number; transfer_available_qty?: number }>
  >(new Map());

  // ===== FORM HANDLERS =====
  const createMovementHandler = useCallback(
    async (payload: CreateMovementPayload) => {
      const res = await MovementApi.createMovement(payload);
      if (isResponseError(res)) {
        setMovementFormErrorMessage(res.message);
        return;
      }
      toast.success(res?.message as string);
      router.push('/inventory/movement');
    },
    [router]
  );

  // ===== INTERFACES =====
  interface WarehouseOptionType extends OptionType {
    area?: string;
    location?: string;
  }

  interface ProductWarehouseOptionType extends OptionType {
    product_id: number;
    warehouse_id: number;
    warehouse_name: string;
    quantity: number;
    transfer_available_qty?: number;
  }

  // ===== USE SELECT HOOKS =====
  const {
    setInputValue: setSourceWarehouseSelectInputValue,
    isLoadingOptions: isLoadingSourceWarehouses,
    loadMore: loadMoreSourceWarehouses,
    rawData: sourceWarehouses,
  } = useSelect<Warehouse>(WarehouseApi.basePath, 'id', 'name', 'search', {
    transfer_context: 'inventory_transfer',
  });

  const {
    setInputValue: setWarehouseSelectInputValue,
    isLoadingOptions: isLoadingWarehouses,
    loadMore: loadMoreWarehouses,
    rawData: warehouses,
  } = useSelect<Warehouse>(WarehouseApi.basePath, 'id', 'name', 'search');

  const { rawData: allProductWarehouses } = useSelect<ProductWarehouse>(
    ProductWarehouseApi.basePath,
    'id',
    'product.name',
    'search',
    { limit: '100' }
  );

  // ===== SELECT INPUT DATA =====
  const {
    setInputValue: setSupplierSelectInputValue,
    options: supplierOptions,
    isLoadingOptions: isLoadingSuppliers,
  } = useSelect<Supplier>(SupplierApi.basePath, 'id', 'name', 'search', {
    category: 'BOP',
    flag: 'EKSPEDISI',
  });

  // ===== DATA PROCESSING =====
  const warehouseStockMap = useMemo(() => {
    if (!isResponseSuccess(allProductWarehouses)) return new Map();

    const stockMap = new Map<
      number,
      { totalQty: number; productCount: number }
    >();

    allProductWarehouses.data.forEach((pw) => {
      const warehouseId = pw.warehouse.id;
      const existing = stockMap.get(warehouseId) || {
        totalQty: 0,
        productCount: 0,
      };

      stockMap.set(warehouseId, {
        totalQty: existing.totalQty + pw.quantity,
        productCount: existing.productCount + 1,
      });
    });

    return stockMap;
  }, [allProductWarehouses]);

  const sourceWarehouseOptions = useMemo(() => {
    if (!isResponseSuccess(sourceWarehouses)) return [];

    return (
      sourceWarehouses?.data.map((w) => {
        warehouseStockMap.get(w.id);
        return {
          value: w.id,
          label: w.name,
          area: w.area?.name,
          location:
            'type' in w && (w.type === 'LOKASI' || w.type === 'KANDANG')
              ? w.location?.name
              : undefined,
        };
      }) || []
    );
  }, [sourceWarehouses, warehouseStockMap]);

  const warehouseOptions = useMemo(() => {
    if (!isResponseSuccess(warehouses)) return [];

    return (
      warehouses?.data.map((w) => {
        warehouseStockMap.get(w.id);
        return {
          value: w.id,
          label: w.name,
          area: w.area?.name,
          location:
            'type' in w && (w.type === 'LOKASI' || w.type === 'KANDANG')
              ? w.location?.name
              : undefined,
        };
      }) || []
    );
  }, [warehouses, warehouseStockMap]);

  // ===== FORM INITIALIZATION =====
  const formikInitialValues = useMemo<MovementFormValues>(
    () => getMovementFormInitialValues(initialValues),
    [initialValues]
  );

  const formik = useFormik<MovementFormValues>({
    initialValues: formikInitialValues,
    validationSchema: MovementFormSchema,
    validateOnChange: true,
    validateOnBlur: true,
    validateOnMount: false,
    enableReinitialize: true,
    onSubmit: async (values) => {
      setMovementFormErrorMessage('');
      if (values.source_warehouse_id === values.destination_warehouse_id) {
        const sourceWarehouseName =
          (values.source_warehouse as WarehouseOptionType)?.label ||
          'Gudang asal';
        const destinationWarehouseName =
          (values.destination_warehouse as WarehouseOptionType)?.label ||
          'gudang tujuan';

        setMovementFormErrorMessage(
          `Tidak bisa submit form. ${sourceWarehouseName} tidak boleh sama dengan ${destinationWarehouseName}.`
        );
        toast.error(
          `Tidak bisa submit form. Gudang asal dan tujuan tidak boleh sama!`
        );
        return;
      }
      const documents: File[] = [];
      const documentNameToIndex = new Map<string, number>();
      let sequentialDocumentIndex = 0;

      const deliveriesPayload = values.deliveries.map((d) => {
        let documentIndex = -1;

        if (d.document && d.document instanceof File) {
          const fileName = d.document.name;

          if (documentNameToIndex.has(fileName)) {
            documentIndex = documentNameToIndex.get(fileName)!;
          } else {
            documents.push(d.document);
            documentIndex = sequentialDocumentIndex;
            documentNameToIndex.set(fileName, documentIndex);
            sequentialDocumentIndex++;
          }
        } else if (d.document_path) {
          const pathFileName =
            d.document_path.split('/').pop() || d.document_path;

          if (documentNameToIndex.has(pathFileName)) {
            documentIndex = documentNameToIndex.get(pathFileName)!;
          } else {
            documentIndex = sequentialDocumentIndex;
            documentNameToIndex.set(pathFileName, documentIndex);
            sequentialDocumentIndex++;
          }
        } else if (d.document && !(d.document instanceof File)) {
          const existingDocFileName =
            d.document.path.split('/').pop() || d.document.path;

          if (documentNameToIndex.has(existingDocFileName)) {
            documentIndex = documentNameToIndex.get(existingDocFileName)!;
          } else {
            documentIndex = sequentialDocumentIndex;
            documentNameToIndex.set(existingDocFileName, documentIndex);
            sequentialDocumentIndex++;
          }
        }

        const deliveryObj: {
          products: Array<{ product_id: number; product_qty: number }>;
          delivery_cost?: number;
          delivery_cost_per_item?: number;
          document_index?: number;
          driver_name?: string;
          vehicle_plate?: string;
          supplier_id?: number;
        } = {
          products: d.products.map((p) => ({
            product_id: p.product_id,
            product_qty: parseInt(p.product_qty.toString()) || 0,
          })),
        };

        const deliveryCost = parseInt((d.delivery_cost || '').toString()) || 0;
        if (deliveryCost > 0) {
          deliveryObj.delivery_cost = deliveryCost;
        }

        const deliveryCostPerItem =
          parseInt((d.delivery_cost_per_item || '').toString()) || 0;
        if (deliveryCostPerItem > 0) {
          deliveryObj.delivery_cost_per_item = deliveryCostPerItem;
        }

        if (documentIndex >= 0) {
          deliveryObj.document_index = documentIndex;
        }

        if (d.driver_name) {
          deliveryObj.driver_name = d.driver_name;
        }

        if (d.vehicle_plate) {
          deliveryObj.vehicle_plate = d.vehicle_plate;
        }

        if (d.supplier_id) {
          deliveryObj.supplier_id = d.supplier_id;
        }

        return deliveryObj;
      });

      const payload: CreateMovementPayload = {
        data: {
          transfer_reason: values.transfer_reason,
          transfer_date: values.transfer_date,
          source_warehouse_id: values.source_warehouse_id,
          destination_warehouse_id: values.destination_warehouse_id,
          products: values.products.map((p) => ({
            product_id: p.product_id,
            product_qty: parseInt(p.product_qty.toString()) || 0,
          })),
          deliveries: deliveriesPayload,
        },
        documents: documents.length > 0 ? documents : undefined,
      };

      switch (type) {
        case 'add':
          await createMovementHandler(payload);
          break;
      }
    },
  });

  const prevSourceWarehouseIdRef = useRef<number | null>(
    formik.values.source_warehouse_id
  );

  // ===== RESET PRODUCTS WHEN SOURCE WAREHOUSE CHANGES =====
  useEffect(() => {
    const prevSourceWarehouseId = prevSourceWarehouseIdRef.current;
    const currentSourceWarehouseId = formik.values.source_warehouse_id;

    if (
      prevSourceWarehouseId !== currentSourceWarehouseId &&
      prevSourceWarehouseId !== null
    ) {
      productStockCacheRef.current = new Map();
      formik.setFieldValue('products', [
        {
          product: null,
          product_id: 0,
          product_qty: '',
        },
      ]);
      formik.setFieldTouched('products', false);

      const updatedDeliveries = formik.values.deliveries.map(
        (delivery: DeliverySchema) => ({
          ...delivery,
          products: [
            {
              product: null,
              product_id: 0,
              product_qty: '',
            },
          ],
        })
      );
      formik.setFieldValue('deliveries', updatedDeliveries);
      formik.setFieldTouched('deliveries', false);
    }

    prevSourceWarehouseIdRef.current = currentSourceWarehouseId;
  }, [formik.values.source_warehouse_id, formik.values.deliveries]);

  // ===== PRODUCT WAREHOUSE FETCHING (after form initialization) =====
  const {
    setInputValue: setProductWarehouseSelectInputValue,
    isLoadingOptions: isLoadingProductWarehouses,
    loadMore: loadMoreProductWarehouses,
    rawData: productWarehouses,
  } = useSelect<ProductWarehouse>(
    formik.values.source_warehouse_id ? ProductWarehouseApi.basePath : null,
    'id',
    'name',
    'search',
    {
      warehouse_id: formik.values.source_warehouse_id
        ? formik.values.source_warehouse_id.toString()
        : '',
      transfer_context: 'inventory_transfer',
      stock_mode: 'exclude_chickin',
    }
  );

  const productWarehouseOptions = useMemo(() => {
    return isResponseSuccess(productWarehouses)
      ? productWarehouses?.data.map((pw) => ({
          value: pw.product.id,
          label: pw.product.name,
          product_id: pw.product.id,
          warehouse_id: pw.warehouse.id,
          warehouse_name: pw.warehouse.name,
          quantity: pw.quantity,
          transfer_available_qty: pw.transfer_available_qty,
        }))
      : [];
  }, [productWarehouses]);

  useEffect(() => {
    productWarehouseOptions.forEach((pw) => {
      productStockCacheRef.current.set(pw.product_id, {
        quantity: pw.quantity,
        transfer_available_qty: pw.transfer_available_qty,
      });
    });
  }, [productWarehouseOptions]);

  // ===== HELPER FUNCTIONS =====
  const isRepeaterInputError = <T extends 'products' | 'deliveries'>(
    arrayName: T,
    column: T extends 'products' ? keyof ProductSchema : keyof DeliverySchema,
    idx: number
  ) => {
    if (
      !formik.touched[arrayName] ||
      !Array.isArray(formik.touched[arrayName])
    ) {
      return {
        isError: false,
        errorMessage: '',
      };
    }

    const touchedField = formik.touched[arrayName]?.[idx]?.[column as string];
    const errorField = formik.errors[arrayName]?.[idx] as Record<
      string,
      string
    >;

    return {
      isError: touchedField && Boolean(errorField?.[column as string]),
      errorMessage:
        touchedField && errorField?.[column as string]
          ? errorField[column as string]
          : '',
    };
  };

  const isDeliveryProductInputError = (
    deliveryIdx: number,
    productIdx: number,
    column: keyof DeliverySchema['products'][number]
  ) => {
    const touchedDelivery = formik.touched.deliveries?.[deliveryIdx];
    const errorDelivery = formik.errors.deliveries?.[deliveryIdx] as
      | { products: Array<Record<string, string>> }
      | undefined;

    if (!touchedDelivery?.products || !errorDelivery?.products) {
      return {
        isError: false,
        errorMessage: '',
      };
    }

    const touchedField = touchedDelivery.products[productIdx]?.[column];
    const errorField = errorDelivery.products[productIdx]?.[column];

    return {
      isError: Boolean(touchedField && errorField),
      errorMessage: touchedField && errorField ? errorField : '',
    };
  };

  // ===== EVENT HANDLERS =====
  const handleTransferDateChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      formik.setFieldValue('transfer_date', e.target.value);
    },
    []
  );

  const handleSourceWarehouseChange = useCallback(
    (val: OptionType | OptionType[] | null) => {
      const newSourceWarehouseId = (val as WarehouseOptionType)?.value;

      if (
        newSourceWarehouseId &&
        newSourceWarehouseId === formik.values.destination_warehouse_id
      ) {
        const destinationWarehouseName =
          (formik.values.destination_warehouse as WarehouseOptionType)?.label ||
          'gudang tujuan';
        toast.error(
          `Tidak bisa memilih gudang yang sama. Gudang asal tidak boleh sama dengan ${destinationWarehouseName}.`
        );
        return;
      }

      formik.setFieldTouched('source_warehouse', true);
      formik.setFieldValue('source_warehouse', val);
      formik.setFieldTouched('source_warehouse_id', true);
      formik.setFieldValue('source_warehouse_id', newSourceWarehouseId);
    },
    [
      formik.values.destination_warehouse_id,
      formik.values.destination_warehouse,
    ]
  );

  const handleDestinationWarehouseChange = useCallback(
    (val: OptionType | OptionType[] | null) => {
      const newDestinationWarehouseId = (val as WarehouseOptionType)?.value;

      if (
        newDestinationWarehouseId &&
        newDestinationWarehouseId === formik.values.source_warehouse_id
      ) {
        const sourceWarehouseName =
          (formik.values.source_warehouse as WarehouseOptionType)?.label ||
          'gudang asal';
        toast.error(
          `Tidak bisa memilih gudang yang sama. Gudang tujuan tidak boleh sama dengan ${sourceWarehouseName}.`
        );
        return;
      }

      formik.setFieldTouched('destination_warehouse', true);
      formik.setFieldValue('destination_warehouse', val);
      formik.setFieldTouched('destination_warehouse_id', true);
      formik.setFieldValue(
        'destination_warehouse_id',
        newDestinationWarehouseId
      );
    },
    [formik.values.source_warehouse_id, formik.values.source_warehouse]
  );

  const addProduct = useCallback(() => {
    const newProducts = [
      ...(formik.values.products || []),
      {
        product: null,
        product_id: 0,
        product_qty: '',
      },
    ];
    formik.setFieldValue('products', newProducts);
  }, [formik.values.products]);

  const removeProduct = useCallback(
    (i: number) => {
      const updatedProducts = formik.values.products?.filter(
        (_, idx) => idx !== i
      );
      formik.setFieldValue('products', updatedProducts);

      setSelectedProducts([]);

      if (productQtyErrorShown) {
        toast.dismiss();
        setProductQtyErrorShown(false);
      }
    },
    [formik.values.products, productQtyErrorShown, setSelectedProducts]
  );

  const bulkRemoveProduct = useCallback(() => {
    const updatedProducts =
      formik.values.products?.filter(
        (_, idx) => !selectedProducts.includes(idx)
      ) ?? [];
    formik.setFieldValue('products', updatedProducts);
    setSelectedProducts([]);

    if (productQtyErrorShown) {
      toast.dismiss();
      setProductQtyErrorShown(false);
    }
  }, [formik, selectedProducts, setSelectedProducts, productQtyErrorShown]);

  const handleProductChange = useCallback(
    (idx: number, val: OptionType | OptionType[] | null) => {
      formik.setFieldTouched(`products.${idx}.product`, true);
      formik.setFieldValue(`products.${idx}.product`, val);
      formik.setFieldTouched(`products.${idx}.product_id`, true);
      formik.setFieldValue(
        `products.${idx}.product_id`,
        (val as ProductWarehouseOptionType)?.value
      );
    },
    []
  );

  const handleProductSelectAllChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      if (e.target.checked) {
        setSelectedProducts(formik.values.products?.map((_, idx) => idx) ?? []);
      } else {
        setSelectedProducts([]);
      }
    },
    [formik.values.products, setSelectedProducts]
  );

  const handleProductCheckboxChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const idx = Number(e.target.name.replace('product-', ''));
      if (e.target.checked) {
        setSelectedProducts((prev) => [...prev, idx]);
      } else {
        setSelectedProducts((prev) => prev.filter((i) => i !== idx));
      }
    },
    [setSelectedProducts]
  );

  const addDelivery = useCallback(() => {
    formik.setFieldValue('deliveries', [
      ...(formik.values.deliveries || []),
      {
        delivery_cost: '',
        delivery_cost_per_item: '',
        document: null,
        driver_name: '',
        vehicle_plate: '',
        supplier: null,
        supplier_id: 0,
        products: [
          {
            product: null,
            product_id: 0,
            product_qty: '',
          },
        ],
      },
    ]);
  }, [formik.values.deliveries]);

  const removeDelivery = useCallback(
    (i: number) => {
      const updatedDeliveries = formik.values.deliveries?.filter(
        (_, idx) => idx !== i
      );
      formik.setFieldValue('deliveries', updatedDeliveries);

      setSelectedDeliveries([]);

      if (deliveryQtyErrorShown) {
        toast.dismiss();
        setDeliveryQtyErrorShown(false);
      }
    },
    [formik.values.deliveries, deliveryQtyErrorShown, setSelectedDeliveries]
  );

  const bulkRemoveDelivery = useCallback(() => {
    const updatedDeliveries =
      formik.values.deliveries?.filter(
        (_, idx) => !selectedDeliveries.includes(idx)
      ) ?? [];
    formik.setFieldValue('deliveries', updatedDeliveries);
    setSelectedDeliveries([]);

    if (deliveryQtyErrorShown) {
      toast.dismiss();
      setDeliveryQtyErrorShown(false);
    }
  }, [
    formik,
    selectedDeliveries,
    setSelectedDeliveries,
    deliveryQtyErrorShown,
  ]);

  const handleDeliverySelectAllChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      if (e.target.checked) {
        setSelectedDeliveries(
          formik.values.deliveries?.map((_, idx) => idx) ?? []
        );
      } else {
        setSelectedDeliveries([]);
      }
    },
    [formik.values.deliveries, setSelectedDeliveries]
  );

  const handleDeliveryCheckboxChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const idx = Number(e.target.name.replace('delivery-', ''));
      if (e.target.checked) {
        setSelectedDeliveries((prev) => [...prev, idx]);
      } else {
        setSelectedDeliveries((prev) => prev.filter((i) => i !== idx));
      }
    },
    [setSelectedDeliveries]
  );

  const handleDeliveryProductChange = useCallback(
    (deliveryIdx: number, val: OptionType | OptionType[] | null) => {
      formik.setFieldTouched(
        `deliveries.${deliveryIdx}.products.0.product`,
        true
      );
      formik.setFieldValue(`deliveries.${deliveryIdx}.products.0.product`, val);
      formik.setFieldTouched(
        `deliveries.${deliveryIdx}.products.0.product_id`,
        true
      );
      formik.setFieldValue(
        `deliveries.${deliveryIdx}.products.0.product_id`,
        (val as OptionType)?.value
      );
    },
    []
  );

  const handleDeliverySupplierChange = useCallback(
    (deliveryIdx: number, val: OptionType | OptionType[] | null) => {
      formik.setFieldTouched(`deliveries.${deliveryIdx}.supplier`, true);
      formik.setFieldValue(`deliveries.${deliveryIdx}.supplier`, val);
      formik.setFieldTouched(`deliveries.${deliveryIdx}.supplier_id`, true);
      formik.setFieldValue(
        `deliveries.${deliveryIdx}.supplier_id`,
        (val as OptionType)?.value
      );
    },
    []
  );

  const handleDeliveryDocumentChange = useCallback(
    (deliveryIdx: number, e: React.ChangeEvent<HTMLInputElement>) => {
      const file = e.target.files?.[0];
      if (file) {
        if (file.size > 5 * 1024 * 1024) {
          toast.error('Ukuran dokumen maksimal 5 MB!');
          e.target.value = '';
          return;
        }
        formik.setFieldValue(`deliveries.${deliveryIdx}.document`, file);
      }
    },
    []
  );

  const handleDeliveryCostChange = useCallback(
    (idx: number, value: number) => {
      formik.setFieldValue(`deliveries.${idx}.delivery_cost`, value);

      const delivery = formik.values.deliveries?.[idx];
      if (delivery) {
        const productQty = delivery.products.reduce(
          (sum, p) => sum + (parseInt(p.product_qty.toString()) || 0),
          0
        );
        if (productQty > 0 && value > 0) {
          const perItem = value / productQty;
          formik.setFieldValue(
            `deliveries.${idx}.delivery_cost_per_item`,
            perItem
          );
        } else if (value === 0) {
          formik.setFieldValue(`deliveries.${idx}.delivery_cost_per_item`, 0);
        }
      }
    },
    [formik.values.deliveries]
  );

  const handleDeliveryCostPerItemChange = useCallback(
    (idx: number, value: number) => {
      formik.setFieldValue(`deliveries.${idx}.delivery_cost_per_item`, value);

      const delivery = formik.values.deliveries?.[idx];
      if (delivery) {
        const productQty = delivery.products.reduce(
          (sum, p) => sum + (parseInt(p.product_qty.toString()) || 0),
          0
        );
        if (productQty > 0 && value > 0) {
          const totalCost = value * productQty;
          formik.setFieldValue(`deliveries.${idx}.delivery_cost`, totalCost);
        } else if (value === 0) {
          formik.setFieldValue(`deliveries.${idx}.delivery_cost`, 0);
        }
      }
    },
    [formik.values.deliveries]
  );

  const handleDeliveryCostChangeWrapper = useCallback(
    (idx: number) => (e: React.ChangeEvent<HTMLInputElement>) => {
      const value = parseFloat(e.target.value) || 0;
      handleDeliveryCostChange(idx, value);
    },
    [handleDeliveryCostChange]
  );

  const handleDeliveryCostPerItemChangeWrapper = useCallback(
    (idx: number) => (e: React.ChangeEvent<HTMLInputElement>) => {
      const value = parseFloat(e.target.value) || 0;
      handleDeliveryCostPerItemChange(idx, value);
    },
    [handleDeliveryCostPerItemChange]
  );

  const getAvailableProductOptions = useCallback(
    (currentIdx: number) => {
      const selectedProductIds =
        formik.values.products
          ?.filter((p, idx) => {
            return idx !== currentIdx && p.product_id && p.product_id !== 0;
          })
          .map((p) => p.product_id) || [];

      return productWarehouseOptions.filter(
        (pw) => !selectedProductIds.includes(pw.product_id)
      );
    },
    [formik.values.products, productWarehouseOptions]
  );

  const getFilteredProductWarehouseOptions = useCallback(() => {
    return (
      formik.values.products
        ?.filter((p) => p.product)
        .map((p) => {
          const totalQtyUsed =
            formik.values.deliveries?.reduce((total, d) => {
              const productQty = d.products.reduce((sum, deliveryProduct) => {
                if (deliveryProduct.product_id === p.product_id) {
                  return sum + (Number(deliveryProduct.product_qty) || 0);
                }
                return sum;
              }, 0);
              return total + productQty;
            }, 0) || 0;

          const availableQty = Number(p.product_qty) - totalQtyUsed;

          if (availableQty > 0) {
            return {
              value: p.product_id,
              label: (p.product as OptionType)?.label,
            };
          }

          return null;
        })
        .filter((option) => option !== null) ?? []
    );
  }, [formik.values.products, formik.values.deliveries]);

  const getAvailableStock = useCallback(
    (productId: number) => {
      if (type === 'detail') return 0;
      const live = productWarehouseOptions.find(
        (pw) => pw.product_id === productId
      );
      if (live) return live.transfer_available_qty ?? live.quantity ?? 0;
      const cached = productStockCacheRef.current.get(productId);
      return cached?.transfer_available_qty ?? cached?.quantity ?? 0;
    },
    [productWarehouseOptions, type]
  );

  const getTotalStock = useCallback(
    (productId: number) => {
      if (type === 'detail') return 0;
      const live = productWarehouseOptions.find(
        (pw) => pw.product_id === productId
      );
      if (live) return live.quantity ?? 0;
      return productStockCacheRef.current.get(productId)?.quantity ?? 0;
    },
    [productWarehouseOptions, type]
  );

  const hasAvailableQty = useCallback(
    (productId: number) => {
      const live = productWarehouseOptions.find(
        (pw) => pw.product_id === productId
      );
      if (live) return live.transfer_available_qty !== undefined;
      return (
        productStockCacheRef.current.get(productId)?.transfer_available_qty !==
        undefined
      );
    },
    [productWarehouseOptions]
  );

  const getProductQtyBottomLabel = useCallback(
    (productIdx: number) => {
      if (type === 'detail') return undefined;
      const product = formik.values.products?.[productIdx];
      if (!product || !product.product_id) return undefined;

      const availableStock = getAvailableStock(product.product_id);
      const totalStock = getTotalStock(product.product_id);
      const requestedQty = Number(product.product_qty) || 0;
      const remainingStock = availableStock - requestedQty;
      const isAyamProduct = hasAvailableQty(product.product_id);

      if (requestedQty > 0) {
        if (isAyamProduct) {
          return `Sisa: ${formatNumber(remainingStock)} (Total: ${formatNumber(totalStock)})`;
        }
        return `Sisa: ${formatNumber(remainingStock)}`;
      }

      if (isAyamProduct) {
        return `Tersedia: ${formatNumber(availableStock)} (Total: ${formatNumber(totalStock)})`;
      }

      return `Tersedia: ${formatNumber(availableStock)}`;
    },
    [
      formik.values.products,
      getAvailableStock,
      getTotalStock,
      hasAvailableQty,
      type,
    ]
  );

  const getDeliveryProductQtyBottomLabel = useCallback(
    (deliveryIdx: number, productIdx: number) => {
      if (type === 'detail') return undefined;
      const delivery = formik.values.deliveries?.[deliveryIdx];
      if (!delivery) return undefined;

      const deliveryProduct = delivery.products[productIdx];
      if (!deliveryProduct || !deliveryProduct.product_id) return undefined;

      const relatedProduct = formik.values.products?.find(
        (p) => p.product_id === deliveryProduct.product_id
      );
      if (!relatedProduct) return undefined;

      const totalQtyUsed =
        formik.values.deliveries?.reduce((total, d) => {
          const productQty = d.products.reduce((sum, p) => {
            if (p.product_id === deliveryProduct.product_id) {
              return sum + (Number(p.product_qty) || 0);
            }
            return sum;
          }, 0);
          return total + productQty;
        }, 0) || 0;

      const availableQty = Number(relatedProduct.product_qty) - totalQtyUsed;

      const displayQty = availableQty > 0 ? availableQty : 0;

      return `Tersedia: ${formatNumber(displayQty)}`;
    },
    [formik.values.deliveries, formik.values.products, type]
  );

  const getWarehouseStockAdornment = useCallback(
    (warehouseId: number) => {
      const stockInfo = warehouseStockMap.get(warehouseId);
      if (!stockInfo) {
        return <span className='text-xs'>Kosong</span>;
      }

      const { productCount } = stockInfo;

      return (
        <span className='text-xs whitespace-nowrap'>
          Tersedia {productCount} produk
        </span>
      );
    },
    [warehouseStockMap]
  );

  const getProductQtyError = useCallback(
    (productIdx: number) => {
      if (type === 'detail') return null;
      const product = formik.values.products?.[productIdx];
      if (!product || !product.product_id) return null;

      const availableStock = getAvailableStock(product.product_id);
      const totalStock = getTotalStock(product.product_id);
      const requestedQty = Number(product.product_qty) || 0;
      const isAyamProduct = hasAvailableQty(product.product_id);

      if (requestedQty > availableStock) {
        if (isAyamProduct) {
          return `Qty melebihi stok tersedia! Maksimal: ${formatNumber(availableStock)} (Total: ${formatNumber(totalStock)}, terpakai untuk chickin: ${formatNumber(totalStock - availableStock)})`;
        }
        return `Qty melebihi stok tersedia! Maksimal: ${formatNumber(availableStock)}`;
      }

      return null;
    },
    [
      formik.values.products,
      getAvailableStock,
      getTotalStock,
      hasAvailableQty,
      type,
    ]
  );

  const validateDeliveryQty = useCallback(
    (deliveryIdx: number, deliveryProductIdx: number, qty: number) => {
      if (type === 'detail') return true;
      const delivery = formik.values.deliveries?.[deliveryIdx];
      if (!delivery) return true;

      const deliveryProduct = delivery.products[deliveryProductIdx];
      if (!deliveryProduct) return true;

      const productId = deliveryProduct.product_id;
      if (!productId) return true;

      const relatedProduct = formik.values.products?.find(
        (p) => p.product_id === productId
      );
      if (!relatedProduct) return true;

      const totalQtyUsed =
        formik.values.deliveries?.reduce((total, d, dIdx) => {
          const productQty = d.products.reduce((sum, p, pIdx) => {
            if (
              p.product_id === productId &&
              !(dIdx === deliveryIdx && pIdx === deliveryProductIdx)
            ) {
              return sum + (Number(p.product_qty) || 0);
            }
            return sum;
          }, 0);
          return total + productQty;
        }, 0) || 0;

      return totalQtyUsed + qty <= Number(relatedProduct.product_qty);
    },
    [formik.values.deliveries, formik.values.products, type]
  );

  const getDeliveryQtyError = useCallback(
    (deliveryIdx: number, deliveryProductIdx: number) => {
      if (type === 'detail') return null;
      const delivery = formik.values.deliveries?.[deliveryIdx];
      if (!delivery) return null;

      const deliveryProduct = delivery.products[deliveryProductIdx];
      if (!deliveryProduct || !deliveryProduct.product_id) return null;

      const qty = Number(deliveryProduct.product_qty) || 0;
      const productId = deliveryProduct.product_id;

      const relatedProduct = formik.values.products?.find(
        (p) => p.product_id === productId
      );
      if (!relatedProduct) return null;

      const totalQtyUsed =
        formik.values.deliveries?.reduce((total, d, dIdx) => {
          const productQty = d.products.reduce((sum, p, pIdx) => {
            if (
              p.product_id === productId &&
              !(dIdx === deliveryIdx && pIdx === deliveryProductIdx)
            ) {
              return sum + (Number(p.product_qty) || 0);
            }
            return sum;
          }, 0);
          return total + productQty;
        }, 0) || 0;

      const availableQty = Number(relatedProduct.product_qty) - totalQtyUsed;

      if (totalQtyUsed + qty > Number(relatedProduct.product_qty)) {
        return `Qty melebihi stok produk! Tersedia: ${availableQty}, Total digunakan: ${totalQtyUsed + qty}`;
      }

      return null;
    },
    [formik.values.deliveries, formik.values.products, type]
  );

  const isSupplierSelected = useCallback(
    (deliveryIdx: number) => {
      const delivery = formik.values.deliveries?.[deliveryIdx];
      return (
        delivery &&
        delivery.supplier_id !== null &&
        delivery.supplier_id !== undefined &&
        delivery.supplier_id > 0
      );
    },
    [formik.values.deliveries]
  );

  const hasAnySupplierSelected = useMemo(() => {
    return formik.values.deliveries?.some(
      (delivery) =>
        delivery.supplier_id !== null &&
        delivery.supplier_id !== undefined &&
        delivery.supplier_id > 0
    );
  }, [formik.values.deliveries]);

  // ===== COMPUTED VALUES =====
  const invalidQtyRows = useMemo(
    () =>
      type === 'detail'
        ? []
        : (formik.values.deliveries?.flatMap((delivery, deliveryIdx) =>
            delivery.products.map((product, productIdx) => {
              const qty = Number(product.product_qty) || 0;
              return !validateDeliveryQty(deliveryIdx, productIdx, qty);
            })
          ) ?? []),
    [
      formik.values.deliveries,
      formik.values.products,
      validateDeliveryQty,
      type,
    ]
  );

  const hasInvalidQty = useMemo(
    () => (type === 'detail' ? false : invalidQtyRows.some(Boolean)),
    [invalidQtyRows, type]
  );

  const hasExceededStock = useMemo(() => {
    if (type === 'detail') return false;
    return (
      formik.values.products?.some((product, idx) => {
        return getProductQtyError(idx) !== null;
      }) ?? false
    );
  }, [formik.values.products, getProductQtyError, type]);

  // ===== EFFECTS =====
  useEffect(() => {
    formik.values.deliveries?.forEach((delivery, idx) => {
      const productQty = delivery.products.reduce(
        (sum, p) => sum + (parseInt(p.product_qty.toString()) || 0),
        0
      );

      const deliveryCost =
        parseInt((delivery.delivery_cost || '').toString()) || 0;
      const deliveryCostPerItem =
        parseInt((delivery.delivery_cost_per_item || '').toString()) || 0;

      if (deliveryCost > 0 && productQty > 0) {
        const perItem = deliveryCost / productQty;
        if (Math.abs(deliveryCostPerItem - perItem) > 0.01) {
          formik.setFieldValue(
            `deliveries.${idx}.delivery_cost_per_item`,
            perItem
          );
        }
      } else if (deliveryCostPerItem > 0 && productQty > 0) {
        const totalCost = deliveryCostPerItem * productQty;
        if (Math.abs(deliveryCost - totalCost) > 0.01) {
          formik.setFieldValue(`deliveries.${idx}.delivery_cost`, totalCost);
        }
      }
    });
  }, [
    formik.values.deliveries
      ?.map((d, idx) => ({
        idx,
        productQty: d.products.reduce(
          (sum, p) => sum + (parseInt(p.product_qty.toString()) || 0),
          0
        ),
        deliveryCost: parseInt((d.delivery_cost || '').toString()) || 0,
        deliveryCostPerItem:
          parseInt((d.delivery_cost_per_item || '').toString()) || 0,
      }))
      .map(
        (item) =>
          `${item.idx}:${item.productQty}:${item.deliveryCost}:${item.deliveryCostPerItem}`
      )
      .join('|'),
  ]);

  useEffect(() => {
    if (
      formik.values.source_warehouse_id &&
      type !== 'edit' &&
      type !== 'detail' &&
      !isInitialized
    ) {
      if (formik.values.products.length === 0) {
        formik.setFieldValue('products', [
          {
            product: null,
            product_id: 0,
            product_qty: '',
          },
        ]);
      }
      if (formik.values.deliveries.length === 0) {
        formik.setFieldValue('deliveries', [
          {
            delivery_cost: undefined,
            delivery_cost_per_item: undefined,
            document: null,
            document_path: null,
            driver_name: '',
            vehicle_plate: '',
            supplier: null,
            supplier_id: 0,
            products: [
              {
                product: null,
                product_id: 0,
                product_qty: '',
              },
            ],
          },
        ]);
      }
      setIsInitialized(true);
    }
  }, [formik.values.source_warehouse_id, isInitialized, type]);

  useEffect(() => {
    if (
      formik.values.source_warehouse_id &&
      formik.values.destination_warehouse_id &&
      formik.values.source_warehouse_id ===
        formik.values.destination_warehouse_id
    ) {
      formik.setFieldError(
        'destination_warehouse_id',
        'Gudang tujuan tidak boleh sama dengan gudang asal!'
      );
    } else {
      if (
        formik.errors.destination_warehouse_id ===
        'Gudang tujuan tidak boleh sama dengan gudang asal!'
      ) {
        formik.setFieldError('destination_warehouse_id', undefined);
      }
    }
  }, [
    formik.values.source_warehouse_id,
    formik.values.destination_warehouse_id,
    formik.errors.destination_warehouse_id,
  ]);

  useEffect(() => {
    if (formik.values.products && formik.values.deliveries) {
      const productIds = formik.values.products.map((p) => p.product_id);

      const updatedDeliveries = formik.values.deliveries.map((delivery) => {
        const deliveryProduct = delivery.products[0];
        if (deliveryProduct && deliveryProduct.product_id !== 0) {
          if (!productIds.includes(deliveryProduct.product_id)) {
            return {
              ...delivery,
              products: [
                {
                  product: null,
                  product_id: 0,
                  product_qty: '',
                },
              ],
              delivery_cost: '',
              delivery_cost_per_item: '',
            };
          }
        }
        return delivery;
      });

      const hasChanges = formik.values.deliveries.some(
        (delivery, idx) =>
          delivery.products[0]?.product_id !==
            updatedDeliveries[idx]?.products[0]?.product_id ||
          delivery.delivery_cost !== updatedDeliveries[idx]?.delivery_cost
      );

      if (hasChanges) {
        formik.setFieldValue('deliveries', updatedDeliveries);
      }
    }
  }, [formik.values.products]);

  useEffect(() => {
    if (productQtyErrorShown) {
      toast.dismiss();
      setProductQtyErrorShown(false);
    }
  }, [formik.values.products?.map((p) => p.product_qty).join(',')]);

  useEffect(() => {
    if (deliveryQtyErrorShown) {
      toast.dismiss();
      setDeliveryQtyErrorShown(false);
    }
  }, [
    formik.values.deliveries
      ?.map((d) => d.products.map((p) => p.product_qty).join(','))
      .join('|'),
    formik.values.products?.map((p) => p.product_qty).join(','),
  ]);

  useEffect(() => {
    if (hasExceededStock && !productQtyErrorShown && type !== 'detail') {
      const firstErrorIndex = formik.values.products?.findIndex(
        (product, idx) => getProductQtyError(idx) !== null
      );
      if (firstErrorIndex !== undefined && firstErrorIndex >= 0) {
        const errorMsg = getProductQtyError(firstErrorIndex);
        if (errorMsg) {
          toast.error(errorMsg, { duration: Infinity });
          setProductQtyErrorShown(true);
        }
      }
    }
  }, [
    hasExceededStock,
    productQtyErrorShown,
    type,
    formik.values.products,
    getProductQtyError,
  ]);

  useEffect(() => {
    if (hasInvalidQty && !deliveryQtyErrorShown && type !== 'detail') {
      const firstError = formik.values.deliveries?.find(
        (delivery, deliveryIdx) =>
          delivery.products.some(
            (product, productIdx) =>
              getDeliveryQtyError(deliveryIdx, productIdx) !== null
          )
      );
      if (firstError) {
        const deliveryIdx = formik.values.deliveries?.indexOf(firstError);
        if (deliveryIdx !== undefined && deliveryIdx >= 0) {
          const errorMsg = getDeliveryQtyError(deliveryIdx, 0);
          if (errorMsg) {
            toast.error(errorMsg, { duration: Infinity });
            setDeliveryQtyErrorShown(true);
          }
        }
      }
    }
  }, [
    hasInvalidQty,
    deliveryQtyErrorShown,
    type,
    formik.values.deliveries,
    formik.values.products,
    getDeliveryQtyError,
  ]);

  const handleValidateForm = async () => {
    const errors = await formik.validateForm();

    if (Object.keys(errors).length > 0) {
      const errorMessages = getUniqueFormikErrors(errors);
      setFormErrorList(errorMessages);
      return;
    }
  };

  const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    handleValidateForm();
    formik.handleSubmit(e);
  };

  return (
    <>
      <section className='w-full'>
        <header className='flex flex-col gap-4'>
          <Button
            href='/inventory/movement'
            variant='link'
            className='w-fit p-0 text-primary'
          >
            <Icon icon='uil:arrow-left' width={24} height={24} />
            Kembali
          </Button>
          <h1 className='text-2xl font-bold text-center'>
            {type === 'add' && 'Tambah Movement'}
            {type === 'edit' && 'Edit Movement'}
            {type === 'detail' && 'Detail Movement'}
          </h1>
        </header>
        <form
          onSubmit={handleFormSubmit}
          onReset={formik.handleReset}
          className='w-full mt-8 flex flex-col gap-6'
        >
          {/* Top card - Movement details */}
          <Card
            title='Detail Movement'
            className={{
              wrapper: 'w-full mb-4 shadow',
              body: 'flex flex-col gap-6',
            }}
          >
            <div className='grid grid-cols-1 md:grid-cols-2 gap-4'>
              <TextInput
                required
                label='Alasan Transfer'
                name='transfer_reason'
                placeholder='Masukkan alasan transfer...'
                value={formik.values.transfer_reason}
                onChange={formik.handleChange}
                onBlur={formik.handleBlur}
                isError={
                  formik.touched.transfer_reason &&
                  Boolean(formik.errors.transfer_reason)
                }
                errorMessage={formik.errors.transfer_reason}
                readOnly={type === 'detail'}
              />
              <DateInput
                required
                label='Tanggal Transfer'
                name='transfer_date'
                value={formik.values.transfer_date}
                onChange={handleTransferDateChange}
                onBlur={formik.handleBlur}
                isError={
                  formik.touched.transfer_date &&
                  Boolean(formik.errors.transfer_date)
                }
                errorMessage={formik.errors.transfer_date}
                readOnly={type === 'detail'}
              />
            </div>
          </Card>

          {/* Warehouse cards */}
          <div className='grid grid-cols-1 md:grid-cols-2 gap-4 mb-4'>
            <Card
              title='Gudang Asal'
              className={{
                wrapper: 'w-full shadow',
                body: 'space-y-4',
              }}
            >
              <SelectInput
                required
                label='Gudang'
                placeholder='Pilih gudang asal...'
                value={formik.values.source_warehouse}
                onChange={handleSourceWarehouseChange}
                options={sourceWarehouseOptions}
                onInputChange={setSourceWarehouseSelectInputValue}
                onMenuScrollToBottom={loadMoreSourceWarehouses}
                isLoading={isLoadingSourceWarehouses}
                isError={
                  formik.touched.source_warehouse_id &&
                  Boolean(formik.errors.source_warehouse_id)
                }
                errorMessage={formik.errors.source_warehouse_id as string}
                isDisabled={type === 'detail'}
                isClearable
                inputPrefix={
                  formik.values.source_warehouse_id
                    ? getWarehouseStockAdornment(
                        formik.values.source_warehouse_id
                      )
                    : undefined
                }
              />

              {/* Area and Location Info */}
              <div className='space-y-4'>
                <TextInput
                  label='Area'
                  name='source_warehouse_area'
                  value={
                    (formik.values.source_warehouse as WarehouseOptionType)
                      ?.area || '-'
                  }
                  readOnly
                  disabled
                />
                <TextInput
                  label='Lokasi'
                  name='source_warehouse_location'
                  value={
                    (formik.values.source_warehouse as WarehouseOptionType)
                      ?.location || '-'
                  }
                  readOnly
                  disabled
                />
              </div>
            </Card>

            <Card
              title='Gudang Tujuan'
              className={{
                wrapper: 'w-full shadow',
                body: 'space-y-4',
              }}
            >
              <SelectInput
                required
                label='Gudang'
                placeholder='Pilih gudang tujuan...'
                value={formik.values.destination_warehouse}
                onChange={handleDestinationWarehouseChange}
                options={warehouseOptions}
                onInputChange={setWarehouseSelectInputValue}
                isLoading={isLoadingWarehouses}
                onMenuScrollToBottom={loadMoreWarehouses}
                isError={
                  formik.touched.destination_warehouse_id &&
                  Boolean(formik.errors.destination_warehouse_id)
                }
                errorMessage={formik.errors.destination_warehouse_id as string}
                isDisabled={type === 'detail'}
                isClearable
                inputPrefix={
                  formik.values.destination_warehouse_id
                    ? getWarehouseStockAdornment(
                        formik.values.destination_warehouse_id
                      )
                    : undefined
                }
              />

              {/* Area and Location Info */}
              <div className='space-y-4'>
                <TextInput
                  label='Area'
                  name='destination_warehouse_area'
                  value={
                    (formik.values.destination_warehouse as WarehouseOptionType)
                      ?.area || '-'
                  }
                  readOnly
                  disabled
                />
                <TextInput
                  label='Lokasi'
                  name='destination_warehouse_location'
                  value={
                    (formik.values.destination_warehouse as WarehouseOptionType)
                      ?.location || '-'
                  }
                  readOnly
                  disabled
                />
              </div>
            </Card>
          </div>

          {/* Products table */}
          <Card
            title='Produk'
            className={{
              wrapper: 'w-full mb-4 shadow',
              title: 'mb-4',
            }}
          >
            <div className='overflow-x-auto'>
              <table className='table'>
                <thead>
                  <tr>
                    {type !== 'detail' && (
                      <th>
                        <CheckboxInput
                          name='select-all-products'
                          checked={
                            formik.values.products?.length ===
                              selectedProducts.length &&
                            formik.values.products?.length > 0
                          }
                          onChange={handleProductSelectAllChange}
                          classNames={{
                            wrapper: 'flex justify-center',
                            checkbox: 'checkbox checkbox-sm',
                          }}
                        />
                      </th>
                    )}
                    <th>
                      Produk
                      <span
                        className='tooltip tooltip-error tooltip-bottom z-9999'
                        data-tip='required'
                      >
                        <span className='text-error'>*</span>
                      </span>
                    </th>
                    <th>
                      Qty
                      <span
                        className='tooltip tooltip-error tooltip-bottom z-9999'
                        data-tip='required'
                      >
                        <span className='text-error'>*</span>
                      </span>
                    </th>
                    {type !== 'detail' && <th>Aksi</th>}
                  </tr>
                </thead>
                <tbody>
                  {formik.values.products?.map((product, idx) => (
                    <tr key={`product-row-${idx}`}>
                      {type !== 'detail' && (
                        <td className='align-middle!'>
                          <CheckboxInput
                            name={`product-${idx}`}
                            checked={selectedProducts.includes(idx)}
                            onChange={handleProductCheckboxChange}
                            classNames={{
                              wrapper: 'flex justify-center',
                              checkbox: 'checkbox checkbox-sm',
                            }}
                          />
                        </td>
                      )}
                      <td>
                        <SelectInput
                          required
                          value={product.product ?? undefined}
                          onChange={(val) => handleProductChange(idx, val)}
                          options={getAvailableProductOptions(idx)}
                          onInputChange={setProductWarehouseSelectInputValue}
                          onMenuScrollToBottom={loadMoreProductWarehouses}
                          isLoading={isLoadingProductWarehouses}
                          isDisabled={
                            type === 'detail' ||
                            !formik.values.source_warehouse_id
                          }
                          placeholder={
                            !formik.values.source_warehouse_id
                              ? 'Pilih gudang asal terlebih dahulu...'
                              : 'Pilih produk...'
                          }
                          isClearable
                          {...isRepeaterInputError(
                            'products',
                            'product_id',
                            idx
                          )}
                          className={{
                            wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
                          }}
                        />
                      </td>
                      <td>
                        <NumberInput
                          required
                          name={`products.${idx}.product_qty`}
                          placeholder='Masukkan kuantitas...'
                          value={product.product_qty ?? ''}
                          onChange={formik.handleChange}
                          onBlur={formik.handleBlur}
                          decimalScale={0}
                          allowNegative={false}
                          thousandSeparator=','
                          decimalSeparator='.'
                          bottomLabel={getProductQtyBottomLabel(idx)}
                          isError={
                            isRepeaterInputError('products', 'product_qty', idx)
                              .isError || Boolean(getProductQtyError(idx))
                          }
                          errorMessage={
                            isRepeaterInputError('products', 'product_qty', idx)
                              .errorMessage ||
                            getProductQtyError(idx) ||
                            undefined
                          }
                          readOnly={type === 'detail'}
                          className={{
                            wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
                          }}
                        />
                      </td>
                      {type !== 'detail' && (
                        <td>
                          <div className='flex flex-col items-start gap-2'>
                            <Button
                              type='button'
                              color='error'
                              onClick={() => removeProduct(idx)}
                            >
                              <Icon
                                icon='material-symbols:delete-outline-rounded'
                                width={24}
                                height={24}
                              />
                            </Button>
                          </div>
                        </td>
                      )}
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            {type !== 'detail' && (
              <div className='flex justify-center items-center mt-4 gap-4'>
                {selectedProducts.length > 0 && (
                  <Button
                    type='button'
                    color='error'
                    onClick={bulkRemoveProduct}
                    className='w-fit'
                  >
                    <Icon
                      icon='material-symbols:delete-outline-rounded'
                      width={24}
                      height={24}
                    />
                    Hapus Produk Terpilih ({selectedProducts.length})
                  </Button>
                )}
                <Button
                  type='button'
                  color='success'
                  onClick={addProduct}
                  className='w-fit'
                >
                  <Icon icon='ic:round-plus' width={24} height={24} />
                  Tambah Produk
                </Button>
              </div>
            )}
          </Card>

          {/* Deliveries table */}
          <Card
            title='Pengiriman'
            className={{
              wrapper: 'w-full mb-4 shadow',
              title: 'mb-8',
            }}
          >
            <div className='overflow-x-auto'>
              <table className='table'>
                <thead>
                  <tr>
                    {type !== 'detail' && (
                      <th>
                        <CheckboxInput
                          name='select-all-deliveries'
                          checked={
                            formik.values.deliveries?.length ===
                              selectedDeliveries.length &&
                            formik.values.deliveries?.length > 0
                          }
                          onChange={handleDeliverySelectAllChange}
                          classNames={{
                            wrapper: 'flex justify-center',
                            checkbox: 'checkbox checkbox-sm',
                          }}
                        />
                      </th>
                    )}
                    <th>
                      Produk
                      <span
                        className='tooltip tooltip-error tooltip-bottom z-9999'
                        data-tip='required'
                      >
                        <span className='text-error'>*</span>
                      </span>
                    </th>
                    <th>
                      Qty
                      <span
                        className='tooltip tooltip-error tooltip-bottom z-9999'
                        data-tip='required'
                      >
                        <span className='text-error'>*</span>
                      </span>
                    </th>
                    <th>
                      Supplier
                      {hasAnySupplierSelected && (
                        <span
                          className='tooltip tooltip-error tooltip-bottom z-9999'
                          data-tip='required jika supplier dipilih'
                        >
                          <span className='text-error'>*</span>
                        </span>
                      )}
                    </th>
                    <th>
                      Plat Nomor
                      {hasAnySupplierSelected && (
                        <span
                          className='tooltip tooltip-error tooltip-bottom z-9999'
                          data-tip='required jika supplier dipilih'
                        >
                          <span className='text-error'>*</span>
                        </span>
                      )}
                    </th>
                    <th>Dokumen</th>
                    <th>
                      Biaya Pengiriman (Rp.)
                      {hasAnySupplierSelected && (
                        <span
                          className='tooltip tooltip-error tooltip-bottom z-9999'
                          data-tip='required jika supplier dipilih'
                        >
                          <span className='text-error'>*</span>
                        </span>
                      )}
                    </th>
                    <th>
                      Biaya Per Item (Rp.)
                      {hasAnySupplierSelected && (
                        <span
                          className='tooltip tooltip-error tooltip-bottom z-9999'
                          data-tip='required jika supplier dipilih'
                        >
                          <span className='text-error'>*</span>
                        </span>
                      )}
                    </th>
                    <th>
                      Nama Sopir
                      {hasAnySupplierSelected && (
                        <span
                          className='tooltip tooltip-error tooltip-bottom z-9999'
                          data-tip='required jika supplier dipilih'
                        >
                          <span className='text-error'>*</span>
                        </span>
                      )}
                    </th>
                    {type !== 'detail' && <th>Aksi</th>}
                  </tr>
                </thead>
                <tbody>
                  {formik.values.deliveries?.map((delivery, idx) => (
                    <tr key={`delivery-row-${idx}`}>
                      {type !== 'detail' && (
                        <td className='align-middle!'>
                          <CheckboxInput
                            name={`delivery-${idx}`}
                            checked={selectedDeliveries.includes(idx)}
                            onChange={handleDeliveryCheckboxChange}
                            classNames={{
                              wrapper: 'flex justify-center',
                              checkbox: 'checkbox checkbox-sm',
                            }}
                          />
                        </td>
                      )}
                      <td>
                        <SelectInput
                          required
                          placeholder='Pilih produk...'
                          value={delivery.products[0]?.product ?? undefined}
                          onChange={(val) =>
                            handleDeliveryProductChange(idx, val)
                          }
                          options={getFilteredProductWarehouseOptions()}
                          isDisabled={type === 'detail'}
                          isClearable
                          isError={
                            isDeliveryProductInputError(idx, 0, 'product_id')
                              .isError
                          }
                          errorMessage={
                            isDeliveryProductInputError(idx, 0, 'product_id')
                              .errorMessage
                          }
                          className={{
                            wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
                          }}
                        />
                      </td>
                      <td>
                        <NumberInput
                          required
                          name={`deliveries.${idx}.products.0.product_qty`}
                          placeholder='Masukkan kuantitas...'
                          value={delivery.products[0]?.product_qty ?? ''}
                          onChange={formik.handleChange}
                          onBlur={formik.handleBlur}
                          decimalScale={0}
                          allowNegative={false}
                          thousandSeparator=','
                          decimalSeparator='.'
                          isError={
                            isDeliveryProductInputError(idx, 0, 'product_qty')
                              .isError || Boolean(getDeliveryQtyError(idx, 0))
                          }
                          errorMessage={
                            isDeliveryProductInputError(idx, 0, 'product_qty')
                              .errorMessage ||
                            getDeliveryQtyError(idx, 0) ||
                            undefined
                          }
                          bottomLabel={getDeliveryProductQtyBottomLabel(idx, 0)}
                          readOnly={type === 'detail'}
                          className={{
                            wrapper: 'w-full min-w-48',
                          }}
                        />
                      </td>
                      <td>
                        <SelectInput
                          placeholder='Pilih supplier...'
                          value={delivery.supplier}
                          onChange={(val) =>
                            handleDeliverySupplierChange(idx, val)
                          }
                          options={supplierOptions}
                          onInputChange={setSupplierSelectInputValue}
                          isLoading={isLoadingSuppliers}
                          isDisabled={type === 'detail'}
                          isClearable
                          {...isRepeaterInputError(
                            'deliveries',
                            'supplier_id',
                            idx
                          )}
                          className={{
                            wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
                          }}
                        />
                      </td>
                      <td>
                        <TextInput
                          name={`deliveries.${idx}.vehicle_plate`}
                          placeholder='Masukkan plat nomor...'
                          value={delivery.vehicle_plate ?? ''}
                          onChange={formik.handleChange}
                          onBlur={formik.handleBlur}
                          {...isRepeaterInputError(
                            'deliveries',
                            'vehicle_plate',
                            idx
                          )}
                          readOnly={type === 'detail'}
                          required={isSupplierSelected(idx)}
                          className={{
                            wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
                          }}
                        />
                      </td>
                      <td>
                        {type === 'detail' ? (
                          <>
                            <div className='flex flex-col items-start gap-2'>
                              {delivery.document_path ? (
                                <Button
                                  color='primary'
                                  className='w-full min-w-52 flex items-center justify-center gap-2'
                                  href={`${S3_PUBLIC_BASE_URL}/${delivery.document_path.startsWith('/') ? delivery.document_path.slice(1) : delivery.document_path}`}
                                  target='_blank'
                                  rel='noopener noreferrer'
                                >
                                  <Icon
                                    icon='material-symbols:file-open-outline'
                                    width={20}
                                    height={20}
                                  />
                                  Lihat Dokumen
                                </Button>
                              ) : delivery.document &&
                                delivery.document instanceof File === false ? (
                                <Button
                                  color='primary'
                                  className='w-full min-w-52 flex items-center justify-center gap-2'
                                  href={`${S3_PUBLIC_BASE_URL}/${delivery.document.path.startsWith('/') ? delivery.document.path.slice(1) : delivery.document.path}`}
                                  target='_blank'
                                  rel='noopener noreferrer'
                                >
                                  <Icon
                                    icon='material-symbols:file-open-outline'
                                    width={20}
                                    height={20}
                                  />
                                  <span className='truncate max-w-[200px]'>
                                    {delivery.document.name}
                                  </span>
                                </Button>
                              ) : (
                                <Button
                                  color='neutral'
                                  className='w-full min-w-52 flex items-center justify-center gap-2 cursor-not-allowed'
                                  disabled
                                >
                                  <Icon
                                    icon='material-symbols:description'
                                    width={20}
                                    height={20}
                                  />
                                  Tidak ada dokumen
                                </Button>
                              )}
                            </div>
                          </>
                        ) : (
                          <FileInput
                            accept='.pdf,.jpg,.jpeg,.png'
                            name={`deliveries.${idx}.document`}
                            onChange={(e) =>
                              handleDeliveryDocumentChange(idx, e)
                            }
                            {...isRepeaterInputError(
                              'deliveries',
                              'document',
                              idx
                            )}
                            className={{
                              wrapper:
                                'w-full min-w-72 md:w-min-80 lg:w-min-96',
                            }}
                          />
                        )}
                      </td>
                      <td>
                        <NumberInput
                          name={`deliveries.${idx}.delivery_cost`}
                          placeholder='Masukkan biaya pengiriman...'
                          value={delivery.delivery_cost ?? ''}
                          onChange={handleDeliveryCostChangeWrapper(idx)}
                          onBlur={formik.handleBlur}
                          decimalScale={0}
                          allowNegative={false}
                          thousandSeparator=','
                          decimalSeparator='.'
                          inputPrefix='Rp'
                          {...isRepeaterInputError(
                            'deliveries',
                            'delivery_cost',
                            idx
                          )}
                          readOnly={type === 'detail'}
                          required={isSupplierSelected(idx)}
                          className={{
                            wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
                          }}
                        />
                      </td>
                      <td>
                        <NumberInput
                          name={`deliveries.${idx}.delivery_cost_per_item`}
                          placeholder='Masukkan biaya per item...'
                          value={delivery.delivery_cost_per_item ?? ''}
                          onChange={handleDeliveryCostPerItemChangeWrapper(idx)}
                          onBlur={formik.handleBlur}
                          decimalScale={0}
                          allowNegative={false}
                          thousandSeparator=','
                          decimalSeparator='.'
                          inputPrefix='Rp'
                          {...isRepeaterInputError(
                            'deliveries',
                            'delivery_cost_per_item',
                            idx
                          )}
                          readOnly={type === 'detail'}
                          required={isSupplierSelected(idx)}
                          className={{
                            wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
                          }}
                        />
                      </td>
                      <td>
                        <TextInput
                          name={`deliveries.${idx}.driver_name`}
                          placeholder='Masukkan nama sopir...'
                          value={delivery.driver_name ?? ''}
                          onChange={formik.handleChange}
                          onBlur={formik.handleBlur}
                          {...isRepeaterInputError(
                            'deliveries',
                            'driver_name',
                            idx
                          )}
                          readOnly={type === 'detail'}
                          required={isSupplierSelected(idx)}
                          className={{
                            wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
                          }}
                        />
                      </td>
                      {type !== 'detail' && (
                        <td>
                          <div className='flex flex-col items-start gap-2'>
                            <Button
                              type='button'
                              color='error'
                              onClick={() => removeDelivery(idx)}
                            >
                              <Icon
                                icon='material-symbols:delete-outline-rounded'
                                width={24}
                                height={24}
                              />
                            </Button>
                          </div>
                        </td>
                      )}
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            {type !== 'detail' && (
              <div className='flex justify-center items-center mt-4 gap-4'>
                {selectedDeliveries.length > 0 && (
                  <Button
                    type='button'
                    color='error'
                    onClick={bulkRemoveDelivery}
                    className='w-fit'
                  >
                    <Icon
                      icon='material-symbols:delete-outline-rounded'
                      width={24}
                      height={24}
                    />
                    Hapus Pengiriman Terpilih ({selectedDeliveries.length})
                  </Button>
                )}
                <Button
                  type='button'
                  color='success'
                  onClick={addDelivery}
                  className='w-fit'
                >
                  <Icon icon='ic:round-plus' width={24} height={24} />
                  Tambah Pengiriman
                </Button>
              </div>
            )}
          </Card>

          <div className='w-full'>
            {movementFormErrorMessage && (
              <div role='alert' className='alert alert-error'>
                <Icon
                  icon='material-symbols:error-outline'
                  width={24}
                  height={24}
                />
                <span>{movementFormErrorMessage}</span>
              </div>
            )}

            {/* Error List Alert */}
            {formErrorList.length > 0 && (
              <AlertErrorList
                formErrorList={formErrorList}
                onClose={() => setFormErrorList([])}
              />
            )}
          </div>

          {/* Action buttons */}
          <div className='flex flex-row justify-between gap-2 flex-wrap'>
            {type !== 'detail' && (
              <div className='flex flex-row justify-end gap-2 w-full'>
                <Button type='reset' color='warning' className='px-4'>
                  Reset
                </Button>

                <Button
                  type='submit'
                  color='primary'
                  className='px-4'
                  isLoading={formik.isSubmitting}
                  disabled={
                    formik.isSubmitting ||
                    (formik.values.source_warehouse_id ===
                      formik.values.destination_warehouse_id &&
                      formik.values.source_warehouse_id !== 0 &&
                      formik.values.destination_warehouse_id !== 0)
                  }
                >
                  Submit
                </Button>
              </div>
            )}
          </div>
        </form>
      </section>
    </>
  );
};

export default MovementForm;
