'use client';

import { RefObject } from 'react';
import { useFormik } from 'formik';
import * as yup from 'yup';

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

import { AreaApi, LocationApi } from '@/services/api/master-data';
import { ProjectFlockApi } from '@/services/api/production';
import { Area } from '@/types/api/master-data/area';
import { Location } from '@/types/api/master-data/location';
import { ProjectFlock } from '@/types/api/production/project-flock';

export type ReportDepreciationFilterValues = {
  area?: OptionType<string>;
  location?: OptionType<string>;
  projectFlock?: OptionType<string>;
  period: string | null;
  totalDays: number;
};

export const ReportDepreciationFilterSchema = yup.object({
  area: yup.mixed<OptionType<string>>().optional(),
  location: yup.mixed<OptionType<string>>().optional(),
  projectFlock: yup
    .mixed<OptionType<string>>()
    .required('Project Flock wajib dipilih'),
  period: yup.string().nullable().required('Periode wajib dipilih'),
  totalDays: yup
    .number()
    .min(1, 'Minimal 1 hari')
    .required('Total Hari wajib diisi'),
});

interface ReportDepreciationFilterModalProps {
  ref: RefObject<HTMLDialogElement | null>;
  initialValues?: Partial<ReportDepreciationFilterValues>;
  onSubmit?: (values: Partial<ReportDepreciationFilterValues>) => void;
  onReset?: () => void;
}

const defaultInitialValues: (
  initialValues?: Partial<ReportDepreciationFilterValues>
) => ReportDepreciationFilterValues = (initialValues) => ({
  area: undefined,
  location: undefined,
  projectFlock: undefined,
  period: initialValues?.period ?? null,
  totalDays: initialValues?.totalDays ?? 10,
});

