'use client';

import Button from '@/components/Button';
import Card from '@/components/Card';
import { FormHeader } from '@/components/helper/form/FormHeader';
import DateInput from '@/components/input/DateInput';
import SelectInput, {
  OptionType,
  useSelect,
} from '@/components/input/SelectInput';
import Modal, { useModal } from '@/components/Modal';
import { formatCurrency, formatDate } from '@/lib/helper';
import {
  BaseDeliveryOrder,
  BaseSalesOrder,
  CreateDeliveryOrderPayload,
  CreateSalesOrderPayload,
  CreateSalesOrderProductPayload,
  Marketing,
  UpdateDeliveryOrderPayload,
  UpdateSalesOrderPayload,
} from '@/types/api/marketing/marketing';
import { Icon } from '@iconify/react';
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
import { Customer } from '@/types/api/master-data/customer';
import { CustomerApi } from '@/services/api/master-data';
import { useFormik } from 'formik';
import {
  DeliveryOrderFormValues,
  DeliveryOrderSchema,
  SalesOrderFormValues,
  SalesOrderSchema,
} from '@/components/pages/marketing/form/MarketingForm.schema';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import {
  DeliveryOrderApi,
  MarketingApi,
  SalesOrderApi,
} from '@/services/api/marketing/marketing';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import toast from 'react-hot-toast';
import { useRouter } from 'next/navigation';
import DebouncedTextArea from '@/components/input/DebouncedTextArea';
import SalesOrderProductTable from '@/components/pages/marketing/form/table-view/SalesOrderProductTable';
import SalesOrderProductForm from '@/components/pages/marketing/form/repeater/sales-order/SalesOrderProductForm';
import DeliveryOrderProductTable from '@/components/pages/marketing/form/table-view/DeliveryOrderProductTable';
import DeliveryOrderProductForm from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct';
import { SalesOrderProductFormValues } from '@/components/pages/marketing/form/repeater/sales-order/SalesOrderProduct.schema';
import { DeliveryOrderProductFormValues } from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct.schema';
import RequirePermission from '@/components/helper/RequirePermission';
import AlertErrorList from '@/components/helper/form/FormErrors';
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
import { CreatedUser } from '@/types/api/api-general';
import { UserApi } from '@/services/api/user';

const MemoizedSalesOrderProductTable = memo(SalesOrderProductTable);
const MemoizedSalesOrderProductForm = memo(SalesOrderProductForm);
const MemoizedDeliveryOrderProductTable = memo(DeliveryOrderProductTable);
const MemoizedDeliveryOrderProductForm = memo(DeliveryOrderProductForm);

// ================== EXTERNAL HELPER FUNCTION ==================
export interface ProductCalculationFields {
  qty: string | number | undefined;
  unit_price: string | number | undefined;
  total_price: string | number | undefined;
  avg_weight: string | number | undefined;
  total_weight: string | number | undefined;
}

