'use client';

import Button from '@/components/Button';
import SelectInput, {
  OptionType,
  useSelect,
} from '@/components/input/SelectInput';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import AlertErrorList from '@/components/helper/form/FormErrors';
import {
  AreaApi,
  FlockApi,
  KandangApi,
  LocationApi,
  NonstockApi,
  ProductionStandardApi,
} from '@/services/api/master-data';
import { Icon } from '@iconify/react';
import { FormikErrors, useFormik } from 'formik';
import { useRouter } from 'next/navigation';
import { ReactNode, useEffect, useMemo, useState } from 'react';
import useSWR, { KeyedMutator } from 'swr';
import {
  ProjectFlockBudgetsSchemaType,
  ProjectFlockFormSchema,
  ProjectFlockFormValues,
  UpdateProjectFlockFormSchema,
} from '@/components/pages/production/project-flock/form/ProjectFlockForm.schema';
import {
  CreateProjectFlockPayload,
  ProjectFlock,
  ProjectFlockBudget,
} from '@/types/api/production/project-flock';
import toast from 'react-hot-toast';
import { Kandang } from '@/types/api/master-data/kandang';
import { ProjectFlockApi } from '@/services/api/production/project-flock';
import { BaseApiResponse } from '@/types/api/api-general';
import { FLOCK_CATEGORY_OPTIONS } from '@/config/constant';
import { useModal } from '@/components/Modal';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import NumberInput from '@/components/input/NumberInput';
import ProjectFlockKandangTable from '@/components/pages/production/project-flock/form/ProjectFlockKandangTable';
import { Nonstock } from '@/types/api/master-data/nonstock';
import { useUiStore } from '@/stores/ui/ui.store';
import RequirePermission from '@/components/helper/RequirePermission';
import DrawerHeader from '@/components/helper/drawer/DrawerHeader';
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
import { cn, formatCurrency, formatDate } from '@/lib/helper';
import Tooltip from '@/components/Tooltip';
import Table from '@/components/Table';
import { ColumnDef } from '@tanstack/react-table';
import StatusBadge from '@/components/helper/StatusBadge';
import { getUniqueFormikErrors } from '@/lib/formik-helper';
import { useProjectFlockStore } from '@/stores/production/project-flock/project-flock.store';

interface ProjectFlockFormProps {
  formType?: 'add' | 'edit' | 'detail';
  initialValues?: ProjectFlock;
  refreshProjectFlocks?: KeyedMutator<
    BaseApiResponse<ProjectFlock> | undefined
  >;
}

export interface ProjectFlockFormConfirmationTableType {
  label: string;
  value: ReactNode;
  subRows?: ProjectFlockFormConfirmationTableType[];
}

export const ProjectFlockFormConfirmationTable = ({
  projectFlockForm,
  kandangs,
}: {
  projectFlockForm?: ProjectFlockFormValues;
  kandangs: Kandang[];
}) => {
  const confirmationTableColumns: ColumnDef<ProjectFlockFormConfirmationTableType>[] =
    [
      {
        header: 'Label',
        accessorKey: 'label',
        enableSorting: false,
        cell: ({ row }) => {
          const isSubRow = row.depth > 0;

          return (
            <>
              {!isSubRow && row.original.label}

              {isSubRow && (
                <div
                  className={cn('w-full min-h-full flex items-stretch gap-0')}
                >
                  <div className='w-px mx-4 bg-base-content/10' />
                  <span className='p-3'>{row.original.label}</span>
                </div>
              )}
            </>
          );
        },
      },
      {
        header: 'Value',
        accessorKey: 'value',
        enableSorting: false,
        cell: ({ row }) => row.original.value,
      },
    ];

  const productsData: ProjectFlockFormConfirmationTableType[] =
    projectFlockForm?.project_budgets?.map((product) => ({
      label: 'Jenis Produk',
      value: product.nonstock?.label ?? '-',
      subRows: [
        {
          label: 'Jumlah Pembelian',
          value: String(product.qty),
        },
        {
          label: 'Harga Satuan',
          value: String(formatCurrency(Number(product.price))),
        },
        {
          label: 'Total Harga',
          value: String(formatCurrency(Number(product.total_price))),
        },
      ],
    })) ?? [];

  const confirmationTableData: ProjectFlockFormConfirmationTableType[] = [
    {
      label: 'Tanggal',
      value: formatDate(Date.now(), 'DD MMMM YYYY'),
    },
    {
      label: 'Area',
      value: projectFlockForm?.area?.label ?? '-',
    },
    {
      label: 'Lokasi',
      value: projectFlockForm?.location?.label ?? '-',
    },
    {
      label: 'Flock',
      value: projectFlockForm?.flock?.label ?? '-',
    },
    {
      label: 'Kategori',
      value: projectFlockForm?.category ?? '-',
    },
    {
      label: 'Standar Produksi',
      value: projectFlockForm?.production_standard?.label ?? '-',
    },
    {
      label: 'Periode',
      value: projectFlockForm?.periode ?? '-',
    },
    {
      label: 'Informasi Kandang',
      value: '',
      subRows:
        projectFlockForm?.kandang_ids?.map((kandang_id) => {
          const kandang = kandangs.find((kandang) => kandang.id === kandang_id);

          const kandangName = kandang?.name ?? '-';
          const kandangAvailability = kandang?.status;

          return {
            label: kandangName,
            value: (
              <StatusBadge
                color={
                  kandangAvailability === 'NON_ACTIVE' ? 'info' : 'neutral'
                }
                text={
                  kandangAvailability === 'NON_ACTIVE'
                    ? 'Tersedia'
                    : 'Tidak Tersedia'
                }
                className={{ badge: 'text-nowrap' }}
              />
            ),
          };
        }) ?? [],
    },
    {
      label: 'Estimasi Anggaran per Kandang',
      value: '',
    },
    ...productsData,
  ];

  return (
    <Table<ProjectFlockFormConfirmationTableType>
      columns={confirmationTableColumns}
      data={confirmationTableData}
      withPagination={false}
      pageSize={10000}
      expanded={true}
      getSubRows={(row) => row.subRows}
      className={{
        headerRowClassName: 'border-b border-base-content/10',
        bodyRowClassName: 'border-none',
        bodySubRowClassName: () => 'border-none',
        bodySubRowColumnClassName: () => 'first:p-0',
      }}
    />
  );
};