const ReportDepreciationFilterModal = ({
  ref,
  initialValues,
  onSubmit,
  onReset,
}: ReportDepreciationFilterModalProps) => {
  const closeModalHandler = () => {
    ref.current?.close();
  };

  const formik = useFormik<ReportDepreciationFilterValues>({
    initialValues: { ...defaultInitialValues(initialValues), ...initialValues },
    validationSchema: ReportDepreciationFilterSchema,
    onSubmit: async (values) => {
      onSubmit?.(values);
      closeModalHandler();
    },
  });

  const {
    setInputValue: setAreaInputValue,
    options: areaOptions,
    isLoadingOptions: isLoadingAreaOptions,
    loadMore: loadMoreAreas,
  } = useSelect<Area>(AreaApi.basePath, 'id', 'name', 'search');

  const {
    setInputValue: setLocationInputValue,
    options: locationOptions,
    isLoadingOptions: isLoadingLocationOptions,
    loadMore: loadMoreLocations,
  } = useSelect<Location>(LocationApi.basePath, 'id', 'name', 'search', {
    area_id: String(formik.values.area?.value ?? ''),
  });

  const {
    setInputValue: setProjectFlockInputValue,
    options: projectFlockOptions,
    isLoadingOptions: isLoadingProjectFlockOptions,
    loadMore: loadMoreProjectFlocks,
  } = useSelect<ProjectFlock>(
    ProjectFlockApi.basePath,
    'id',
    'flock_name',
    'search',
    {
      location_id: String(formik.values.location?.value ?? ''),
    }
  );

  const formikResetHandler = () => {
    onReset?.();
    formik.resetForm({ values: defaultInitialValues(initialValues) });
    closeModalHandler();
  };

  const areaChangeHandler = (val: OptionType | OptionType[] | null) => {
    const area =
      val && !Array.isArray(val) ? (val as OptionType<string>) : undefined;
    formik.setFieldValue('area', area);
    formik.setFieldValue('location', undefined);
    formik.setFieldValue('projectFlock', undefined);
  };

  const locationChangeHandler = (val: OptionType | OptionType[] | null) => {
    const location =
      val && !Array.isArray(val) ? (val as OptionType<string>) : undefined;
    formik.setFieldValue('location', location);
    formik.setFieldValue('projectFlock', undefined);
  };

  const projectFlockChangeHandler = (val: OptionType | OptionType[] | null) => {
    const projectFlock =
      val && !Array.isArray(val) ? (val as OptionType<string>) : undefined;
    formik.setFieldValue('projectFlock', projectFlock);
  };

  return (
    <Modal
      ref={ref}
      className={{
        modalBox: 'p-0 rounded-xl xl:max-w-4/12 max-w-sm',
      }}
    >
      <form
        onSubmit={formik.handleSubmit}
        onReset={formikResetHandler}
        className='w-full flex flex-col'
      >
        <div className='p-4 flex items-center justify-between gap-2 border-b border-base-content/10'>
          <div className='flex items-center gap-2 text-primary'>
            <Icon icon='heroicons:funnel' width={20} height={20} />
            <h3 className='text-sm font-medium'>Filter Data</h3>
          </div>

          <Button
            type='button'
            variant='ghost'
            color='none'
            onClick={closeModalHandler}
            className='p-0 text-base-content/50 hover:text-base-content'
          >
            <Icon icon='heroicons:x-mark' width={20} height={20} />
          </Button>
        </div>

        <div className='p-4 flex flex-col gap-1.5'>
          <SelectInput
            label='Area'
            placeholder='Pilih Area'
            options={areaOptions}
            value={formik.values.area ?? null}
            onChange={areaChangeHandler}
            onInputChange={setAreaInputValue}
            onMenuScrollToBottom={loadMoreAreas}
            isLoading={isLoadingAreaOptions}
            isClearable
            isSearchable={true}
            className={{ wrapper: 'w-full' }}
          />

          <SelectInput
            label='Lokasi'
            placeholder='Pilih Lokasi'
            options={locationOptions}
            value={formik.values.location ?? null}
            onChange={locationChangeHandler}
            onInputChange={setLocationInputValue}
            onMenuScrollToBottom={loadMoreLocations}
            isLoading={isLoadingLocationOptions}
            isClearable
            isSearchable={true}
            className={{ wrapper: 'w-full' }}
          />

          <SelectInput
            label='Project Flock'
            placeholder='Pilih Project Flock'
            options={projectFlockOptions}
            value={formik.values.projectFlock ?? null}
            onChange={projectFlockChangeHandler}
            onInputChange={setProjectFlockInputValue}
            onMenuScrollToBottom={loadMoreProjectFlocks}
            isLoading={isLoadingProjectFlockOptions}
            isClearable
            isSearchable={true}
            className={{ wrapper: 'w-full' }}
            isError={
              formik.touched.projectFlock && !!formik.errors.projectFlock
            }
            errorMessage={
              formik.touched.projectFlock
                ? (formik.errors.projectFlock as string)
                : undefined
            }
          />

          <DateInput
            label='Periode'
            name='period'
            placeholder='Pilih Periode'
            value={formik.values.period || ''}
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
            isError={formik.touched.period && !!formik.errors.period}
            errorMessage={formik.errors.period}
            required
            isNestedModal
          />

          <NumberInput
            label='Total Hari'
            name='totalDays'
            placeholder='Masukkan total hari'
            value={formik.values.totalDays}
            onChange={(e) => {
              const val = Number(e.target.value);
              formik.setFieldValue(
                'totalDays',
                isNaN(val) || val < 1 ? 1 : Math.floor(val)
              );
            }}
            onBlur={formik.handleBlur}
            decimalScale={0}
            allowNegative={false}
            thousandSeparator=''
            isError={formik.touched.totalDays && !!formik.errors.totalDays}
            errorMessage={
              formik.touched.totalDays
                ? (formik.errors.totalDays as string)
                : undefined
            }
            className={{ wrapper: 'w-full' }}
          />
        </div>

        <div className='p-4 flex justify-between gap-4 border-t border-base-content/10 bg-gray-50'>
          <Button
            type='reset'
            variant='soft'
            className='rounded-lg text-base-content/65 bg-transparent border-none hover:bg-base-content/10 hover:text-base-content/65 transition-colors px-3 py-2'
          >
            Reset Filter
          </Button>

          <Button
            type='submit'
            className='min-w-40 text-sm rounded-lg py-3 text-white font-semibold'
            disabled={!formik.isValid || formik.isSubmitting}
          >
            Apply Filter
          </Button>
        </div>
      </form>
    </Modal>
  );
};

export default ReportDepreciationFilterModal;