export const SalesProductToFieldValues = (
  product: BaseSalesOrder
): SalesOrderProductFormValues => {
  return {
    id: product.id,
    vehicle_number: product.vehicle_number,
    kandang_id: product.product_warehouse.warehouse.id,
    kandang: {
      value: product.product_warehouse.warehouse.id,
      label: product.product_warehouse.warehouse.name,
    },
    product_warehouse: {
      value: product.product_warehouse.id,
      label: product.product_warehouse.product.name,
    },
    product_warehouse_id: product.product_warehouse.id,
    unit_price: product.unit_price,
    total_weight: product.total_weight,
    qty: product.qty,
    avg_weight: product.avg_weight,
    total_price: product.total_price,
  };
};
export const DeliveryProductToFieldValues = (
  salesOrders: BaseSalesOrder[],
  delivery: BaseDeliveryOrder
): DeliveryOrderProductFormValues[] => {
  const data = delivery.deliveries.map((item) => {
    const soId = salesOrders.find(
      (so) => so.product_warehouse.id === item.product_warehouse.id
    )?.id;
    return {
      id: soId,
      unit_price: item.unit_price,
      total_weight: item.total_weight,
      qty: item.qty,
      avg_weight: item.avg_weight,
      total_price: item.total_price,
      vehicle_number: item.vehicle_number,
      delivery_date: formatDate(delivery.delivery_date, 'yyyy-MM-DD'),
      do_number: delivery.do_number,
      marketing_product_id: soId,
      marketing_product: {
        id: soId,
        vehicle_number: item.vehicle_number,
        kandang_id: item.product_warehouse.warehouse.id,
        kandang: {
          value: item.product_warehouse.warehouse.id,
          label: item.product_warehouse.warehouse.name,
        },
        product_warehouse: {
          value: item.product_warehouse.id,
          label: item.product_warehouse.product.name,
        },
        product_warehouse_id: item.product_warehouse.id,
        unit_price: item.unit_price,
        total_weight: item.total_weight,
        qty: item.qty,
        avg_weight: item.avg_weight,
        total_price: item.total_price,
      },
    } as DeliveryOrderProductFormValues;
  });
  return data;
};
export const mergeSOwithDO = (
  salesOrders: SalesOrderProductFormValues[],
  deliveryOrders: DeliveryOrderProductFormValues[]
): DeliveryOrderProductFormValues[] => {
  return salesOrders.map((so) => {
    const delivery = deliveryOrders.find(
      (d) => d?.marketing_product_id === so.id
    );

    return {
      ...so, // nilai dasar dari sales order
      marketing_product_id: so.id,
      delivery_date: delivery?.delivery_date || undefined,
      do_number: delivery?.do_number || undefined,
      vehicle_number: delivery?.vehicle_number || so.vehicle_number,
      unit_price: delivery?.unit_price,
      total_weight: delivery?.total_weight,
      qty: delivery?.qty,
      avg_weight: delivery?.avg_weight,
      total_price: delivery?.total_price,
      marketing_product: so, // jika ada, override
    } as DeliveryOrderProductFormValues;
  });
};
export const recalculate = (
  field: string,
  values: ProductCalculationFields
) => {
  const { qty, unit_price, total_price, avg_weight, total_weight } = values;
  const result: Partial<ProductCalculationFields> = {};
  if (field == 'unit_price' || field == 'total_price' || field == 'qty') {
    if (qty && unit_price && (field == 'unit_price' || field == 'qty')) {
      result.total_price = Number(qty) * Number(unit_price);
    } else if (qty && total_price && field == 'total_price') {
      result.unit_price = Number(total_price) / Number(qty);
    }
  }
  if (field == 'avg_weight' || field == 'total_weight' || field == 'qty') {
    if (qty && avg_weight && (field == 'avg_weight' || field == 'qty')) {
      result.total_weight = Number(qty) * Number(avg_weight);
    } else if (qty && total_weight && field == 'total_weight') {
      result.avg_weight = Number(total_weight) / Number(qty);
    }
  }
  return result;
};
export const getSubmitField = (values: ProductCalculationFields) => {
  const { qty, unit_price, total_price, avg_weight, total_weight } = values;

  // Harga logic
  if (qty && unit_price && !total_price) {
    return 'unit_price';
  }
  if (qty && total_price && !unit_price) {
    return 'total_price';
  }

  // Bobot logic
  if (qty && avg_weight && !total_weight) {
    return 'avg_weight';
  }
  if (qty && total_weight && !avg_weight) {
    return 'total_weight';
  }

  // Tidak ada yang perlu dihitung
  return '';
};