const ProjectFlockForm = ({
  formType = 'add',
  initialValues,
}: ProjectFlockFormProps) => {
  // State
  const router = useRouter();
  const setIsSuccess = useProjectFlockStore((s) => s.setIsSuccess);
  const setCreatedProjectFlock = useProjectFlockStore(
    (s) => s.setCreatedProjectFlock
  );

  const [formStep, setFormStep] = useState<'form' | 'confirmation'>('form');

  const [projectFlockFormErrorMessage, setProjectFlockFormErrorMessage] =
    useState('');
  const [selectedArea, setSelectedArea] = useState('');
  const [selectedLocation, setSelectedLocation] = useState('');
  const [selectedCategory, setSelectedCategory] = useState('');
  const [disabledLocation, setDisabledLocation] = useState(
    initialValues?.location?.id ? false : true
  );
  const [, setOpenSelectKandangs] = useState(
    initialValues?.kandangs && initialValues?.kandangs?.length > 0
  );
  const [optionsKandang, setOptionsKandang] = useState<Kandang[]>(
    initialValues?.kandangs ?? []
  );
  const [selectedFlock, setSelectedFlock] = useState<string | undefined>(
    initialValues?.flock_name?.slice(
      0,
      initialValues?.flock_name?.lastIndexOf(' ')
    ) ?? ''
  );
  const subscribeValidate = useUiStore((s) => s.subscribeValidate);
  const setIsValid = useUiStore((s) => s.setIsValid);

  const deleteModal = useModal();

  const [isDeleteLoading, setIsDeleteLoading] = useState(false);

  const [rowSelection, setRowSelection] = useState<Record<string, boolean>>(
    () =>
      Object.fromEntries(
        (initialValues?.kandangs ?? []).map((k: Kandang) => [
          k.id.toString(),
          true,
        ])
      )
  );

  // Fetch Data
  const {
    setInputValue: setInputValueFlock,
    isLoadingOptions: isLoadingFlocks,
    options: optionsFlock,
    loadMore: loadMoreFlock,
  } = useSelect(FlockApi.basePath, 'id', 'name', 'search', {
    project_category: selectedCategory,
    location_id: selectedLocation,
    area_id: selectedArea,
  });

  const {
    setInputValue: setInputValueArea,
    options: optionsArea,
    isLoadingOptions: isLoadingAreas,
    loadMore: loadMoreArea,
  } = useSelect(AreaApi.basePath, 'id', 'name');

  const {
    options: optionsLocation,
    isLoadingOptions: isLoadingLocations,
    setInputValue: setInputValueLocation,
    loadMore: loadMoreLocation,
  } = useSelect(LocationApi.basePath, 'id', 'name', 'search', {
    area_id:
      selectedArea != ''
        ? selectedArea
        : ((initialValues?.area?.id ?? '') as string),
  });

  const {
    options: optionsProductionStandards,
    isLoadingOptions: isLoadingProductionStandards,
    setInputValue: setInputValueProductionStandard,
    loadMore: loadMoreProductionStandard,
  } = useSelect(ProductionStandardApi.basePath, 'id', 'name', 'search', {
    project_category: selectedCategory,
  });

  const kandangUrl = `${KandangApi.basePath}?${new URLSearchParams({
    search: '',
    location_id: selectedLocation == '' ? '0' : selectedLocation,
    limit: '500',
  }).toString()}`;
  const {
    data: kandang,
    isLoading: isLoadingKandang,
    mutate: refreshKandang,
  } = useSWR(kandangUrl, KandangApi.getAllFetcher);

  const { data: periodFlocks, mutate: refreshPeriodFlocks } = useSWR(
    selectedFlock ? `${selectedFlock?.toString()}/periods` : undefined,
    () => ProjectFlockApi.getNextPeriod(parseInt(selectedLocation as string))
  );

  const {
    options: optionsNonstock,
    rawData: nonstocks,
    isLoadingOptions: isLoadingNonstocks,
    setInputValue: setInputValueNonstock,
    loadMore: loadMoreNonstock,
  } = useSelect<Nonstock>(NonstockApi.basePath, 'id', 'name');

  useEffect(() => {
    if (isResponseSuccess(kandang)) {
      if (selectedLocation) {
        setOptionsKandang(kandang.data);
        setOpenSelectKandangs(true);
      } else {
        formik.setFieldValue('kandang_ids', []);
        setOptionsKandang([]);
        setOpenSelectKandangs(false);
        const selectedRowIds = Object.keys(rowSelection)
          .filter((id) => rowSelection[id])
          .map((id) => parseInt(id));
        if (
          JSON.stringify(kandang.data.map((k) => k.id)) !==
          JSON.stringify(formik.values.kandang_ids)
        ) {
          formik.setFieldValue('kandang_ids', []);
          setRowSelection({});
        } else {
          formik.setFieldValue('kandang_ids', selectedRowIds);
        }
      }
      refreshPeriodFlocks();
    }
  }, [kandang, selectedLocation]);
  useEffect(() => {
    if (initialValues?.kandangs) {
      refreshKandang();
      setOpenSelectKandangs(true);

      const newRowSelection = Object.fromEntries(
        initialValues.kandangs.map((k: Kandang) => [k.id.toString(), true])
      );
      setRowSelection(newRowSelection);
    }
  }, [initialValues, kandang]);

  // Options Handler
  const areaChangeHandler = (val: OptionType | OptionType[] | null) => {
    formik.setFieldValue('area_id', (val as OptionType)?.value);
    formik.setFieldValue('area', val);

    if (Boolean(val)) {
      formik.setFieldTouched('area_id', false);
      formik.setFieldError('area_id', '');
    } else {
      formik.setFieldTouched('area_id', true);
    }

    setSelectedArea((val as OptionType)?.value as string);
    setSelectedLocation('');
    const disabled = (val as OptionType)?.value == null;
    setDisabledLocation(disabled);

    formik.setFieldValue('location', null);
    formik.setFieldValue('location_id', 0);
    formik.setFieldTouched('location', false);
    formik.setFieldTouched('location_id', false);
  };

  const locationChangeHandler = (val: OptionType | OptionType[] | null) => {
    formik.setFieldValue('kandang_ids', []);
    setSelectedLocation((val as OptionType)?.value as string);
    optionChangeHandler(val, 'location');
    const selectedRowIds = Object.keys(rowSelection)
      .filter((id) => rowSelection[id])
      .map((id) => parseInt(id));
    formik.setFieldValue('kandang_ids', selectedRowIds);
  };

  const optionChangeHandler = (
    val: OptionType | OptionType[] | null,
    inputName: string
  ) => {
    formik.setFieldValue(inputName, val);
    formik.setFieldValue(
      `${inputName}_id`,
      val ? (val as OptionType)?.value : 0
    );

    if (Boolean(val)) {
      formik.setFieldTouched(`${inputName}_id`, false);
      formik.setFieldError(`${inputName}_id`, '');
    } else {
      formik.setFieldTouched(`${inputName}_id`, true);
    }
  };

  const categoryChangeHandler = (val: OptionType | OptionType[] | null) => {
    // Reset production standard when category is changed
    formik.setFieldValue('production_standard_id', '');
    formik.setFieldValue('production_standard', '');

    formik.setFieldValue('category_option', val);
    formik.setFieldValue('category', val ? (val as OptionType)?.value : '');

    setSelectedCategory((val as OptionType)?.value as string);

    if (Boolean(val)) {
      formik.setFieldTouched('category', false);
      formik.setFieldError('category', '');
    } else {
      formik.setFieldTouched('category', true);
    }
  };

  // Submit Handler
  const createProjectFlockHandler = async (
    payload: CreateProjectFlockPayload
  ) => {
    const createProjectFlockRes = await ProjectFlockApi.create(payload);

    if (isResponseSuccess(createProjectFlockRes)) {
      toast.success(createProjectFlockRes?.message as string);
      handleReset();
      setCreatedProjectFlock(createProjectFlockRes?.data ?? null);
      setIsSuccess(true);
      router.push('/production/project-flock');
    }
    if (isResponseError(createProjectFlockRes)) {
      setProjectFlockFormErrorMessage(createProjectFlockRes?.message as string);
      toast.error(createProjectFlockRes?.message as string);
    }
  };
  const updateProjectFlockHandler = async (
    payload: CreateProjectFlockPayload
  ) => {
    const updateProjectFlockRes = await ProjectFlockApi.resubmit(
      initialValues?.id as number,
      payload
    );

    if (isResponseSuccess(updateProjectFlockRes)) {
      toast.success(updateProjectFlockRes?.message as string);
      handleReset();
      setCreatedProjectFlock(updateProjectFlockRes?.data ?? null);
      setIsSuccess(true);
      router.push('/production/project-flock');
    }
    if (isResponseError(updateProjectFlockRes)) {
      setProjectFlockFormErrorMessage(updateProjectFlockRes?.message as string);
      toast.error(updateProjectFlockRes?.message as string);
    }
  };
  const handleReset = () => {
    formik.resetForm();
    setSelectedArea('');
    setSelectedLocation('');
    setDisabledLocation(true);
    setOpenSelectKandangs(false);
    setOptionsKandang([]);
    formikSetValues(formikInitialValues);
  };

  const [, setFormikLastValues] = useState<ProjectFlockFormValues | undefined>(
    undefined
  );

  // Formik InitialValue
  const formikInitialValues = useMemo<ProjectFlockFormValues>(() => {
    const trimFlock =
      initialValues?.flock_name?.slice(
        0,
        initialValues?.flock_name?.lastIndexOf(' ')
      ) ?? '';
    // const optionFind = optionsFlock.find((flock) => {
    //   return flock.label == trimFlock;
    // }) as OptionType;
    return {
      flock:
        optionsFlock.find((flock) => {
          return flock.label == trimFlock;
        }) ?? null,
      area: initialValues?.area
        ? {
            value: initialValues.area?.id,
            label: initialValues.area.name,
          }
        : null,
      category_option: initialValues?.category
        ? {
            value: initialValues.category,
            label: initialValues.category,
          }
        : null,
      production_standard: initialValues?.production_standard
        ? {
            value: initialValues.production_standard?.id,
            label: initialValues.production_standard.name,
          }
        : null,
      location: initialValues?.location
        ? {
            value: initialValues.location?.id,
            label: initialValues.location.name,
          }
        : null,
      flock_name:
        optionsFlock.find((flock) => {
          return flock.label == trimFlock;
        })?.label ?? trimFlock,
      area_id: initialValues?.area?.id ?? 0,
      category: initialValues?.category as NonNullable<
        'GROWING' | 'LAYING' | undefined
      >,
      production_standard_id: initialValues?.production_standard?.id ?? 0,
      location_id: initialValues?.location?.id ?? 0,
      kandang_ids: initialValues?.kandangs?.map(
        (k: Kandang) => k.id
      ) as number[],
      periode: initialValues?.period ?? '',
      project_budgets: initialValues?.project_budgets?.map((budget) => {
        return {
          nonstock: {
            value: budget.nonstock?.id ?? '',
            label: budget.nonstock?.name ?? '',
          },
          nonstock_id: budget.nonstock?.id ?? '',
          qty: budget.qty,
          price: budget.price,
          total_price: budget.qty * budget.price,
        };
      }) ?? [
        {
          nonstock: null,
          nonstock_id: '',
          qty: '',
          price: '',
          total_price: '',
        },
      ],
    };
  }, [initialValues, optionsFlock]);

  // Formik
  const formik = useFormik<ProjectFlockFormValues>({
    initialValues: {
      ...formikInitialValues,
    } as ProjectFlockFormValues,
    validationSchema:
      formType == 'add' ? ProjectFlockFormSchema : UpdateProjectFlockFormSchema,
    validateOnBlur: true,
    onSubmit: async (values) => {
      setProjectFlockFormErrorMessage('');
      const payload: CreateProjectFlockPayload = {
        flock_name: values.flock_name as string,
        area_id: values.area_id as number,
        category: values.category as string,
        production_standard_id: values.production_standard_id as number,
        location_id: values.location_id as number,
        periode: parseInt(values.periode as unknown as string),
        kandang_ids: values.kandang_ids as number[],
        project_budgets: values.project_budgets.flatMap((budget) => {
          return {
            nonstock_id: budget.nonstock_id,
            qty: budget.qty,
            price: budget.price,
          } as ProjectFlockBudget;
        }),
      };

      setFormikLastValues(values);

      switch (formType) {
        case 'add':
          await createProjectFlockHandler(payload);
          break;
        case 'edit':
          await updateProjectFlockHandler(payload);
          break;
        default:
          break;
      }
    },
  });
  const { setValues: formikSetValues } = formik;

  // Effect Initial
  useEffect(() => {
    if (formType == 'detail') {
      formik.setFieldValue('area', {
        value: initialValues?.area?.id,
        label: initialValues?.area?.name,
      });
      formik.setFieldValue('area_id', initialValues?.area_id);
      if (initialValues?.area_id) {
        setSelectedArea(initialValues?.area_id.toString() as string);
      }
    }
  }, [initialValues, setSelectedArea, formType]);

  useEffect(() => {
    const trimFlock =
      initialValues?.flock_name?.slice(
        0,
        initialValues?.flock_name?.lastIndexOf(' ')
      ) ?? '';
    formikSetValues({
      ...formikInitialValues,
      flock: optionsFlock.find((flock) => {
        return flock.label == trimFlock;
      }) as OptionType,
      flock_name: trimFlock ?? '',
    });
  }, [formikSetValues]);

  // Aktifkan lokasi jika formType = 'detail'
  useEffect(() => {
    if (formType === 'detail') {
      setDisabledLocation(false);
    }
  }, [formType]);

  // Set lokasi otomatis berdasarkan initialValues saat formType = 'detail'
  useEffect(() => {
    if (formType != 'add') {
      if (initialValues?.location?.id) {
        setSelectedLocation(initialValues.location?.id.toString());
        setDisabledLocation(false); // biar dropdown lokasi aktif juga
      }
    }
  }, [formType, initialValues]);

  useEffect(() => {
    const selectedRowIds = Object.keys(rowSelection)
      .filter((id) => rowSelection[id])
      .map((id) => parseInt(id));
    formikSetValues({
      ...formik.values,
      kandang_ids: selectedRowIds,
    });
  }, [rowSelection, formikSetValues]);

  useEffect(() => {
    const unsub = subscribeValidate(() => {
      formik.validateForm().then((errors) => {
        if (Object.keys(errors).length > 0) {
          // Membentuk touched object yang strongly-typed
          const touched: Record<string, boolean | Record<string, boolean>[]> =
            {};
          Object.keys(formik.values).forEach((key) => {
            if (
              key === 'project_budgets' &&
              Array.isArray(formik.values.project_budgets)
            ) {
              touched[key] = formik.values.project_budgets.map(() => ({})); // Mark each item as touched if it's an array
            } else {
              touched[key] = true;
            }
          });

          formik.setTouched(touched, true);
        }
        setIsValid(Object.keys(errors).length === 0);
      });
    });

    return unsub;
  }, []);

  // Actions handler
  const confirmationModalDeleteClickHandler = async () => {
    setIsDeleteLoading(true);
    const deleteProjectFlockRes = await ProjectFlockApi.delete(
      initialValues?.id as number
    );

    if (isResponseSuccess(deleteProjectFlockRes)) {
      toast.success(deleteProjectFlockRes?.message as string);
      router.push('/production/project-flock');
    }
    if (isResponseError(deleteProjectFlockRes)) {
      toast.error(deleteProjectFlockRes?.message as string);
    }
    setIsDeleteLoading(false);
  };

  const onAddBudgetRowHandler = () => {
    const newProjectBudgets = [
      ...(formik.values.project_budgets ?? []),
      {
        nonstock: null,
        nonstock_id: '',
        qty: '',
        price: '',
      },
    ];
    formik.setFieldValue('project_budgets', newProjectBudgets);
  };

  const onDeleteBudgetRowHandler = (nonstock_id: number, index?: number) => {
    if (!nonstock_id) {
      const updatedBudgets = formik.values.project_budgets
        .map((budget, i) => {
          if (i == index) {
            return null;
          } else {
            return budget;
          }
        })
        .filter((budget) => budget != null);
      formik.setFieldValue('project_budgets', updatedBudgets);
    } else {
      const updatedBudgets = (formik.values.project_budgets ?? []).filter(
        (budget) => budget.nonstock_id !== nonstock_id
      );
      formik.setFieldValue('project_budgets', updatedBudgets);
    }
  };

  const handleBudgetChange = (
    index: number,
    fieldName: 'qty' | 'price' | 'total_price',
    value: string
  ) => {
    const updatedBudgets = [...formik.values.project_budgets];
    const currentBudget = updatedBudgets[index];

    const isNewValueEmpty = value === '';

    let numericValue: number;

    if (isNewValueEmpty) {
      (currentBudget[fieldName] as string) = '';
      numericValue = 0;

      formik.setFieldValue('project_budgets', updatedBudgets);
      return;
    } else {
      numericValue = Math.max(0, parseFloat(value) || 0);

      (currentBudget[fieldName] as number) = numericValue;
    }

    const getSafeNumber = (val: string | number) =>
      Math.max(0, parseFloat(String(val)) || 0);

    const currentQty = getSafeNumber(currentBudget.qty);
    const currentPrice = getSafeNumber(currentBudget.price);
    const currentTotal = getSafeNumber(currentBudget.total_price);

    let newQty = currentQty;
    let newPrice = currentPrice;
    let newTotal = currentTotal;

    if (fieldName === 'price') {
      // Jika Harga Satuan diubah, hitung Total Harga
      newTotal = newQty * numericValue;
      newPrice = numericValue;
    } else if (fieldName === 'qty') {
      // Jika Kuantitas diubah, hitung Total Harga
      newTotal = numericValue * newPrice;
      newQty = numericValue;
    } else if (fieldName === 'total_price') {
      // Jika Total Harga diubah, hitung Harga Satuan
      newTotal = numericValue;
      if (newQty > 0) {
        newPrice = newTotal / newQty;
      } else {
        // Jika Qty 0, Harga Satuan tetap 0
        newPrice = 0;
      }
    }

    currentBudget.qty = newQty;
    currentBudget.price = newPrice;
    currentBudget.total_price = newTotal;

    formik.setFieldValue('project_budgets', updatedBudgets);
  };

  const selectedPeriod = isResponseSuccess(periodFlocks)
    ? periodFlocks.data.find((kandang) =>
        formik.values.kandang_ids?.includes(kandang.id)
      )?.period
    : undefined;

  const inputPeriod =
    (initialValues?.period ?? selectedPeriod == 0) ? 1 : selectedPeriod;

  const filteredNonStockOptions = optionsNonstock.filter((nonstock) => {
    const isNonstockAlreadyInBudgets = (
      formik.values.project_budgets ?? []
    ).some((budget) => budget.nonstock_id === nonstock.value);

    return !isNonstockAlreadyInBudgets;
  });

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

  return (
    <>
      <form
        onSubmit={(e) => {
          e.preventDefault();

          const submitHandler = async () => {
            const validateFormErrorResult = await formik.validateForm();
            const isFormError = Object.keys(validateFormErrorResult).length > 0;

            if (isFormError) {
              const errorMessages = getUniqueFormikErrors(
                validateFormErrorResult
              );
              setFormErrorList(errorMessages);
            }

            if (isFormError) {
              return;
            }

            if (formStep === 'form') {
              setFormStep('confirmation');
              return;
            }

            handleFormSubmit(e);
          };

          submitHandler();
        }}
        onReset={formik.handleReset}
        className='w-full h-full sm:w-[446px] flex flex-col'
      >
        {/* Header */}
        <DrawerHeader
          leftIcon={
            formType == 'add' ? 'heroicons:chevron-left' : 'mdi:arrow-left'
          }
          // leftIconHref={
          //   formType == 'add'
          //     ? '/production/project-flock'
          //     : `/production/project-flock/detail?projectFlockId=${initialValues?.id}`
          // }
          leftIconOnClick={() => {
            if (formStep === 'confirmation') {
              setFormStep('form');
              return;
            }

            if (formType == 'add') {
              router.push('/production/project-flock');
            } else {
              router.push(
                `/production/project-flock/detail?projectFlockId=${initialValues?.id}`
              );
            }
          }}
          leftIconClassName='hover:text-gray-400'
          subtitle={formType == 'add' ? 'Add List Flock' : 'Update Flock'}
          className='sticky top-0 z-10 bg-base-100'
        >
          {formType == 'edit' && (
            <Button
              type='button'
              variant='ghost'
              color='none'
              onClick={() => {
                if (initialValues?.id) {
                  deleteModal.openModal();
                }
              }}
              className='p-0 text-error'
            >
              <Tooltip content='Hapus' position='bottom'>
                <Icon icon='heroicons:trash' width={20} height={20} />
              </Tooltip>
            </Button>
          )}

          {formType == 'add' && (
            <Button
              type='button'
              variant='ghost'
              color='none'
              onClick={() => {
                router.push('/production/project-flock');
              }}
              className='p-0 text-error'
            >
              <Tooltip content='Hapus' position='bottom'>
                <Icon icon='heroicons:trash' width={20} height={20} />
              </Tooltip>
            </Button>
          )}
        </DrawerHeader>

        <div className='w-auto h-full overflow-y-auto'>
          {formStep === 'form' && (
            <div className='h-full'>
              {/* Form Informasi Umum */}
              <div className='flex flex-col p-4'>
                <h2 className='text-base font-medium text-base-content/50 font-roboto'>
                  Informasi Umum
                </h2>

                <SelectInput
                  required
                  label='Area'
                  placeholder='Pilih Area'
                  value={formik.values.area as OptionType}
                  onChange={areaChangeHandler}
                  options={optionsArea}
                  isLoading={isLoadingAreas}
                  isError={
                    formik.touched.area_id && Boolean(formik.errors.area_id)
                  }
                  errorMessage={formik.errors.area_id as string}
                  onInputChange={setInputValueArea}
                  onMenuScrollToBottom={loadMoreArea}
                  isClearable
                  isDisabled={formType != 'add'}
                />
                <SelectInput
                  required
                  label='Lokasi'
                  placeholder='Pilih Lokasi'
                  value={formik.values.location as OptionType}
                  onChange={locationChangeHandler}
                  options={
                    selectedArea != '' || initialValues?.area?.id
                      ? optionsLocation
                      : []
                  }
                  isLoading={isLoadingLocations}
                  isError={
                    formik.touched.location_id &&
                    Boolean(formik.errors.location_id)
                  }
                  onInputChange={setInputValueLocation}
                  onMenuScrollToBottom={loadMoreLocation}
                  errorMessage={formik.errors.location_id as string}
                  isClearable
                  isDisabled={formType != 'add' || disabledLocation}
                />
                <SelectInput
                  required
                  label='Flock'
                  placeholder='Pilih Flock'
                  value={
                    formik.values.flock_name
                      ? ({
                          label: formik.values.flock_name,
                          value: optionsFlock.find((flock) => {
                            return flock.label === formik.values.flock_name;
                          })?.value,
                        } as OptionType)
                      : undefined
                  }
                  onChange={(val) => {
                    optionChangeHandler(val, 'flock');
                    setSelectedFlock((val as OptionType)?.label);
                    formik.setFieldValue(
                      'flock_name',
                      (val as OptionType)?.label
                    );
                  }}
                  options={optionsFlock}
                  onInputChange={setInputValueFlock}
                  onMenuScrollToBottom={loadMoreFlock}
                  isLoading={isLoadingFlocks}
                  isError={
                    formik.touched.flock_name &&
                    Boolean(formik.errors.flock_name)
                  }
                  errorMessage={formik.errors.flock_name as string}
                  isClearable
                  isDisabled={formType != 'add'}
                />
                <SelectInput
                  required
                  label='Kategori'
                  placeholder='Pilih Kategori'
                  value={formik.values.category_option as OptionType}
                  onChange={categoryChangeHandler}
                  options={FLOCK_CATEGORY_OPTIONS}
                  isError={
                    formik.touched.category && Boolean(formik.errors.category)
                  }
                  errorMessage={formik.errors.category as string}
                  isClearable
                  isDisabled={formType != 'add'}
                />
                <SelectInput
                  required
                  label='Standar Produksi'
                  placeholder='Pilih Standar Produksi'
                  value={formik.values.production_standard as OptionType}
                  onChange={(val) => {
                    optionChangeHandler(val, 'production_standard');
                  }}
                  onInputChange={setInputValueProductionStandard}
                  onMenuScrollToBottom={loadMoreProductionStandard}
                  options={optionsProductionStandards}
                  isLoading={isLoadingProductionStandards}
                  isError={
                    formik.touched.production_standard_id &&
                    Boolean(formik.errors.production_standard_id)
                  }
                  errorMessage={formik.errors.production_standard_id as string}
                  isClearable
                  isDisabled={formType != 'add'}
                />
                <NumberInput
                  name='periode'
                  label='Periode'
                  placeholder='Periode Flock'
                  value={formik.values.periode}
                  onChange={formik.handleChange}
                  onBlur={formik.handleBlur}
                  allowNegative={false}
                  decimalScale={0}
                  isError={
                    formik.touched.periode && Boolean(formik.errors.periode)
                  }
                  errorMessage={formik.errors.periode as string}
                />
              </div>

              {/* Form Pilih Kandang */}

              <div className='flex flex-col gap-3 p-4 border-y border-base-content/10'>
                <h2 className='text-base font-medium text-base-content/50 font-roboto'>
                  Informasi Kandang
                </h2>
                <div className='overflow-x-auto duration-300 ease-in-out'>
                  {isLoadingKandang && (
                    <span className='loading loading-dots loading-xl block mx-auto' />
                  )}
                  <ProjectFlockKandangTable
                    listPeriods={
                      isResponseSuccess(periodFlocks) ? periodFlocks.data : []
                    }
                    listKandang={optionsKandang}
                    rowSelection={rowSelection}
                    setRowSelection={setRowSelection}
                    selectedIds={formik.values.kandang_ids}
                    formType={formType}
                    initialValues={initialValues}
                  />
                </div>
              </div>

              {/* Card Estimasi Budget */}
              <div className='flex flex-col'>
                <div className='flex flex-col'>
                  {formik.values.project_budgets &&
                  formik.values.project_budgets.length > 0 ? (
                    formik.values.project_budgets.map((budget, index) => {
                      const nonstockUomName = isResponseSuccess(nonstocks)
                        ? (nonstocks.data.find(
                            (ns) => ns.id === budget.nonstock_id
                          )?.uom?.name ?? '')
                        : '';

                      return (
                        <div
                          key={index}
                          className='flex flex-col p-4 border-b border-base-content/10'
                        >
                          <div className='flex flex-row justify-between items-center'>
                            <h2 className='text-base font-medium text-base-content/50 font-roboto'>
                              Estimasi Anggaran Per Flock
                            </h2>

                            {formik.values.project_budgets.length > 1 && (
                              <Button
                                type='button'
                                variant='ghost'
                                color='none'
                                onClick={() =>
                                  onDeleteBudgetRowHandler(
                                    budget.nonstock_id as number,
                                    index
                                  )
                                }
                                className='p-0 text-error'
                              >
                                <Icon
                                  icon='heroicons:trash'
                                  width={20}
                                  height={20}
                                />
                              </Button>
                            )}
                          </div>

                          <div className='flex flex-row justify-between items-center'>
                            <SelectInput
                              isClearable
                              label='Jenis Produk'
                              options={filteredNonStockOptions ?? []}
                              isLoading={isLoadingNonstocks}
                              placeholder='Pilih Jenis Produk'
                              value={
                                formik.values.project_budgets[index].nonstock
                              }
                              onInputChange={setInputValueNonstock}
                              onMenuScrollToBottom={loadMoreNonstock}
                              onChange={(val) => {
                                const updatedBudgets = [
                                  ...formik.values.project_budgets,
                                ];
                                updatedBudgets[index].nonstock =
                                  val as OptionType;
                                updatedBudgets[index].nonstock_id =
                                  (val as OptionType)
                                    ? (val as OptionType).value
                                    : 0;
                                formik.setFieldValue(
                                  'project_budgets',
                                  updatedBudgets
                                );
                                formik.setFieldTouched(
                                  `project_budgets[${index}].nonstock_id`,
                                  true
                                );
                              }}
                              errorMessage={
                                (
                                  formik.errors.project_budgets?.[
                                    index
                                  ] as FormikErrors<ProjectFlockBudgetsSchemaType>
                                )?.nonstock_id as string
                              }
                              isError={
                                formik.touched.project_budgets?.[index]
                                  ?.nonstock_id &&
                                Boolean(
                                  (
                                    formik.errors.project_budgets?.[
                                      index
                                    ] as FormikErrors<ProjectFlockBudgetsSchemaType>
                                  )?.nonstock_id as string
                                )
                              }
                            />
                          </div>
                          <div className='flex flex-row justify-between items-center'>
                            <NumberInput
                              name={`project_budgets[${index}].qty`}
                              label='Jumlah Pembelian'
                              placeholder='Masukkan Jumlah Pembelian'
                              value={formik.values.project_budgets[index].qty}
                              onChange={(e) =>
                                handleBudgetChange(index, 'qty', e.target.value)
                              }
                              onBlur={formik.handleBlur}
                              allowNegative={false}
                              inputPrefix={
                                <>
                                  {nonstockUomName && (
                                    <div className='w-full h-full py-1 flex flex-row items-stretch justify-between gap-3'>
                                      <span className='text-sm text-base-content/60 self-center text-nowrap truncate'>
                                        {nonstockUomName}
                                      </span>

                                      <div className='w-px bg-base-content/10' />
                                    </div>
                                  )}
                                </>
                              }
                              errorMessage={
                                (
                                  formik.errors.project_budgets?.[
                                    index
                                  ] as FormikErrors<ProjectFlockBudgetsSchemaType>
                                )?.qty as string
                              }
                              isError={
                                formik.touched.project_budgets?.[index]?.qty &&
                                Boolean(
                                  (
                                    formik.errors.project_budgets?.[
                                      index
                                    ] as FormikErrors<ProjectFlockBudgetsSchemaType>
                                  )?.qty as string
                                )
                              }
                              className={{
                                inputPrefix:
                                  'py-0 px-0 pl-3 text-base-content/50 bg-transparent border-r-0',
                                inputWrapper: cn('border-l-0 pl-0', {
                                  'pl-5':
                                    isResponseSuccess(nonstocks) &&
                                    budget.nonstock_id,
                                }),
                              }}
                            />
                          </div>
                          <div className='flex flex-row justify-between items-center'>
                            <NumberInput
                              name={`project_budgets[${index}].price`}
                              label='Harga Satuan (Rp)'
                              value={formik.values.project_budgets[index].price}
                              onChange={(e) =>
                                handleBudgetChange(
                                  index,
                                  'price',
                                  e.target.value
                                )
                              }
                              onBlur={formik.handleBlur}
                              placeholder='Masukkan Harga Satuan (Rp)'
                              allowNegative={false}
                              inputPrefix={
                                <div className='w-full h-full py-1 flex flex-row items-stretch justify-between gap-3'>
                                  <span className='text-sm text-base-content/60 self-center text-nowrap truncate'>
                                    Rp
                                  </span>

                                  <div className='w-px bg-base-content/10' />
                                </div>
                              }
                              errorMessage={
                                (
                                  formik.errors.project_budgets?.[
                                    index
                                  ] as FormikErrors<ProjectFlockBudgetsSchemaType>
                                )?.price as string
                              }
                              isError={
                                formik.touched.project_budgets?.[index]
                                  ?.price &&
                                Boolean(
                                  (
                                    formik.errors.project_budgets?.[
                                      index
                                    ] as FormikErrors<ProjectFlockBudgetsSchemaType>
                                  )?.price as string
                                )
                              }
                              className={{
                                inputPrefix:
                                  'py-0 px-0 pl-3 text-base-content/50 bg-transparent border-r-0',
                                inputWrapper: 'border-l-0 pl-5',
                              }}
                            />
                          </div>
                          <div className='flex flex-row justify-between items-center'>
                            <NumberInput
                              name={`project_budgets[${index}].total_price`}
                              label='Total Harga'
                              value={
                                formik.values.project_budgets[index].total_price
                              }
                              onChange={(e) =>
                                handleBudgetChange(
                                  index,
                                  'total_price',
                                  e.target.value
                                )
                              }
                              onBlur={formik.handleBlur}
                              placeholder='Masukkan Total Harga'
                              allowNegative={false}
                              inputPrefix={
                                <div className='w-full h-full py-1 flex flex-row items-stretch justify-between gap-3'>
                                  <span className='text-sm text-base-content/60 self-center text-nowrap truncate'>
                                    Rp
                                  </span>

                                  <div className='w-px bg-base-content/10' />
                                </div>
                              }
                              errorMessage={
                                (
                                  formik.errors.project_budgets?.[
                                    index
                                  ] as FormikErrors<ProjectFlockBudgetsSchemaType>
                                )?.total_price as string
                              }
                              isError={
                                formik.touched.project_budgets?.[index]
                                  ?.total_price &&
                                Boolean(
                                  (
                                    formik.errors.project_budgets?.[
                                      index
                                    ] as FormikErrors<ProjectFlockBudgetsSchemaType>
                                  )?.total_price as string
                                )
                              }
                              className={{
                                inputPrefix:
                                  'py-0 px-0 pl-3 text-base-content/50 bg-transparent border-r-0',
                                inputWrapper: 'border-l-0 pl-5',
                              }}
                            />
                          </div>
                        </div>
                      );
                    })
                  ) : (
                    <div className='text-center py-4 text-gray-400'>
                      Tidak ada data estimasi anggaran.
                    </div>
                  )}

                  <div className='w-full p-4'>
                    <Button
                      type='button'
                      color='primary'
                      variant='outline'
                      onClick={onAddBudgetRowHandler}
                      disabled={filteredNonStockOptions.length == 0}
                      className='w-full p-3 rounded-lg text-sm font-semibold hover:text-base-100 focus-visible:text-base-100'
                    >
                      Tambah Produk
                    </Button>
                  </div>
                </div>
              </div>

              {(formErrorList.length > 0 || projectFlockFormErrorMessage) && (
                <div className='p-4'>
                  <AlertErrorList
                    formErrorList={formErrorList}
                    onClose={close}
                  />

                  {projectFlockFormErrorMessage && (
                    <div className='my-4'>
                      <div role='alert' className='alert alert-error'>
                        <Icon
                          icon='material-symbols:error-outline'
                          width={24}
                          height={24}
                        />
                        <span>{projectFlockFormErrorMessage}</span>
                        <Button
                          type='button'
                          onClick={() => {
                            setProjectFlockFormErrorMessage('');
                          }}
                          variant='link'
                        >
                          <Icon
                            icon='material-symbols:close'
                            width={24}
                            height={24}
                          />
                        </Button>
                      </div>
                    </div>
                  )}
                </div>
              )}
            </div>
          )}

          {formStep === 'confirmation' && (
            <div className='p-4'>
              <ProjectFlockFormConfirmationTable
                projectFlockForm={formik.values}
                kandangs={optionsKandang}
              />
            </div>
          )}
        </div>

        <div className='p-4 flex-1 flex flex-row justify-center gap-2 flex-wrap shadow-bg'>
          {formType !== 'detail' && (
            <RequirePermission
              permissions={
                formType == 'add'
                  ? 'lti.production.project_flocks.create'
                  : 'lti.production.project_flocks.update'
              }
            >
              <Button
                type='submit'
                isLoading={formik.isSubmitting}
                disabled={formik.isSubmitting}
                className='w-full p-3 rounded-lg text-sm font-semibold text-base-100'
              >
                Submit
              </Button>
            </RequirePermission>
          )}
        </div>
      </form>

      <ConfirmationModal
        ref={deleteModal.ref}
        type='error'
        text={`Apakah anda yakin ingin menghapus data Project Flock ini (${initialValues?.flock_name} - ${initialValues?.area?.name})?`}
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: 'error',
          isLoading: isDeleteLoading,
          onClick: confirmationModalDeleteClickHandler,
        }}
        className={{
          modal: 'w-full sm:w-[446px]',
        }}
      />
    </>
  );
};

ProjectFlockForm.displayName = 'ProjectFlockForm';

export default ProjectFlockForm;
