'use client';

import { useFormik } from 'formik';
import {
  SalesOrderProductFormValues,
  SalesOrderProductSchema,
} from '@/components/pages/marketing/form/repeater/sales-order/SalesOrderProduct.schema';
import { RefObject, useMemo, useState } from 'react';
import SelectInput, {
  OptionType,
  useSelect,
} from '@/components/input/SelectInput';
import { Kandang } from '@/types/api/master-data/kandang';
import { ProductApi, UomApi, WarehouseApi } from '@/services/api/master-data';
import { ProductWarehouse } from '@/types/api/inventory/product-warehouse';
import { ProductWarehouseApi } from '@/services/api/inventory';
import NumberInput from '@/components/input/NumberInput';
import Button from '@/components/Button';
import { isResponseSuccess } from '@/lib/api-helper';
import {
  formatCurrency,
  formatNumber,
  formatVechicleNumber,
} from '@/lib/helper';
import PatternInput from '@/components/input/PatternInput';
import Alert from '@/components/Alert';
import AlertErrorList from '@/components/helper/form/FormErrors';
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
import useSWR from 'swr';

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

const SalesOrderProductForm = ({
  initialValues,
  exisitingValues,
  onSubmitForm,
}: {
  initialValues?: SalesOrderProductFormValues;
  exisitingValues?: SalesOrderProductFormValues[];
  modalRef?: RefObject<HTMLDialogElement | null>;
  onSubmitForm?: (
    value: SalesOrderProductFormValues,
    id?: number
  ) => Promise<void>;
}) => {
  const [formErrorMessage, setFormErrorMessage] = useState('');
  const [currentInput, setCurrentInput] = useState<string>('');
  const [selectedProductWarehouse, setSelectedProductWarehouse] =
    useState<ProductWarehouse | null>(null);

  // ============ Formik ============
  const formik = useFormik<SalesOrderProductFormValues>({
    enableReinitialize: true,
    initialValues: {
      vehicle_number: initialValues?.vehicle_number || '',
      kandang_id: initialValues?.kandang_id || undefined,
      kandang: initialValues?.kandang || null,
      product_warehouse: initialValues?.product_warehouse || null,
      product_warehouse_id: initialValues?.product_warehouse_id || undefined,
      unit_price: initialValues?.unit_price || '',
      total_weight: initialValues?.total_weight || '',
      qty: initialValues?.qty || '',
      avg_weight: initialValues?.avg_weight || '',
      total_price: initialValues?.total_price || '',
      uom: initialValues?.uom || '',
    },
    validationSchema: SalesOrderProductSchema,
    onSubmit: async (values) => {
      setFormErrorMessage('');
      onSubmitForm?.(values, initialValues?.id);
      handleResetForm();
    },
    validateOnBlur: true,
    isInitialValid: false,
  });

  // ===== Options =====
  const {
    options: kandangSourceOptions,
    isLoadingOptions: isLoadingKandangSourceOptions,
    setInputValue: setKandangInputValue,
    loadMore: loadMoreKandang,
  } = useSelect<Kandang>(WarehouseApi.basePath, 'id', 'name');

  const {
    options: warehouseSourceOptions,
    rawData: warehouseSourceRawData,
    isLoadingOptions: isLoadingWarehouseSourceOptions,
    setInputValue: setWarehouseInputValue,
    loadMore: loadMoreWarehouse,
  } = useSelect<ProductWarehouse>(
    ProductWarehouseApi.basePath,
    'id',
    'product.name',
    '',
    {
      warehouse_id: formik.values.kandang_id?.toString() ?? '',
    }
  );

  const productOptionsFiltered = useMemo(() => {
    return warehouseSourceOptions.filter(
      (product) =>
        !exisitingValues
          ?.map((item) => item.product_warehouse_id)
          .includes(product.value)
    );
  }, [warehouseSourceOptions, exisitingValues]);

  // ===== Handler =====
  const kandangChangeHandler = (val: OptionType | OptionType[] | null) => {
    formik.setFieldValue('kandang', val as OptionType);
    formik.setFieldValue('kandang_id', (val as OptionType)?.value);
    formik.setFieldValue('product_warehouse_id', null);
    formik.setFieldValue('product_warehouse', null);
    formik.setFieldValue('qty', '');
  };

  const warehouseChangeHandler = (val: OptionType | OptionType[] | null) => {
    formik.setFieldValue('product_warehouse', val as OptionType);
    const newId = (val as OptionType)?.value;
    formik.setFieldValue('product_warehouse_id', newId);

    if (isResponseSuccess(warehouseSourceRawData) && newId) {
      const productWarehouse = warehouseSourceRawData?.data.find(
        (item: ProductWarehouse) => item.id === newId
      );
      setSelectedProductWarehouse(productWarehouse || null);
      formik.setFieldValue('qty', productWarehouse?.quantity);
      handleBlurField('qty');
    } else {
      formik.setFieldValue('qty', '');
    }
  };

  const handleResetForm = () => {
    setFormErrorMessage('');
    formik.resetForm({
      values: {
        vehicle_number: '',
        kandang_id: undefined,
        kandang: null,
        product_warehouse: null,
        product_warehouse_id: undefined,
        unit_price: '',
        total_weight: '',
        qty: '',
        avg_weight: '',
        total_price: '',
      },
    });
  };

  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;

    // Cek apakah produk memiliki flag OVK atau PAKAN
    const productFlags = selectedProductWarehouse?.product?.flags || [];
    const isOvkOrPakan =
      productFlags.includes('OVK') || productFlags.includes('PAKAN');

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

          // Hitung total_price berdasarkan flag produk
          if (unitPrice > 0) {
            if (isOvkOrPakan) {
              // Untuk OVK/PAKAN: total_price = qty × unit_price
              formik.setFieldValue('total_price', roundPrice(qty * unitPrice));
            } else {
              // Untuk produk lain: total_price = unit_price × total_weight
              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 flag produk
          if (unitPrice > 0) {
            if (isOvkOrPakan) {
              // Untuk OVK/PAKAN: total_price = qty × unit_price
              formik.setFieldValue('total_price', roundPrice(qty * unitPrice));
            } else {
              // Untuk produk lain: total_price = unit_price × total_weight
              formik.setFieldValue('total_price', roundPrice(unitPrice * tw));
            }
          }
        }
        break;
      }

      case 'unit_price': {
        if (unitPrice > 0) {
          if (isOvkOrPakan) {
            // Untuk OVK/PAKAN: total_price = qty × unit_price
            formik.setFieldValue('total_price', roundPrice(qty * unitPrice));
          } else if (totalWeight > 0) {
            // Untuk produk lain: total_price = 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 flag produk
          if (unitPrice > 0) {
            if (isOvkOrPakan) {
              // Untuk OVK/PAKAN: total_price = qty × unit_price
              formik.setFieldValue('total_price', roundPrice(qty * unitPrice));
            } else {
              // Untuk produk lain: total_price = unit_price × total_weight
              formik.setFieldValue(
                'total_price',
                roundPrice(unitPrice * totalWeight)
              );
            }
          }
        }
        break;
      }

      case 'total_price': {
        if (totalPrice > 0) {
          if (isOvkOrPakan && qty > 0) {
            // Untuk OVK/PAKAN: unit_price = total_price / qty
            formik.setFieldValue('unit_price', roundPrice(totalPrice / qty));
          } else if (totalWeight > 0) {
            // Untuk produk lain: unit_price = total_price / total_weight
            formik.setFieldValue(
              'unit_price',
              roundPrice(totalPrice / totalWeight)
            );
          }
        }
        break;
      }
    }
  };

  // ===== Formik Error List =====
  const { formErrorList, close, handleFormSubmit } = useFormikErrorList(
    formik,
    {
      onBeforeSubmit(e) {
        e.preventDefault();
        handleBlurField(currentInput);
        formik.setFieldValue(
          'uom',
          selectedProductWarehouse?.product?.uom?.name
        );
      },
    }
  );

  return (
    <>
      <form
        className='size-full'
        onSubmit={handleFormSubmit}
        onReset={handleResetForm}
      >
        {formErrorMessage && (
          <div onClick={() => setFormErrorMessage('')} className='my-3 w-full'>
            <Alert color='error'>
              {formErrorMessage ? formErrorMessage : ''}
            </Alert>
          </div>
        )}
        <div className='grid sm:grid-cols-3 gap-4 z-200'>
          <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={
              formik.touched.vehicle_number &&
              Boolean(formik.errors.vehicle_number)
            }
            errorMessage={formik.errors.vehicle_number}
          />
          <SelectInput
            required
            label='Kandang'
            options={kandangSourceOptions}
            isLoading={isLoadingKandangSourceOptions}
            value={formik.values.kandang}
            onChange={kandangChangeHandler}
            isClearable
            onInputChange={setKandangInputValue}
            onMenuScrollToBottom={loadMoreKandang}
            isError={
              formik.touched.kandang_id && Boolean(formik.errors.kandang_id)
            }
            errorMessage={formik.errors.kandang_id}
            placeholder='Pilih Kandang'
          />
          <SelectInput
            required
            label='Produk'
            options={productOptionsFiltered}
            isLoading={isLoadingWarehouseSourceOptions}
            value={formik.values.product_warehouse}
            onChange={warehouseChangeHandler}
            onInputChange={setWarehouseInputValue}
            onMenuScrollToBottom={loadMoreWarehouse}
            isClearable
            placeholder={
              formik.values.kandang_id
                ? productOptionsFiltered.length == 0
                  ? 'Tidak ada produk yang tersedia'
                  : 'Pilih produk'
                : 'Pilih Kandang Terlebih Dahulu'
            }
            isDisabled={!formik.values.kandang_id}
            isError={
              formik.touched.product_warehouse_id &&
              Boolean(formik.errors.product_warehouse_id)
            }
            errorMessage={formik.errors.product_warehouse_id}
          />
        </div>
        <div className='divider my-6'></div>
        <div className='grid sm:grid-cols-3 gap-4 z-200'>
          <NumberInput
            required
            label='Kuantitas'
            name='qty'
            value={formik.values.qty}
            onChange={(e) => {
              formik.handleChange(e);
              setCurrentInput(e.target.name);
            }}
            onBlur={() => handleBlurField('qty')}
            isError={formik.touched.qty && 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'>
                  {selectedProductWarehouse?.product?.uom?.name}
                </span>
              </div>
            }
            bottomLabel={
              isResponseSuccess(warehouseSourceRawData) &&
              formik.values.product_warehouse_id
                ? `Stok tersedia: ${formatNumber(
                    warehouseSourceRawData?.data?.find(
                      (item) => item.id === formik.values.product_warehouse_id
                    )?.quantity ?? 0
                  )} ${selectedProductWarehouse?.product?.uom?.name}`
                : ''
            }
          />
          <NumberInput
            required
            label={`Harga / ${selectedProductWarehouse?.product?.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={
              formik.touched.unit_price && 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={
              formik.touched.avg_weight && 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={
              formik.touched.total_weight && 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={
              formik.touched.total_price && Boolean(formik.errors.total_price)
            }
            errorMessage={formik.errors.total_price}
            placeholder='Masukan Total Penjualan'
          />
        </div>

        <div className='mt-4'>
          <AlertErrorList formErrorList={formErrorList} onClose={close} />
        </div>

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

export default SalesOrderProductForm;
