'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useFormik } from 'formik';
import { toast } from 'react-hot-toast';

import { Icon } from '@iconify/react';
import Button from '@/components/Button';
import TextInput from '@/components/input/TextInput';
import { useModal } from '@/components/Modal';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import RequirePermission from '@/components/helper/RequirePermission';

import {
  FcrFormSchema,
  FcrFormValues,
  UpdateFcrFormSchema,
} from '@/components/pages/master-data/fcr/form/FcrForm.schema';
import { isResponseError } from '@/lib/api-helper';
import {
  CreateFcrPayload,
  Fcr,
  FcrWithStandards,
  UpdateFcrPayload,
} from '@/types/api/master-data/fcr';
import { FcrApi } from '@/services/api/master-data';
import { cn } from '@/lib/helper';
import AlertErrorList from '@/components/helper/form/FormErrors';
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';

interface FcrFormProps {
  type?: 'add' | 'edit' | 'detail';
  initialValues?: FcrWithStandards;
}

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

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

  const createFcrHandler = useCallback(
    async (payload: CreateFcrPayload) => {
      const createFcrRes = await FcrApi.create(payload);

      if (isResponseError(createFcrRes)) {
        setFcrFormErrorMessage(createFcrRes.message);
        return;
      }

      toast.success(createFcrRes?.message as string);
      router.push('/master-data/fcr');
    },
    [router]
  );

  const updateFcrHandler = useCallback(
    async (fcrId: number, payload: UpdateFcrPayload) => {
      const updateFcrRes = await FcrApi.update(fcrId, payload);

      if (updateFcrRes?.status === 'error') {
        setFcrFormErrorMessage(updateFcrRes.message);
        return;
      }

      toast.success(updateFcrRes?.message as string);
      router.refresh();
      router.push('/master-data/fcr');
    },
    [router]
  );

  const formikInitialValues = useMemo<FcrFormValues>(() => {
    return {
      name: initialValues?.name ?? '',
      fcrStandards: initialValues?.fcr_standards
        ? initialValues?.fcr_standards
        : [
            {
              weight: '',
              fcr_number: '',
              mortality: '',
            },
          ],
    };
  }, [initialValues]);

  const formik = useFormik<FcrFormValues>({
    initialValues: formikInitialValues,
    validationSchema: type === 'edit' ? UpdateFcrFormSchema : FcrFormSchema,
    onSubmit: async (values) => {
      setFcrFormErrorMessage('');

      const fcrPayload: CreateFcrPayload = {
        name: values.name,
        fcr_standards: values.fcrStandards as CreateFcrPayload['fcr_standards'],
      };

      switch (type) {
        case 'add':
          await createFcrHandler(fcrPayload);
          break;

        case 'edit':
          await updateFcrHandler(initialValues?.id as number, fcrPayload);
          break;
      }
    },
  });

  const { setValues: formikSetValues } = formik;

  const addFcrStandard = () =>
    formik.setFieldValue('fcrStandards', [
      ...formik.values.fcrStandards,
      {
        weight: '',
        fcr_number: '',
        mortality: '',
      },
    ]);

  const removeFcrStandard = (i: number) =>
    formik.setFieldValue(
      'fcrStandards',
      formik.values.fcrStandards.filter((_, idx) => idx !== i)
    );

  const deleteFcrClickHandler = () => {
    deleteModal.openModal();
  };

  const confirmationModalDeleteClickHandler = async () => {
    setIsDeleteLoading(true);

    await FcrApi.delete(initialValues?.id as number);

    deleteModal.closeModal();
    toast.success('Successfully delete FCR!');
    setIsDeleteLoading(false);
    router.push('/master-data/fcr');
  };

  const isRepeaterInputError = (
    column: keyof CreateFcrPayload['fcr_standards'][0],
    idx: number
  ) => {
    return (
      formik.touched.fcrStandards?.[idx]?.[column] &&
      Boolean(
        formik.errors.fcrStandards?.[idx] instanceof Object &&
          formik.errors.fcrStandards?.[idx]?.[column]
      )
    );
  };

  useEffect(() => {
    formikSetValues(formikInitialValues);
  }, [formikSetValues, formikInitialValues]);

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

  return (
    <>
      <section className='w-full max-w-5xl'>
        <header className='flex flex-col gap-4'>
          <Button
            href='/master-data/fcr'
            variant='link'
            className='w-fit p-0 text-primary'
          >
            <Icon icon='uil:arrow-left' width={24} height={24} />
            Kembali
          </Button>

          <h1 className='text-2xl font-bold text-center'>
            {type === 'add' && 'Tambah FCR'}
            {type === 'edit' && 'Edit FCR'}
            {type === 'detail' && 'Detail FCR'}
          </h1>
        </header>

        <form
          onSubmit={handleFormSubmit}
          onReset={formik.handleReset}
          className='w-full mt-8 flex flex-col gap-6'
        >
          <div className='flex flex-col gap-4'>
            <TextInput
              required
              label='Nama'
              name='name'
              placeholder='Masukkan nama FCR'
              value={formik.values.name}
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
              isError={formik.touched.name && Boolean(formik.errors.name)}
              errorMessage={formik.errors.name}
              readOnly={type === 'detail'}
            />

            <div>
              <div className='overflow-x-auto'>
                <table className='table'>
                  <thead>
                    <tr>
                      <th>Bobot</th>
                      <th>FCR</th>
                      <th>Mortalitas</th>
                      {type !== 'detail' && <th>Aksi</th>}
                    </tr>
                  </thead>

                  <tbody>
                    {formik.values.fcrStandards.map((fcrStandard, idx) => (
                      <tr key={idx}>
                        <td>
                          <TextInput
                            required
                            type='number'
                            name={`fcrStandards[${idx}].weight`}
                            placeholder='Masukkan bobot'
                            value={fcrStandard.weight}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                            isError={isRepeaterInputError('weight', idx)}
                            readOnly={type === 'detail'}
                            className={{
                              wrapper: 'w-full min-w-24',
                            }}
                          />
                        </td>
                        <td>
                          <TextInput
                            required
                            type='number'
                            name={`fcrStandards[${idx}].fcr_number`}
                            placeholder='Masukkan FCR'
                            value={fcrStandard.fcr_number}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                            isError={isRepeaterInputError('fcr_number', idx)}
                            readOnly={type === 'detail'}
                            className={{
                              wrapper: 'w-full min-w-24',
                            }}
                          />
                        </td>
                        <td>
                          <TextInput
                            required
                            type='number'
                            name={`fcrStandards[${idx}].mortality`}
                            placeholder='Masukkan mortalitas'
                            value={fcrStandard.mortality}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                            isError={isRepeaterInputError('mortality', idx)}
                            readOnly={type === 'detail'}
                            className={{
                              wrapper: 'w-full min-w-24',
                            }}
                          />
                        </td>
                        {type !== 'detail' && (
                          <td>
                            <Button
                              type='button'
                              color='error'
                              onClick={() => removeFcrStandard(idx)}
                            >
                              <Icon
                                icon='material-symbols:delete-outline-rounded'
                                width={24}
                                height={24}
                              />
                            </Button>
                          </td>
                        )}
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>

            {type !== 'detail' && (
              <Button
                type='button'
                color='success'
                onClick={addFcrStandard}
                className='w-fit mx-auto'
              >
                <Icon icon='ic:round-plus' width={24} height={24} /> Tambah FCR
              </Button>
            )}
          </div>

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

          <div className='flex flex-row justify-between gap-2 flex-wrap'>
            {type !== 'add' && (
              <div className='flex flex-row justify-start gap-2'>
                <RequirePermission permissions='lti.master.fcr.delete'>
                  <Button
                    type='button'
                    color='error'
                    onClick={deleteFcrClickHandler}
                    className='px-4'
                  >
                    <Icon
                      icon='material-symbols:delete-outline-rounded'
                      width={24}
                      height={24}
                      className='justify-start text-sm'
                    />
                    Delete
                  </Button>
                </RequirePermission>

                {type !== 'edit' && (
                  <RequirePermission permissions='lti.master.fcr.update'>
                    <Button
                      type='button'
                      color='warning'
                      href={`/master-data/fcr/detail/edit/?fcrId=${initialValues?.id}`}
                      className='px-4'
                    >
                      <Icon
                        icon='material-symbols:edit-outline'
                        width={24}
                        height={24}
                        className='justify-start text-sm'
                      />
                      Edit
                    </Button>
                  </RequirePermission>
                )}
              </div>
            )}

            {type !== 'detail' && (
              <div
                className={cn('flex flex-row justify-end gap-2', {
                  'w-full': type === 'add',
                })}
              >
                <Button type='reset' color='warning' className='px-4'>
                  Reset
                </Button>

                <Button
                  type='submit'
                  color='primary'
                  isLoading={formik.isSubmitting}
                  disabled={formik.isSubmitting}
                  className='px-4'
                >
                  Submit
                </Button>
              </div>
            )}
          </div>

          {fcrFormErrorMessage && (
            <div role='alert' className='alert alert-error'>
              <Icon
                icon='material-symbols:error-outline'
                width={24}
                height={24}
              />
              <span>{fcrFormErrorMessage}</span>
            </div>
          )}
        </form>
      </section>

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

export default FcrForm;