const MarketingForm = ({
  formType = 'add',
  initialValues,
  afterSubmit,
}: {
  formType?: 'add' | 'edit' | 'add_deliver' | 'edit_deliver';
  initialValues?: Marketing;
  afterSubmit?: () => void;
}) => {
  const router = useRouter();
  const deleteModal = useModal();

  const [isLoading, setIsLoading] = useState(false);
  const [selectedMarketingProduct, setSelectedMarketingProduct] =
    useState<SalesOrderProductFormValues | null>(null);
  const [selectedDeliveryProduct, setSelectedDeliveryProduct] =
    useState<DeliveryOrderProductFormValues | null>(null);
  const [deliveryFormState, setDeliveryFormState] = useState<'add' | 'edit'>(
    'add'
  );
  const [deliveryOrderValues, setDeliveryOrderValues] = useState<
    DeliveryOrderProductFormValues[]
  >(
    mergeSOwithDO(
      initialValues?.sales_order?.map(SalesProductToFieldValues) ?? [],
      initialValues?.delivery_order?.flatMap((delivery) =>
        DeliveryProductToFieldValues(initialValues.sales_order, delivery)
      ) ?? []
    )
  );

  // ================== REPEATER ==================
  const addSOModal = useModal();
  const addDOModal = useModal();
  const [rowSOSelection, setRowSOSelection] = useState<Record<string, boolean>>(
    {}
  );
  const selectedRowSOIds = Object.keys(rowSOSelection).map((item) =>
    parseInt(item)
  );

  // ================== FETCH OPTIONS ==================
  const {
    options: customerOptions,
    isLoadingOptions: isLoadingCustomerOptions,
    setInputValue: setInputCustomerValue,
    loadMore: loadMoreCustomer,
  } = useSelect<Customer>(CustomerApi.basePath, 'id', 'name');
  const {
    options: salesOptions,
    isLoadingOptions: isLoadingSalesOptions,
    setInputValue: setInputSalesValue,
    loadMore: loadMoreSales,
  } = useSelect<CreatedUser>(UserApi.basePath, 'id', 'name');

  // ================== SETUP FORMIK ==================
  const formikInitialValues = useMemo<
    SalesOrderFormValues & DeliveryOrderFormValues
  >(() => {
    return {
      so_date: initialValues?.so_date || undefined,
      notes: initialValues?.notes || undefined,
      customer_id: initialValues?.customer?.id || undefined,
      sales_person_id: initialValues?.sales_person?.id || 1,
      sales_person: initialValues?.sales_person
        ? {
            value: initialValues.sales_person.id,
            label: initialValues.sales_person.name,
          }
        : null,
      customer: initialValues?.customer
        ? {
            value: initialValues.customer.id,
            label: initialValues.customer.name,
          }
        : null,
      sales_order:
        initialValues?.sales_order?.map((product) =>
          SalesProductToFieldValues(product)
        ) ?? [],
      delivery_order: mergeSOwithDO(
        initialValues?.sales_order?.map(SalesProductToFieldValues) ?? [],
        initialValues?.delivery_order?.flatMap((delivery) =>
          DeliveryProductToFieldValues(initialValues.sales_order, delivery)
        ) ?? []
      ),
    };
  }, [initialValues]);
  const formik = useFormik<SalesOrderFormValues & DeliveryOrderFormValues>({
    enableReinitialize: true,
    initialValues: formikInitialValues,
    validationSchema:
      formType == 'add_deliver' || formType == 'edit_deliver'
        ? DeliveryOrderSchema
        : SalesOrderSchema,
    validateOnMount: true,
    onSubmit: async (values) => {
      const payload =
        formType != 'add_deliver' && formType != 'edit_deliver'
          ? ({
              customer_id: values.customer_id as number,
              sales_person_id: values.sales_person_id as number,
              date: formatDate(values.so_date as string, 'yyyy-MM-DD'),
              notes: values.notes as string,
              marketing_products: values.sales_order.map((product) => {
                return {
                  vehicle_number: product.vehicle_number as string,
                  kandang_id: product.kandang_id as number,
                  product_warehouse_id: product.product_warehouse_id as number,
                  unit_price: parseFloat(product.unit_price as string),
                  total_weight: parseFloat(product.total_weight as string),
                  qty: parseFloat(product.qty as string),
                  avg_weight: parseFloat(product.avg_weight as string),
                  total_price: parseFloat(product.total_price as string),
                } as CreateSalesOrderProductPayload;
              }),
            } as CreateSalesOrderPayload)
          : ({
              marketing_id: initialValues?.id as number,
              delivery_products: values.delivery_order
                .map((product) => {
                  if (Boolean(product.delivery_date)) {
                    return {
                      marketing_product_id:
                        product.marketing_product_id as number,
                      unit_price: parseFloat(product.unit_price as string),
                      total_weight: parseFloat(product.total_weight as string),
                      qty: parseFloat(product.qty as string),
                      avg_weight: parseFloat(product.avg_weight as string),
                      total_price: parseFloat(product.total_price as string),
                      delivery_date: formatDate(
                        product.delivery_date as string,
                        'yyyy-MM-DD'
                      ),
                      vehicle_number: product.vehicle_number,
                    };
                  }
                })
                .filter((item) => Boolean(item)),
            } as UpdateDeliveryOrderPayload);
      switch (formType) {
        case 'add':
          await createMarketingHandler(payload as CreateSalesOrderPayload);
          break;
        case 'edit':
          await updateMarketingHandler(payload as UpdateSalesOrderPayload);
          break;
        case 'add_deliver':
          await createDeliveryHandler(payload as CreateDeliveryOrderPayload);
          break;
        case 'edit_deliver':
          await updateDeliveryHandler(payload as UpdateDeliveryOrderPayload);
          break;
        default:
          break;
      }
      afterSubmit?.();
    },
  });

  const memoSalesOrder = formik.values.sales_order;

  // ================== FORM REPEATER HANDLER ==================
  const createMarketingHandler = async (values: CreateSalesOrderPayload) => {
    setIsLoading(true);
    const createMarketingRes = await SalesOrderApi.create(values);
    if (isResponseSuccess(createMarketingRes)) {
      toast.success(createMarketingRes?.message as string);
      router.push('/marketing');
    }
    if (isResponseError(createMarketingRes)) {
      toast.error(createMarketingRes?.message as string);
    }
    setIsLoading(false);
  };
  const updateMarketingHandler = async (values: UpdateSalesOrderPayload) => {
    setIsLoading(true);
    const updateMarketingRes = await SalesOrderApi.update(
      initialValues?.id as number,
      values
    );
    if (isResponseSuccess(updateMarketingRes)) {
      toast.success(updateMarketingRes?.message as string);
      router.push(`/marketing/detail?marketingId=${initialValues?.id}`);
    }
    if (isResponseError(updateMarketingRes)) {
      toast.error(updateMarketingRes?.message as string);
    }
    setIsLoading(false);
  };
  const createDeliveryHandler = async (values: CreateDeliveryOrderPayload) => {
    setIsLoading(true);
    const createDeliveryRes = await DeliveryOrderApi.create(values);
    if (isResponseSuccess(createDeliveryRes)) {
      toast.success(createDeliveryRes?.message as string);
      setDeliveryOrderValues(
        createDeliveryRes.data?.delivery_order?.flatMap((delivery) =>
          DeliveryProductToFieldValues(
            createDeliveryRes.data?.sales_order,
            delivery
          )
        ) ?? []
      );
      router.push(`/marketing/detail?marketingId=${initialValues?.id}`);
    }
    if (isResponseError(createDeliveryRes)) {
      toast.error(createDeliveryRes?.message as string);
    }
    setIsLoading(false);
  };
  const updateDeliveryHandler = async (values: UpdateDeliveryOrderPayload) => {
    setIsLoading(true);
    const updateDeliveryRes = await DeliveryOrderApi.update(
      initialValues?.id as number,
      values
    );
    if (isResponseSuccess(updateDeliveryRes)) {
      toast.success(updateDeliveryRes?.message as string);
      setDeliveryOrderValues(
        mergeSOwithDO(
          formik.values.sales_order,
          updateDeliveryRes.data?.delivery_order?.flatMap((delivery) =>
            DeliveryProductToFieldValues(
              updateDeliveryRes.data?.sales_order,
              delivery
            )
          ) ?? []
        )
      );
      router.push(`/marketing/detail?marketingId=${initialValues?.id}`);
    }
    if (isResponseError(updateDeliveryRes)) {
      toast.error(updateDeliveryRes?.message as string);
    }
    setIsLoading(false);
  };

  // ================== MARKETING HANDLER ==================
  const deleteMarketingHandler = async () => {
    setIsLoading(true);
    const deleteMarketingRes = await MarketingApi.delete(
      initialValues?.id as number
    );
    if (isResponseSuccess(deleteMarketingRes)) {
      toast.success(deleteMarketingRes?.message as string);
    }
    if (isResponseError(deleteMarketingRes)) {
      toast.error(deleteMarketingRes?.message as string);
    }
    setIsLoading(false);
    deleteModal.closeModal();
    router.push('/marketing');
  };
  const handleChangeCustomer = useCallback(
    (val: OptionType | OptionType[] | null) => {
      formik.setFieldValue('customer_id', (val as OptionType)?.value);
      formik.setFieldValue('customer', val as OptionType);
    },
    []
  );
  const handleChangeSalesPerson = useCallback(
    (val: OptionType | OptionType[] | null) => {
      formik.setFieldValue('sales_person_id', (val as OptionType)?.value);
      formik.setFieldValue('sales_person', val as OptionType);
    },
    []
  );
  const handleDelete = useCallback(() => {
    deleteModal.openModal();
  }, [deleteModal]);

  // ================== SALES ORDER HANDLER ==================
  const handleDeleteSO = useCallback(
    (id: number) => {
      const currentProducts = formik.values.sales_order;
      formik.setFieldValue(
        'sales_order',
        currentProducts.filter((p) => p.id != id)
      );
    },
    [memoSalesOrder]
  );
  const handleEditSO = useCallback(
    (id: number) => {
      const currentProducts = formik.values.sales_order;
      const selectedProduct = currentProducts.find((p) => p.id == id);
      setSelectedMarketingProduct(selectedProduct ?? null);
      addSOModal.openModal();
    },
    [memoSalesOrder]
  );
  const handleBulkDeleteSO = useCallback(() => {
    const currentProducts = formik.values.sales_order;
    formik.setFieldValue(
      'sales_order',
      currentProducts.filter(
        (product) => !selectedRowSOIds.includes(product.id ?? -1)
      )
    );
    setRowSOSelection({});
  }, [selectedRowSOIds, memoSalesOrder]);
  const handleAddSOClick = useCallback(() => {
    setSelectedMarketingProduct(null);
    addSOModal.openModal();
  }, [addSOModal]);
  const handleAddSubmitSO = useCallback(
    async (values: SalesOrderProductFormValues, id?: number) => {
      const currentProducts = formik.values.sales_order;

      const newValues = {
        ...values,
        id: values.id ?? Date.now(),
      };

      let updatedProducts = [];

      if (id) {
        // Overwrite
        updatedProducts = currentProducts.map((item) =>
          item.id === id ? newValues : item
        );
      } else {
        // Add new item
        updatedProducts = [...currentProducts, newValues];
      }

      formik.setFieldValue('sales_order', updatedProducts);

      addSOModal.closeModal();
    },
    [addSOModal, memoSalesOrder]
  );

  // ================== DELIVERY ORDER HANDLER ==================
  const handleEditDO = useCallback(
    (id: number, values?: DeliveryOrderProductFormValues) => {
      setDeliveryFormState('edit');
      const currentProducts = formik.values.delivery_order.find(
        (product) => product.id == id
      );
      setSelectedDeliveryProduct(values ?? currentProducts ?? null);
      addDOModal.openModal();
    },
    [addDOModal]
  );
  const handleAddDOClick = useCallback(() => {
    setDeliveryFormState('add');
    setSelectedDeliveryProduct(null);
    addDOModal.openModal();
  }, [addDOModal]);
  const handleAddSubmitDO = useCallback(
    async (values: DeliveryOrderProductFormValues) => {
      const newValues = {
        ...values,
        id: values.id ?? Date.now(),
      };

      setDeliveryOrderValues((prev) => [...prev, newValues]);
      addDOModal.closeModal();
      setSelectedDeliveryProduct(null);
    },
    [addDOModal]
  );
  const handleUpdateDO = useCallback(
    async (id: number, values: DeliveryOrderProductFormValues) => {
      setDeliveryOrderValues((prev) =>
        prev.map((product) =>
          product.id === id ? { ...product, ...values } : product
        )
      );
      addDOModal.closeModal();
      setSelectedDeliveryProduct(null);
    },
    [addDOModal]
  );
  const handleDeleteDO = useCallback(
    async (id: number) => {
      setDeliveryOrderValues((prev) =>
        prev.map((product) =>
          product.id === id
            ? {
                ...product,
                ...{
                  unit_price: '',
                  total_weight: '',
                  qty: '',
                  avg_weight: '',
                  total_price: '',
                  delivery_date: '',
                },
              }
            : product
        )
      );
      addDOModal.closeModal();
      setSelectedDeliveryProduct(null);
    },
    [addDOModal]
  );

  useEffect(() => {
    formik.setFieldValue('delivery_order', deliveryOrderValues);
  }, [deliveryOrderValues, initialValues]);

  const grandTotal = useMemo(() => {
    return memoSalesOrder.reduce(
      (total, product) =>
        total + parseFloat((product.total_price as string) || '0'),
      0
    );
  }, [memoSalesOrder]);

  // ===== Formik Error List =====
  const { formErrorList, close, handleFormSubmit } = useFormikErrorList(formik);

  return (
    <>
      <form
        className='flex flex-col gap-4'
        onSubmit={handleFormSubmit}
        onReset={formik.handleReset}
      >
        <FormHeader
          title={`${formType == 'add' || formType == 'add_deliver' ? 'Tambah' : 'Edit'} ${formType === 'add_deliver' || formType === 'edit_deliver' ? 'Delivery' : 'Sales'} Order`}
          backUrl='/marketing'
        />
        {/* Input Cutomer And Date  */}
        <Card
          title='Informasi Order'
          className={{
            wrapper: 'bg-white w-full',
          }}
          variant='bordered'
        >
          <div className='grid sm:grid-cols-2 gap-3 mt-3'>
            <SelectInput
              label='Pelanggan'
              options={customerOptions}
              isLoading={isLoadingCustomerOptions}
              value={formik.values.customer}
              onChange={handleChangeCustomer}
              onInputChange={setInputCustomerValue}
              onMenuScrollToBottom={loadMoreCustomer}
              isError={
                formik.touched.customer_id && Boolean(formik.errors.customer_id)
              }
              errorMessage={formik.errors.customer_id}
              isClearable
              placeholder='Pilih Pelanggan'
              isDisabled={
                formType === 'add_deliver' ||
                formType === 'edit_deliver' ||
                formType === 'edit'
              }
            />
            <DateInput
              name='so_date'
              label='Tanggal'
              value={formik.values.so_date}
              onChange={formik.handleChange}
              isError={formik.touched.so_date && Boolean(formik.errors.so_date)}
              errorMessage={formik.errors.so_date}
              placeholder='Pilih Tanggal'
              readOnly={formType == 'add_deliver' || formType == 'edit_deliver'}
            />
          </div>
        </Card>

        {/* Input Table Repeater Sales Order */}
        <Card
          title='Informasi Produk'
          className={{
            wrapper: 'bg-white w-full',
          }}
          variant='bordered'
        >
          <MemoizedSalesOrderProductTable
            formType={formType}
            data={memoSalesOrder}
            rowSelection={rowSOSelection}
            setRowSelection={setRowSOSelection}
            selectedRowIds={selectedRowSOIds}
            onDelete={handleDeleteSO}
            onEdit={handleEditSO}
            onBulkDelete={handleBulkDeleteSO}
            onAddProductClick={handleAddSOClick}
          />
        </Card>

        {/* Input Table Repeater Delivery Order */}
        {(formType == 'add_deliver' || formType == 'edit_deliver') &&
          initialValues?.sales_order &&
          initialValues?.sales_order.length > 0 && (
            <Card
              title='Informasi Pengiriman'
              className={{
                wrapper: 'bg-white w-full',
              }}
            >
              <MemoizedDeliveryOrderProductTable
                formType={formType}
                data={deliveryOrderValues}
                onEdit={handleEditDO}
                onDelete={handleDeleteDO}
                onAddProductClick={handleAddDOClick}
              />
            </Card>
          )}

        {/* Input Notes */}
        <div className='grid sm:grid-cols-2 gap-3'>
          <div className='flex flex-col h-full items-end gap-3'>
            <SelectInput
              label='Sales'
              options={salesOptions}
              isLoading={isLoadingSalesOptions}
              value={formik.values.sales_person}
              onChange={handleChangeSalesPerson}
              onInputChange={setInputSalesValue}
              onMenuScrollToBottom={loadMoreSales}
              isError={
                formik.touched.sales_person_id &&
                Boolean(formik.errors.sales_person_id)
              }
              errorMessage={formik.errors.sales_person_id}
              isClearable
              placeholder='Pilih Sales'
              isDisabled={
                formType === 'add_deliver' || formType === 'edit_deliver'
              }
            />
            <DebouncedTextArea
              required
              name='notes'
              label='Catatan'
              rows={3}
              placeholder='Masukan catatan penjualan'
              value={formik.values.notes}
              onChange={formik.handleChange}
              isError={formik.touched.notes && Boolean(formik.errors.notes)}
              errorMessage={formik.errors.notes}
              disabled={
                formType === 'add_deliver' || formType === 'edit_deliver'
              }
            />
          </div>
          <div className='flex flex-col h-full justify-end items-end'>
            <span>Total Penjualan</span>
            <span className='text-lg font-semibold'>
              {formatCurrency(grandTotal)}{' '}
            </span>
          </div>
        </div>

        <AlertErrorList formErrorList={formErrorList} onClose={close} />

        {/* Form Actions */}
        <div className='flex flex-row items-start justify-center gap-2 mt-4'>
          <Button type='reset' color='warning' disabled={formik.isSubmitting}>
            Reset
          </Button>
          <Button
            type='submit'
            disabled={formik.isSubmitting}
            isLoading={formik.isSubmitting}
          >
            Submit
          </Button>
        </div>
      </form>

      {/* Actions button */}
      {formType == 'edit' && (
        <div className='flex flex-row justify-start'>
          <RequirePermission permissions='lti.marketing.sales_order.delete'>
            <Button
              type='button'
              color='error'
              onClick={handleDelete}
              isLoading={isLoading}
            >
              <Icon icon='mdi:trash' width={24} height={24} />
              Hapus
            </Button>
          </RequirePermission>
        </div>
      )}

      {/* Modals */}
      <Modal
        ref={addSOModal.ref}
        closeOnBackdrop
        className={{
          modalBox: 'max-w-4/5 z-100',
        }}
      >
        <div className='flex flex-col gap-4'>
          <div className='flex flex-row items-center justify-between'>
            <h3 className='text-lg font-semibold mb-4'>Tambah Produk</h3>
            <Button
              variant='ghost'
              color='error'
              className='rounded-full'
              onClick={addSOModal.closeModal}
            >
              <Icon icon='mdi:close' width={20} height={20} />
            </Button>
          </div>
          <div>
            <MemoizedSalesOrderProductForm
              onSubmitForm={handleAddSubmitSO}
              initialValues={selectedMarketingProduct ?? undefined}
              exisitingValues={memoSalesOrder}
            />
          </div>
        </div>
      </Modal>
      <Modal
        ref={addDOModal.ref}
        closeOnBackdrop
        className={{
          modalBox: 'max-w-4/5 z-100',
        }}
      >
        <div className='flex flex-col gap-4'>
          <div className='flex flex-row items-center justify-between'>
            <h3 className='text-lg font-semibold mb-4'>
              {selectedDeliveryProduct ? 'Edit' : 'Tambah'} Pengiriman
            </h3>
            <Button
              variant='ghost'
              color='error'
              className='rounded-full'
              onClick={addDOModal.closeModal}
            >
              <Icon icon='mdi:close' width={20} height={20} />
            </Button>
          </div>
          <div>
            <MemoizedDeliveryOrderProductForm
              formState={deliveryFormState}
              salesOrders={initialValues?.sales_order ?? []}
              exisitingValues={deliveryOrderValues}
              onSubmitForm={handleAddSubmitDO}
              initialValues={selectedDeliveryProduct ?? undefined}
              onUpdateForm={handleUpdateDO}
            />
          </div>
        </div>
      </Modal>
      <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,
        }}
      />
    </>
  );
};

export default MarketingForm;
