'use client';

import { FormikContextType } from 'formik';

import { Icon } from '@iconify/react';
import Card from '@/components/Card';
import SelectInput, {
  OptionType,
  useSelect,
} from '@/components/input/SelectInput';
import NumberInput from '@/components/input/NumberInput';
import TextInput from '@/components/input/TextInput';
import Button from '@/components/Button';

import { ExpenseRequestFormValues } from '@/components/pages/expense/form/ExpenseRequestForm.schema';
import { cn } from '@/lib/helper';
import { NonstockApi } from '@/services/api/master-data';
import { Nonstock } from '@/types/api/master-data/nonstock';
import { removeArrayItemAndSync } from '@/lib/utils/formik';

interface ExpenseRequestKandangDetailExpenseProps {
  type?: 'add' | 'edit' | 'detail';
  formik: FormikContextType<ExpenseRequestFormValues>;
  supplierId?: number;
  location?: {
    value: number;
    label: string;
  } | null;
  className?: {
    wrapper?: string;
  };
}

const ExpenseRequestKandangDetailExpense: React.FC<
  ExpenseRequestKandangDetailExpenseProps
> = ({ type, formik, supplierId, location, className }) => {
  const {
    setInputValue: setNonstockInputValue,
    options: nonstockOptions,
    isLoadingOptions: isLoadingNonstockOptions,
  } = useSelect<Nonstock>(
    NonstockApi.basePath,
    'id',
    'name',
    'search',
    supplierId ? { supplier_id: String(supplierId) } : undefined
  );

  const nonstockChangeHandler = (
    kandangExpenseIdx: number,
    expenseIdx: number,
    val: OptionType | OptionType[] | null
  ) => {
    formik.setFieldTouched(
      `expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock`,
      true
    );
    formik.setFieldTouched(
      `expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock_id`,
      true
    );
    formik.setFieldValue(
      `expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock`,
      val
    );

    const nonstockId = Array.isArray(val) ? val[0]?.value : val?.value;
    formik.setFieldValue(
      `expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock_id`,
      nonstockId ?? 0
    );
  };

  const addExpenseItemHandler = (kandangExpenseIdx: number) => {
    const newExpensesValue = [
      ...formik.values.expense_nonstocks[kandangExpenseIdx].cost_items,
      {
        nonstock: null,
        nonstock_id: 0,
        price: undefined,
        quantity: undefined,
        notes: '',
      },
    ];

    formik.setFieldValue(
      `expense_nonstocks[${kandangExpenseIdx}].cost_items`,
      newExpensesValue
    );
  };

  const deleteExpenseItemHandler = (
    kandangExpenseIdx: number,
    expenseIdx: number
  ) => {
    const path = `expense_nonstocks[${kandangExpenseIdx}].cost_items`;

    // trims values, errors, and touched at expenseIdx
    removeArrayItemAndSync(formik, path, expenseIdx);
  };

  const isExpenseRepeaterInputError = (
    column: 'nonstock_id' | 'quantity' | 'price' | 'notes',
    kandangExpenseIdx: number,
    expenseIdx: number
  ) => {
    return (
      formik.touched.expense_nonstocks?.[kandangExpenseIdx]?.cost_items?.[
        expenseIdx
      ]?.[column] &&
      Boolean(
        formik.errors.expense_nonstocks?.[kandangExpenseIdx] &&
          typeof formik.errors.expense_nonstocks?.[kandangExpenseIdx] ===
            'object' &&
          formik.errors.expense_nonstocks?.[kandangExpenseIdx].cost_items?.[
            expenseIdx
          ] &&
          typeof formik.errors.expense_nonstocks?.[kandangExpenseIdx]
            .cost_items?.[expenseIdx] === 'object' &&
          formik.errors.expense_nonstocks?.[kandangExpenseIdx].cost_items?.[
            expenseIdx
          ]?.[column]
      )
    );
  };

  const getExpenseRepeaterErrorMessage = (
    column: 'nonstock_id' | 'quantity' | 'price' | 'notes',
    kandangExpenseIdx: number,
    expenseIdx: number
  ): string => {
    const kandangError = formik.errors.expense_nonstocks?.[kandangExpenseIdx];

    if (!kandangError || typeof kandangError !== 'object') return '';

    if (!('cost_items' in kandangError)) return '';

    const costItemsError = kandangError.cost_items?.[expenseIdx];

    if (!costItemsError || typeof costItemsError !== 'object') return '';

    const fieldError = costItemsError[column as keyof typeof costItemsError];

    if (!fieldError) return '';

    if (typeof fieldError === 'object' && fieldError !== null) {
      return 'Nonstock wajib diisi!';
    }

    return String(fieldError);
  };

  return (
    <Card
      className={{
        wrapper: cn('w-full', className?.wrapper),
        body: 'p-4 shadow',
      }}
    >
      <div className='mb-4 text-center'>
        <h4 className='font-bold text-xl'>
          Rincian Pengajuan Biaya Operasional
        </h4>
      </div>

      <div className='w-full flex flex-col gap-6'>
        {!formik.values.supplier?.value && (
          <div>
            <p className='text-sm text-gray-400 text-center'>
              Pilih supplier terlebih dahulu!
            </p>
          </div>
        )}

        {formik.values.expense_nonstocks.length === 0 &&
          formik.values.supplier?.value && (
            <div>
              <p className='text-sm text-gray-400 text-center'>
                Belum ada item biaya. Silakan pilih lokasi terlebih dahulu.
              </p>
            </div>
          )}

        {formik.values.expense_nonstocks.length > 0 &&
          formik.values.supplier?.value &&
          formik.values.expense_nonstocks.map(
            (kandangExpense, kandangExpenseIdx) => {
              const kandangName = kandangExpense.kandang_id
                ? formik.values.kandangs?.find(
                    (kandang) => kandang.id === kandangExpense.kandang_id
                  )
                : null;

              return (
                (kandangName?.name || !kandangExpense.kandang_id) && (
                  <div
                    key={`kandangExpense-${kandangExpenseIdx}`}
                    className='w-full flex flex-col gap-4'
                  >
                    <div>
                      <h5 className='mb-2 text-lg font-bold text-center'>
                        Biaya {kandangName?.name || location?.label || 'Umum'}
                      </h5>

                      <div className='overflow-x-auto'>
                        <table className='table'>
                          <thead>
                            <tr>
                              <th className='after:content-["*"] after:text-red-500 after:ml-0.5'>
                                Nonstock
                              </th>
                              <th className='after:content-["*"] after:text-red-500 after:ml-0.5'>
                                Total Kuantitas
                              </th>
                              <th className='after:content-["*"] after:text-red-500 after:ml-0.5'>
                                Harga Satuan
                              </th>
                              <th>Catatan</th>
                              {type !== 'detail' && <th>Aksi</th>}
                            </tr>
                          </thead>

                          <tbody>
                            {kandangExpense.cost_items.map(
                              (expenseItem, expenseIdx) => (
                                <tr key={`expense-${expenseIdx}`}>
                                  <td className='p-2'>
                                    <SelectInput
                                      placeholder='Pilih Nonstock'
                                      value={expenseItem.nonstock}
                                      onChange={(val) => {
                                        nonstockChangeHandler(
                                          kandangExpenseIdx,
                                          expenseIdx,
                                          val
                                        );
                                      }}
                                      isError={isExpenseRepeaterInputError(
                                        'nonstock_id',
                                        kandangExpenseIdx,
                                        expenseIdx
                                      )}
                                      errorMessage={getExpenseRepeaterErrorMessage(
                                        'nonstock_id',
                                        kandangExpenseIdx,
                                        expenseIdx
                                      )}
                                      options={nonstockOptions}
                                      isLoading={isLoadingNonstockOptions}
                                      onInputChange={setNonstockInputValue}
                                      className={{ wrapper: 'min-w-48' }}
                                      isClearable={true}
                                    />
                                  </td>

                                  <td className='p-2'>
                                    <NumberInput
                                      required
                                      name={`expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].quantity`}
                                      placeholder='Masukkan Total Kuantitas'
                                      value={
                                        formik.values.expense_nonstocks[
                                          kandangExpenseIdx
                                        ].cost_items[expenseIdx].quantity ?? ''
                                      }
                                      onChange={formik.handleChange}
                                      onBlur={formik.handleBlur}
                                      isError={isExpenseRepeaterInputError(
                                        'quantity',
                                        kandangExpenseIdx,
                                        expenseIdx
                                      )}
                                      errorMessage={getExpenseRepeaterErrorMessage(
                                        'quantity',
                                        kandangExpenseIdx,
                                        expenseIdx
                                      )}
                                      className={{ wrapper: 'min-w-24' }}
                                    />
                                  </td>

                                  <td className='p-2'>
                                    <NumberInput
                                      name={`expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].price`}
                                      placeholder='Masukkan Harga Satuan'
                                      value={
                                        formik.values.expense_nonstocks[
                                          kandangExpenseIdx
                                        ].cost_items[expenseIdx].price ?? ''
                                      }
                                      onChange={formik.handleChange}
                                      onBlur={formik.handleBlur}
                                      isError={isExpenseRepeaterInputError(
                                        'price',
                                        kandangExpenseIdx,
                                        expenseIdx
                                      )}
                                      errorMessage={getExpenseRepeaterErrorMessage(
                                        'price',
                                        kandangExpenseIdx,
                                        expenseIdx
                                      )}
                                      inputPrefix={
                                        <span className='text-gray-600 font-medium'>
                                          Rp
                                        </span>
                                      }
                                      className={{ wrapper: 'min-w-24' }}
                                    />
                                  </td>

                                  <td className='p-2'>
                                    <TextInput
                                      name={`expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].notes`}
                                      placeholder='Tuliskan catatan'
                                      value={
                                        formik.values.expense_nonstocks[
                                          kandangExpenseIdx
                                        ].cost_items[expenseIdx].notes ?? ''
                                      }
                                      onChange={formik.handleChange}
                                      onBlur={formik.handleBlur}
                                      isError={isExpenseRepeaterInputError(
                                        'notes',
                                        kandangExpenseIdx,
                                        expenseIdx
                                      )}
                                      errorMessage={getExpenseRepeaterErrorMessage(
                                        'notes',
                                        kandangExpenseIdx,
                                        expenseIdx
                                      )}
                                      className={{ wrapper: 'min-w-24' }}
                                    />
                                  </td>

                                  {type !== 'detail' && (
                                    <td>
                                      <Button
                                        type='button'
                                        color='error'
                                        onClick={() =>
                                          deleteExpenseItemHandler(
                                            kandangExpenseIdx,
                                            expenseIdx
                                          )
                                        }
                                      >
                                        <Icon
                                          icon='material-symbols:delete-outline-rounded'
                                          width={24}
                                          height={24}
                                        />
                                      </Button>
                                    </td>
                                  )}
                                </tr>
                              )
                            )}
                          </tbody>
                        </table>
                      </div>
                    </div>

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

export default ExpenseRequestKandangDetailExpense;
