import { useEffect, useState } from 'react';
import {
  DeliveryOrderProductFormValues,
  DeliveryOrderProductSchema,
} from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct.schema';
import { useFormik } from 'formik';
import Alert from '@/components/Alert';
import Button from '@/components/Button';
import NumberInput from '@/components/input/NumberInput';
import PatternInput from '@/components/input/PatternInput';
import { formatVechicleNumber } from '@/lib/helper';
import DateInput from '@/components/input/DateInput';
import SelectInput, { OptionType } from '@/components/input/SelectInput';
import { BaseSalesOrder } from '@/types/api/marketing/marketing';
import Badge from '@/components/Badge';
import { SalesProductToFieldValues } from '@/components/pages/marketing/form/MarketingForm';
import * as Yup from 'yup';
import { isResponseSuccess } from '@/lib/api-helper';
import AlertErrorList from '@/components/helper/form/FormErrors';
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
import useSWR from 'swr';
import { ProductApi } from '@/services/api/master-data';

const roundWeight = (value: number) => Number(value.toFixed(2));
const roundPrice = (value: number) => Math.round(value);

const DeliveryOrderProductForm = ({
  formState,
  salesOrders,
  initialValues,
  exisitingValues,
  onSubmitForm,
  onUpdateForm,
}: {
  formState: 'add' | 'edit';
  salesOrders: BaseSalesOrder[];
  initialValues?: DeliveryOrderProductFormValues;
  exisitingValues?: DeliveryOrderProductFormValues[];
  onSubmitForm?: (value: DeliveryOrderProductFormValues) => Promise<void>;
  onUpdateForm?: (
    id: number,
    value: DeliveryOrderProductFormValues
  ) => Promise<void>;
}) => {
  const [formikErrorMessage, setFormErrorMessage] = useState('');
  const [selectedProduct, setSelectedProduct] = useState<OptionType | null>(
    null
  );
  const [currentInput, setCurrentInput] = useState<string>('');

  // ============ Fetch Data ============
  const { data: productData } = useSWR(
    selectedProduct?.value
      ? ProductApi.basePath + '/' + selectedProduct?.value
      : null,
    () =>
      selectedProduct?.value
        ? ProductApi.getSingle(Number(selectedProduct?.value))
        : undefined
  );

  const salesOrder = salesOrders.find(
    (item) => item.id === initialValues?.marketing_product_id
  );

  const formik = useFormik<DeliveryOrderProductFormValues>({
    enableReinitialize: true,
    initialValues: {
      delivery_date: initialValues?.delivery_date || undefined,
      vehicle_number: initialValues?.vehicle_number || undefined,
      marketing_product_id:
        salesOrder?.id || initialValues?.marketing_product_id || undefined,
      unit_price: initialValues?.unit_price || undefined,
      total_weight: initialValues?.total_weight || undefined,
      qty: initialValues?.qty || undefined,
      avg_weight: initialValues?.avg_weight || undefined,
      total_price: initialValues?.total_price || undefined,
      marketing_product: initialValues?.marketing_product || undefined,
    },
    isInitialValid: false,
    validationSchema: Yup.object().shape({
      ...DeliveryOrderProductSchema.fields,

      qty: Yup.lazy((_, context) => {
        // values diambil aman dari context
        const { parent } = context;

        const mpId = parent?.marketing_product_id;
        const selectedSO = salesOrders.find((item) => item.id === mpId);

        const maxQty = selectedSO?.qty ?? Infinity;

        return Yup.number()
          .min(1, 'Kuantitas wajib diisi!')
          .max(maxQty, `Maksimal kuantitas adalah ${maxQty}`)
          .required('Kuantitas wajib diisi!');
      }),
    }),
    validateOnChange: true,
    validateOnBlur: true,
    onSubmit: async (values) => {
      setFormErrorMessage('');
      if (initialValues?.id) {
        await onUpdateForm?.(initialValues.id, values);
      } else {
        await onUpdateForm?.(values.marketing_product_id as number, values);
      }
      handleResetForm();
      setSelectedProduct(null);
    },
  });

  const handleResetForm = () => {
    setFormErrorMessage('');
    formik.resetForm({
      values: {
        delivery_date: '',
        vehicle_number: '',
        marketing_product_id: undefined,
        unit_price: '',
        total_weight: '',
        qty: '',
        avg_weight: '',
        total_price: '',
        marketing_product: undefined,
      },
    });
    // setSelectedProduct(null);
  };

  const handleBlurField = (field: string) => {
    setCurrentInput(field);

    const qty = Number(formik.values.qty || 0);
    const avgWeight = Number(formik.values.avg_weight || 0);
    const totalWeight = Number(formik.values.total_weight || 0);
    const unitPrice = Number(formik.values.unit_price || 0);
    const totalPrice = Number(formik.values.total_price || 0);

    if (qty <= 0) return;

    switch (field) {
      // ===== SOURCE FIELDS =====
      case 'qty': {
        if (avgWeight > 0) {
          const tw = roundWeight(qty * avgWeight);
          formik.setFieldValue('total_weight', tw);

          // Hitung total_price berdasarkan unit_price × total_weight
          if (unitPrice > 0) {
            formik.setFieldValue('total_price', roundPrice(unitPrice * tw));
          }
        }
        break;
      }

      case 'avg_weight': {
        if (avgWeight > 0) {
          const tw = roundWeight(qty * avgWeight);
          formik.setFieldValue('total_weight', tw);

          // Hitung total_price berdasarkan unit_price × total_weight
          if (unitPrice > 0) {
            formik.setFieldValue('total_price', roundPrice(unitPrice * tw));
          }
        }
        break;
      }

      case 'unit_price': {
        if (unitPrice > 0 && totalWeight > 0) {
          // Hitung total_price berdasarkan unit_price × total_weight
          formik.setFieldValue(
            'total_price',
            roundPrice(unitPrice * totalWeight)
          );
        }
        break;
      }

      // ===== TOTAL EDITABLE =====
      case 'total_weight': {
        if (totalWeight > 0) {
          formik.setFieldValue('avg_weight', roundWeight(totalWeight / qty));

          // Hitung ulang total_price berdasarkan unit_price × total_weight
          if (unitPrice > 0) {
            formik.setFieldValue(
              'total_price',
              roundPrice(unitPrice * totalWeight)
            );
          }
        }
        break;
      }

      case 'total_price': {
        if (totalPrice > 0 && totalWeight > 0) {
          // Hitung unit_price berdasarkan total_price / total_weight
          formik.setFieldValue(
            'unit_price',
            roundPrice(totalPrice / totalWeight)
          );
        }
        break;
      }
    }
  };

  const options = exisitingValues
    ?.map((item) => {
      if (!Boolean(item.qty)) {
        return {
          value: item.id,
          label: `${item.marketing_product?.product_warehouse?.label} - ${item.marketing_product?.kandang?.label}`,
        } as OptionType;
      } else {
        return null;
      }
    })
    ?.filter((item) => item != null) as OptionType[];

  const { setValues: setFormikValues } = formik;

  useEffect(() => {
    if (initialValues) {
      if (!Boolean(initialValues.qty)) {
        handleResetForm();
      } else {
        setFormikValues(initialValues);
        // const value = exisitingValues?.find(
        //   (item) => item.id === initialValues?.id
        // );
        if (initialValues?.marketing_product_id) {
          setSelectedProduct({
            value: initialValues?.id,
            label: `${initialValues?.marketing_product?.product_warehouse?.label} - ${initialValues?.marketing_product?.kandang?.label}`,
          } as OptionType);
        }
      }
    }
  }, [initialValues]);

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

  return (
    <>
      <form
        className='size-full'
        onSubmit={handleFormSubmit}
        onReset={handleResetForm}
      >
        {formikErrorMessage && (
          <div onClick={() => setFormErrorMessage('')} className='my-3 w-full'>
            <Alert color='error'>{formikErrorMessage}</Alert>
          </div>
        )}

        <div className='grid sm:grid-cols-3 gap-4'>
          <SelectInput
            options={options}
            label='Produk'
            placeholder='Pilih Produk'
            isDisabled={formState == 'edit'}
            value={
              selectedProduct
                ? ({
                    value: selectedProduct?.value,
                    label: exisitingValues?.find(
                      (item) => item.id === selectedProduct?.value
                    )?.marketing_product?.product_warehouse?.label,
                  } as OptionType)
                : null
            }
            onChange={(value) => {
              const selected = value as OptionType;
              setSelectedProduct(selected);

              const so = salesOrders?.find(
                (item) => item.id === selected?.value
              );
              if (!so) {
                formik.setValues({
                  ...formik.values,
                  marketing_product_id: undefined,
                  marketing_product: null,
                  qty: '',
                  unit_price: '',
                  total_price: '',
                  avg_weight: '',
                  total_weight: '',
                  vehicle_number: '',
                });
                return;
              }

              formik.setValues({
                ...formik.values,
                marketing_product_id: selected.value as number,
                marketing_product: SalesProductToFieldValues(so),
                qty: so.qty,
                unit_price: so.unit_price,
                total_price: so.total_price,
                avg_weight: so.avg_weight,
                total_weight: so.total_weight,
                vehicle_number: so.vehicle_number,
              });
            }}
            startAdornment={
              selectedProduct && (
                <Badge
                  variant='soft'
                  color='success'
                  size='sm'
                  className={{ badge: 'whitespace-nowrap font-semibold' }}
                >
                  {
                    exisitingValues?.find(
                      (item) => item.id === selectedProduct?.value
                    )?.marketing_product?.kandang?.label
                  }
                </Badge>
              )
            }
            isClearable
            isError={Boolean(formik.errors.marketing_product_id)}
            errorMessage={formik.errors.marketing_product_id}
            required
          />
          <DateInput
            name='delivery_date'
            label='Tanggal'
            value={formik.values.delivery_date ?? undefined}
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
            isError={
              formik.touched.delivery_date &&
              Boolean(formik.errors.delivery_date)
            }
            errorMessage={formik.errors.delivery_date}
            placeholder='Pilih Tanggal'
            className={{
              inputWrapper: 'bg-white',
            }}
            required
          />

          <PatternInput
            name='vehicle_number'
            label='No. Polisi'
            format='AA #### AAA'
            mask='_'
            inputVehicleNumber
            required
            type='text'
            placeholder='B 1234 CDE'
            value={formatVechicleNumber(formik.values.vehicle_number ?? '')}
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
            isError={Boolean(formik.errors.vehicle_number)}
            errorMessage={formik.errors.vehicle_number}
          />
        </div>
        <div className='divider my-6'></div>
        <div className='grid sm:grid-cols-3 gap-4'>
          <NumberInput
            required
            label='Kuantitas'
            name='qty'
            value={formik.values.qty}
            onChange={(e) => {
              formik.handleChange(e);
              setCurrentInput(e.target.name);
            }}
            onBlur={() => handleBlurField('qty')}
            isError={Boolean(formik.errors.qty)}
            errorMessage={formik.errors.qty}
            placeholder='Masukan Kuantitas'
            endAdornment={
              <div className='flex items-center gap-2'>
                <span className='text-sm text-gray-500'>
                  {isResponseSuccess(productData)
                    ? productData?.data?.uom.name
                    : ''}
                </span>
              </div>
            }
            bottomLabel={
              formik.values.marketing_product_id
                ? 'Stok dijual: ' +
                  salesOrders?.find(
                    (item) => item.id === formik.values.marketing_product_id
                  )?.qty +
                  ' ' +
                  (isResponseSuccess(productData)
                    ? productData?.data?.uom.name
                    : '')
                : ''
            }
          />
          <NumberInput
            required
            label={`Harga / ${isResponseSuccess(productData) ? productData?.data?.uom?.name : 'Produk'} (Rp)`}
            name='unit_price'
            value={formik.values.unit_price}
            onChange={(e) => {
              formik.handleChange(e);
              setCurrentInput(e.target.name);
            }}
            onBlur={() => handleBlurField('unit_price')}
            isError={Boolean(formik.errors.unit_price)}
            errorMessage={formik.errors.unit_price}
            placeholder='Masukan Harga Satuan'
          />
          <NumberInput
            required
            label='Avg. Bobot (Kg)'
            name='avg_weight'
            value={formik.values.avg_weight}
            onChange={(e) => {
              formik.handleChange(e);
              setCurrentInput(e.target.name);
            }}
            onBlur={() => handleBlurField('avg_weight')}
            isError={Boolean(formik.errors.avg_weight)}
            errorMessage={formik.errors.avg_weight}
            placeholder='Masukan Bobot Rata-rata'
          />
          <NumberInput
            required
            label='Total Bobot (Kg)'
            name='total_weight'
            value={formik.values.total_weight}
            onChange={(e) => {
              formik.handleChange(e);
              setCurrentInput(e.target.name);
            }}
            onBlur={() => handleBlurField('total_weight')}
            isError={Boolean(formik.errors.total_weight)}
            errorMessage={formik.errors.total_weight}
            placeholder='Masukan Total Bobot'
          />

          <NumberInput
            required
            label='Total Penjualan (Rp)'
            name='total_price'
            value={formik.values.total_price}
            onChange={(e) => {
              formik.handleChange(e);
              setCurrentInput(e.target.name);
            }}
            onBlur={() => handleBlurField('total_price')}
            isError={Boolean(formik.errors.total_price)}
            errorMessage={formik.errors.total_price}
            placeholder='Masukan Total Penjualan'
          />
        </div>

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

        <div className='flex flex-row justify-end gap-3 mt-4'>
          <Button type='reset' color='warning'>
            Reset
          </Button>
          <Button
            type='submit'
            isLoading={formik.isSubmitting}
            disabled={formik.isSubmitting}
          >
            Submit
          </Button>
        </div>
      </form>
    </>
  );
};

export default DeliveryOrderProductForm;
