'use client';

import { useCallback, useMemo, useState } from 'react';
import { useFormik } from 'formik';
import useSWR from 'swr';
import { useRouter } from 'next/navigation';
import { Icon } from '@iconify/react';
import { toast } from 'react-hot-toast';
import Button from '@/components/Button';
import TextInput from '@/components/input/TextInput';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import { useModal } from '@/components/Modal';
import { FormHeader } from '@/components/helper/form/FormHeader';
import { FormActions } from '@/components/helper/form/FormActions';

import {
  PurchaseRequestFormSchema,
  PurchaseRequestFormValues,
  getPurchaseRequestFormInitialValues,
  UpdatePurchaseRequestFormSchema,
} from './PurchaseRequestForm.schema';
import { SupplierApi } from '@/services/api/master-data';
import { WarehouseApi } from '@/services/api/master-data';
import { isResponseSuccess, isResponseError } from '@/lib/api-helper';
import { PurchaseApi } from '@/services/api/purchasing';

import Card from '@/components/Card';
import {
  CreatePurchaseRequestPayload,
  Purchase,
} from '@/types/api/purchase/purchase';

interface PurchaseRequestFormProps {
  type?: 'add' | 'edit' | 'detail';
  initialValues?: Purchase;
}

const PurchaseRequestForm = ({
  type = 'add',
  initialValues,
}: PurchaseRequestFormProps) => {
  const router = useRouter();
  const deleteModal = useModal();

  const [selectedPurchaseItems, setSelectedPurchaseItems] = useState<number[]>(
    []
  );
  const [purchaseRequestFormErrorMessage, setPurchaseRequestFormErrorMessage] =
    useState('');
  const [isDeleteLoading, setIsDeleteLoading] = useState(false);

  // ===== FORM HANDLERS =====
  const createPurchaseRequestHandler = useCallback(
    async (payload: CreatePurchaseRequestPayload) => {
      const res = await PurchaseApi.create(payload);
      if (isResponseError(res)) {
        setPurchaseRequestFormErrorMessage(res.message);
        return;
      }
      toast.success(res?.message as string);
      router.push('/purchase');
    },
    [router]
  );

  const updatePurchaseRequestHandler = useCallback(
    async (
      purchaseRequestId: number,
      payload: CreatePurchaseRequestPayload
    ) => {
      const res = await PurchaseApi.update(purchaseRequestId, payload);
      if (isResponseError(res)) {
        setPurchaseRequestFormErrorMessage(res.message);
        return;
      }
      toast.success(res?.message as string);
      router.refresh();
      router.push('/purchase');
    },
    [router]
  );

  const deletePurchaseRequestClickHandler = useCallback(() => {
    deleteModal.openModal();
  }, [deleteModal]);

  const confirmationModalDeleteClickHandler = useCallback(async () => {
    if (!initialValues?.id) return;

    setIsDeleteLoading(true);
    await PurchaseApi.delete(initialValues.id);
    deleteModal.closeModal();
    toast.success('Successfully delete Purchase Request!');
    setIsDeleteLoading(false);
    router.push('/purchase');
  }, [deleteModal, initialValues?.id, router]);

  // ===== API DATA FETCHING =====
  const { data: suppliers, isLoading: isLoadingSuppliers } = useSWR(
    SupplierApi.basePath,
    SupplierApi.getAllFetcher
  );

  const { data: warehouses, isLoading: isLoadingWarehouses } = useSWR(
    WarehouseApi.basePath,
    WarehouseApi.getAllFetcher
  );

  // ===== DATA PROCESSING =====
  const supplierOptions = useMemo(() => {
    if (!isResponseSuccess(suppliers)) return [];
    return (
      suppliers?.data.map((supplier) => ({
        value: supplier.id,
        label: supplier.name,
      })) || []
    );
  }, [suppliers]);

  const warehouseOptions = useMemo(() => {
    if (!isResponseSuccess(warehouses)) return [];
    return (
      warehouses?.data.map((warehouse) => ({
        value: warehouse.id,
        label: warehouse.name,
      })) || []
    );
  }, [warehouses]);

  const formikInitialValues = useMemo<PurchaseRequestFormValues>(
    () => getPurchaseRequestFormInitialValues(initialValues),
    [initialValues]
  );

  const formik = useFormik<PurchaseRequestFormValues>({
    initialValues: formikInitialValues,
    validationSchema:
      type === 'edit'
        ? UpdatePurchaseRequestFormSchema
        : PurchaseRequestFormSchema,
    validateOnChange: true,
    validateOnBlur: true,
    onSubmit: async (values) => {
      const payload: CreatePurchaseRequestPayload = {
        supplier_id: values.supplier_id || 0,
        credit_term: values.credit_term || 0,
        notes: values.notes || '',
        purchase_items: (values.purchase_items || []).map((item) => ({
          warehouse_id: item.warehouse_id || 0,
          product_id: item.product_id || 0,
          product_warehouse_id: item.product_warehouse_id || undefined,
          sub_qty: item.sub_qty || 0,
          total_qty: item.total_qty || 0,
          price:
            typeof item.price === 'number'
              ? item.price
              : parseFloat(item.price) || 0,
        })),
      };

      switch (type) {
        case 'add':
          await createPurchaseRequestHandler(payload);
          break;
        case 'edit':
          await updatePurchaseRequestHandler(
            initialValues?.id as number,
            payload
          );
          break;
      }
    },
  });

  // ===== EVENT HANDLERS =====
  const supplierChangeHandler = (val: string) => {
    const supplierId = parseInt(val) || 0;
    formik.setFieldValue('supplier_id', supplierId);

    const selectedSupplier = supplierOptions.find(
      (option) => option.value === supplierId
    );
    if (selectedSupplier) {
      formik.setFieldValue('supplier', selectedSupplier);
    } else {
      formik.setFieldValue('supplier', null);
    }
  };

  // Purchase Items Handlers
  const addPurchaseItem = () => {
    const newPurchaseItems = [
      ...(formik.values.purchase_items || []),
      {
        warehouse: null,
        warehouse_id: 0,
        product: null,
        product_id: 0,
        product_warehouse: null,
        product_warehouse_id: null,
        sub_qty: 0,
        total_qty: 0,
        price: 0,
      },
    ];
    formik.setFieldValue('purchase_items', newPurchaseItems);
  };

  const removePurchaseItem = (idx: number) => {
    const updatedPurchaseItems = formik.values.purchase_items?.filter(
      (_, i) => i !== idx
    );
    formik.setFieldValue('purchase_items', updatedPurchaseItems);
  };

  const removeSelectedPurchaseItems = () => {
    const updatedPurchaseItems = formik.values.purchase_items?.filter(
      (_, idx) => !selectedPurchaseItems.includes(idx)
    );
    formik.setFieldValue('purchase_items', updatedPurchaseItems);
    setSelectedPurchaseItems([]);
  };

  const handlePurchaseItemChange = (
    idx: number,
    field: string,
    value: string | number
  ) => {
    const integerFields = [
      'warehouse_id',
      'product_id',
      'product_warehouse_id',
      'total_qty',
    ];
    const floatFields = ['price', 'sub_qty'];

    if (integerFields.includes(field)) {
      const numValue = typeof value === 'string' ? parseInt(value) || 0 : value;
      formik.setFieldValue(`purchase_items.${idx}.${field}`, numValue);
    } else if (floatFields.includes(field)) {
      const numValue =
        typeof value === 'string' ? parseFloat(value) || 0 : value;
      formik.setFieldValue(`purchase_items.${idx}.${field}`, numValue);
    } else {
      formik.setFieldValue(`purchase_items.${idx}.${field}`, value);
    }
  };

  return (
    <>
      <section className='w-full'>
        <FormHeader type={type} title='Purchase Request' backUrl='/purchase' />
        <form
          onSubmit={formik.handleSubmit}
          className='w-full mt-8 flex flex-col gap-6'
        >
          {/* Basic Info Card */}
          <Card
            title='Informasi Purchase Request'
            className={{
              wrapper: 'w-full mb-4 shadow',
              body: 'flex flex-col gap-6',
            }}
          >
            <div
              className={
                type === 'detail'
                  ? 'flex flex-col gap-6'
                  : 'grid grid-cols-1 md:grid-cols-2 gap-6'
              }
            >
              <TextInput
                required
                label='Vendor'
                name='supplier_id'
                value={formik.values.supplier_id}
                onChange={(e) => supplierChangeHandler(e.target.value)}
                onBlur={formik.handleBlur}
                isError={
                  formik.touched.supplier_id &&
                  Boolean(formik.errors.supplier_id)
                }
                errorMessage={formik.errors.supplier_id as string}
                readOnly={type === 'detail'}
                type='number'
                placeholder='Masukkan Supplier ID'
              />

              <TextInput
                required
                label='Jatuh tempo (hari)'
                name='credit_term'
                value={formik.values.credit_term}
                onChange={formik.handleChange}
                onBlur={formik.handleBlur}
                isError={
                  formik.touched.credit_term &&
                  Boolean(formik.errors.credit_term)
                }
                errorMessage={formik.errors.credit_term as string}
                readOnly={type === 'detail'}
                type='number'
                placeholder='Masukkan Credit Term'
              />

              <div className={type === 'detail' ? 'col-span-1' : 'col-span-2'}>
                <TextInput
                  label='Notes'
                  name='notes'
                  value={formik.values.notes || ''}
                  onChange={formik.handleChange}
                  onBlur={formik.handleBlur}
                  isError={formik.touched.notes && Boolean(formik.errors.notes)}
                  errorMessage={formik.errors.notes as string}
                  readOnly={type === 'detail'}
                  placeholder='Masukkan catatan'
                />
              </div>
            </div>
          </Card>

          {/* Purchase Items Table */}
          <Card
            title='Item Pembelian'
            className={{
              wrapper: 'w-full mb-4 shadow',
              title: 'mb-4',
            }}
          >
            <div className='overflow-x-auto'>
              <table className='table'>
                <thead>
                  <tr>
                    {type !== 'detail' && (
                      <th>
                        <input
                          type='checkbox'
                          className='checkbox checkbox-sm'
                          checked={
                            formik.values.purchase_items?.length ===
                              selectedPurchaseItems.length &&
                            formik.values.purchase_items?.length > 0
                          }
                          onChange={(e) => {
                            if (e.target.checked) {
                              setSelectedPurchaseItems(
                                formik.values.purchase_items?.map(
                                  (_, idx) => idx
                                ) ?? []
                              );
                            } else {
                              setSelectedPurchaseItems([]);
                            }
                          }}
                        />
                      </th>
                    )}
                    <th>
                      Warehouse ID
                      <span className='text-error'>*</span>
                    </th>
                    <th>
                      Product ID
                      <span className='text-error'>*</span>
                    </th>
                    <th>
                      Product Warehouse ID
                      <span className='text-error'>*</span>
                    </th>
                    <th>
                      Sub Qty
                      <span className='text-error'>*</span>
                    </th>
                    <th>
                      Total Qty
                      <span className='text-error'>*</span>
                    </th>
                    <th>
                      Price
                      <span className='text-error'>*</span>
                    </th>
                    {type !== 'detail' && <th>Action</th>}
                  </tr>
                </thead>
                <tbody>
                  {formik.values.purchase_items?.map((item, idx) => (
                    <tr key={`purchase-item-${idx}`}>
                      {type !== 'detail' && (
                        <td className='!align-middle'>
                          <input
                            type='checkbox'
                            className='checkbox checkbox-sm'
                            checked={selectedPurchaseItems.includes(idx)}
                            onChange={(e) => {
                              if (e.target.checked) {
                                setSelectedPurchaseItems([
                                  ...selectedPurchaseItems,
                                  idx,
                                ]);
                              } else {
                                setSelectedPurchaseItems(
                                  selectedPurchaseItems.filter((i) => i !== idx)
                                );
                              }
                            }}
                          />
                        </td>
                      )}
                      <td>
                        <TextInput
                          required
                          name={`purchase_items.${idx}.warehouse_id`}
                          value={item.warehouse_id}
                          onChange={(e) =>
                            handlePurchaseItemChange(
                              idx,
                              'warehouse_id',
                              e.target.value
                            )
                          }
                          onBlur={formik.handleBlur}
                          type='number'
                          placeholder='Warehouse ID'
                          readOnly={type === 'detail'}
                          className={{
                            wrapper: 'min-w-24',
                          }}
                        />
                      </td>
                      <td>
                        <TextInput
                          required
                          name={`purchase_items.${idx}.product_id`}
                          value={item.product_id}
                          onChange={(e) =>
                            handlePurchaseItemChange(
                              idx,
                              'product_id',
                              e.target.value
                            )
                          }
                          onBlur={formik.handleBlur}
                          type='number'
                          placeholder='Product ID'
                          readOnly={type === 'detail'}
                          className={{
                            wrapper: 'min-w-24',
                          }}
                        />
                      </td>
                      <td>
                        <TextInput
                          name={`purchase_items.${idx}.product_warehouse_id`}
                          value={item.product_warehouse_id || ''}
                          onChange={(e) =>
                            handlePurchaseItemChange(
                              idx,
                              'product_warehouse_id',
                              e.target.value
                            )
                          }
                          onBlur={formik.handleBlur}
                          type='number'
                          placeholder='Product Warehouse ID'
                          readOnly={type === 'detail'}
                          className={{
                            wrapper: 'min-w-24',
                          }}
                        />
                      </td>
                      <td>
                        <TextInput
                          required
                          name={`purchase_items.${idx}.sub_qty`}
                          value={item.sub_qty}
                          onChange={(e) =>
                            handlePurchaseItemChange(
                              idx,
                              'sub_qty',
                              e.target.value
                            )
                          }
                          onBlur={formik.handleBlur}
                          type='number'
                          placeholder='Sub Qty'
                          readOnly={type === 'detail'}
                          className={{
                            wrapper: 'min-w-24',
                          }}
                        />
                      </td>
                      <td>
                        <TextInput
                          required
                          name={`purchase_items.${idx}.total_qty`}
                          value={item.total_qty}
                          onChange={(e) =>
                            handlePurchaseItemChange(
                              idx,
                              'total_qty',
                              e.target.value
                            )
                          }
                          onBlur={formik.handleBlur}
                          type='number'
                          placeholder='Total Qty'
                          readOnly={type === 'detail'}
                          className={{
                            wrapper: 'min-w-24',
                          }}
                        />
                      </td>
                      <td>
                        <TextInput
                          required
                          name={`purchase_items.${idx}.price`}
                          value={item.price}
                          onChange={(e) =>
                            handlePurchaseItemChange(
                              idx,
                              'price',
                              e.target.value
                            )
                          }
                          onBlur={formik.handleBlur}
                          type='number'
                          placeholder='Price'
                          readOnly={type === 'detail'}
                          className={{
                            wrapper: 'min-w-24',
                          }}
                        />
                      </td>
                      {type !== 'detail' && (
                        <td>
                          <div className='flex justify-center'>
                            <Button
                              type='button'
                              color='error'
                              onClick={() => removePurchaseItem(idx)}
                            >
                              <Icon
                                icon='mdi:trash-can'
                                width={24}
                                height={24}
                              />
                            </Button>
                          </div>
                        </td>
                      )}
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            {type !== 'detail' && (
              <div className='flex justify-center items-center mt-4 gap-4'>
                {selectedPurchaseItems.length > 0 && (
                  <Button
                    type='button'
                    color='error'
                    onClick={removeSelectedPurchaseItems}
                    disabled={selectedPurchaseItems.length === 0}
                    className='w-fit'
                  >
                    <Icon icon='mdi:trash-can' width={24} height={24} />
                    Hapus Terpilih ({selectedPurchaseItems.length})
                  </Button>
                )}
                <Button
                  type='button'
                  color='success'
                  onClick={addPurchaseItem}
                  className='w-fit'
                >
                  <Icon icon='ic:round-plus' width={24} height={24} />
                  Tambah Item
                </Button>
              </div>
            )}
          </Card>

          {/* Action buttons */}
          <FormActions<PurchaseRequestFormValues>
            type={type}
            formik={formik}
            editUrl={
              initialValues
                ? `/purchase/detail/edit/?purchaseId=${initialValues.id}`
                : undefined
            }
            onDelete={deletePurchaseRequestClickHandler}
          />
          {purchaseRequestFormErrorMessage && (
            <div role='alert' className='alert alert-error'>
              <Icon
                icon='material-symbols:error-outline'
                width={24}
                height={24}
              />
              <span>{purchaseRequestFormErrorMessage}</span>
            </div>
          )}
        </form>
      </section>

      {type !== 'add' && (
        <ConfirmationModal
          ref={deleteModal.ref}
          type='error'
          text='Apakah anda yakin ingin menghapus data Purchase Request ini?'
          secondaryButton={{
            text: 'Tidak',
          }}
          primaryButton={{
            text: 'Ya',
            color: 'error',
            isLoading: isDeleteLoading,
            onClick: confirmationModalDeleteClickHandler,
          }}
        />
      )}
    </>
  );
};

export default PurchaseRequestForm;
