'use client';

import { RefObject, useCallback, useMemo, useState } from 'react';
import { useFormik } from 'formik';
import { Icon } from '@iconify/react';
import Modal from '@/components/Modal';
import Button from '@/components/Button';
import SelectInput, {
  OptionType,
  useSelect,
} from '@/components/input/SelectInput';
import DateInput from '@/components/input/DateInput';
import SelectInputRadio from '@/components/input/SelectInputRadio';
import { MARKETING_APPROVAL_LINE } from '@/config/approval-line';
import {
  MarketingFilterFormValues,
  MarketingFilterSchema,
} from '@/components/pages/marketing/filter/MarketingFilter';
import { MarketingFilter } from '@/types/api/marketing/marketing';
import SelectInputCheckbox from '@/components/input/SelectInputCheckbox';
import { MarketingApi } from '@/services/api/marketing/marketing';
import {
  CustomerApi,
  ProductApi,
  WarehouseApi,
} from '@/services/api/master-data';
import { isResponseSuccess } from '@/lib/api-helper';
import { BaseMarketing, BaseSalesOrder } from '@/types/api/marketing/marketing';
import { ProjectFlockApi } from '@/services/api/production';
import { ProjectFlock } from '@/types/api/production/project-flock';
import { Product } from '@/types/api/master-data/product';
import { Warehouse } from '@/types/api/master-data/warehouse';

interface MarketingFilterModal {
  ref: RefObject<HTMLDialogElement | null>;
  onSubmit?: (values: MarketingFilter) => void;
  onReset?: () => void;
  initialValues?: {
    product_ids: OptionType<number>[];
    status: OptionType<string> | null;
    customer: OptionType<number> | null;
    project_flock: OptionType<number> | null;
    project_flock_kandang: OptionType<number> | null;
    warehouse: OptionType<number> | null;
    start_date: string;
    end_date: string;
    filter_by: OptionType<string> | null;
  };
}

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

  // ===== OPTIONS =====
  const {
    options: productsOptions,
    isLoadingOptions: isLoadingProductsOptions,
    setInputValue: setProductsInputValue,
    loadMore: loadMoreProducts,
  } = useSelect<Product>(ProductApi.basePath, 'id', 'name', 'search', {
    include_all: 'true',
  });

  const {
    options: customersOptions,
    isLoadingOptions: isLoadingCustomersOptions,
    setInputValue: setCustomersInputValue,
    loadMore: loadMoreCustomers,
  } = useSelect(CustomerApi.basePath, 'id', 'name', 'search', {
    has_marketing: 'true',
  });

  const {
    options: projectFlockOptions,
    rawData: projectFlocksRawData,
    isLoadingOptions: isLoadingProjectFlockOptions,
    setInputValue: setProjectFlockInputValue,
    loadMore: loadMoreProjectFlocks,
  } = useSelect<ProjectFlock>(
    ProjectFlockApi.basePath,
    'id',
    'flock_name',
    'search'
  );

  const {
    options: warehouseOptions,
    isLoadingOptions: isLoadingWarehouseOptions,
    setInputValue: setWarehouseInputValue,
    loadMore: loadMoreWarehouses,
  } = useSelect<Warehouse>(WarehouseApi.basePath, 'id', 'name', 'search');

  const statusOptions = [
    ...MARKETING_APPROVAL_LINE.map((item) => ({
      value: item.step_name.split(' ').join('_').toUpperCase(),
      label: item.step_name,
    })),
    { value: 'DITOLAK', label: 'Ditolak' },
  ];

  const filterByOptions = [
    { value: 'so_date', label: 'Tanggal SO' },
    { value: 'created_at', label: 'Tanggal Dibuat' },
  ];

  const [hasDateError, setHasDateError] = useState(false);

  const formik = useFormik<MarketingFilterFormValues>({
    initialValues: initialValues || {
      product_ids: [],
      status: null,
      customer: null,
      project_flock: null,
      project_flock_kandang: null,
      warehouse: null,
      start_date: '',
      end_date: '',
      filter_by: null,
    },
    validationSchema: MarketingFilterSchema,

    onSubmit: async (values) => {
      const formattedValues: MarketingFilter = {
        product_ids: values.product_ids.map((item) => Number(item.value)),
        product_names: values.product_ids.map((item) => item.label),
        status: values.status?.value.toString() || '',
        status_name: values.status?.label || '-',
        customer_id: Number(values.customer?.value),
        customer_name: values.customer?.label || '-',
        project_flock_id: values.project_flock?.value || undefined,
        project_flock_name: values.project_flock?.label,
        project_flock_kandang_id:
          Number(values.project_flock_kandang?.value) || undefined,
        project_flock_kandang_name:
          values.project_flock_kandang?.label || undefined,
        warehouse_id: Number(values.warehouse?.value) || undefined,
        warehouse_name: values.warehouse?.label || undefined,
        start_date: values.start_date || undefined,
        end_date: values.end_date || undefined,
        filter_by: values.filter_by?.value || undefined,
        filter_by_name: values.filter_by?.label || undefined,
      };

      onSubmit?.(formattedValues);
      closeModalHandler();
    },

    onReset: () => {
      onReset?.();
      closeModalHandler();
    },
  });

  const { resetForm } = formik;

  const formikResetHandler = useCallback(() => {
    resetForm({
      values: {
        product_ids: [],
        status: null,
        customer: null,
        project_flock: null,
        project_flock_kandang: null,
        warehouse: null,
        start_date: '',
        end_date: '',
        filter_by: null,
      },
    });
    setHasDateError(false);
    onReset?.();
    closeModalHandler();
  }, [resetForm, onReset, closeModalHandler]);

  const handleStartDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    formik.setFieldValue('start_date', value);
    if (value && formik.values.end_date) {
      setHasDateError(new Date(formik.values.end_date) < new Date(value));
    } else {
      setHasDateError(false);
    }
  };

  const handleEndDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    formik.setFieldValue('end_date', value);
    if (value && formik.values.start_date) {
      setHasDateError(new Date(value) < new Date(formik.values.start_date));
    } else {
      setHasDateError(false);
    }
  };

  const productChangeHandler = (val: OptionType | OptionType[] | null) => {
    formik.setFieldValue('product_ids', val as OptionType[]);
  };

  const customerChangeHandler = (val: OptionType | OptionType[] | null) => {
    formik.setFieldValue(
      'customer',
      !Array.isArray(val) ? (val as OptionType<number> | null) : null
    );
  };

  const statusChangeHandler = (val: OptionType | OptionType[] | null) => {
    formik.setFieldValue('status', val as OptionType);
  };

  const projectFlockKandangOptions = useMemo(() => {
    if (
      !formik.values.project_flock ||
      !projectFlocksRawData ||
      !isResponseSuccess(projectFlocksRawData)
    ) {
      return [];
    }

    const selectedProjectFlock = projectFlocksRawData.data.find(
      (item) => item.id === formik.values.project_flock?.value
    );

    return (
      selectedProjectFlock?.kandangs?.map((item) => ({
        value: item.project_flock_kandang_id,
        label: item.name,
      })) || []
    );
  }, [formik.values.project_flock, projectFlocksRawData]);

  return (
    <Modal
      ref={ref}
      className={{
        modalBox: 'p-0 rounded-xl',
      }}
    >
      <form
        onSubmit={formik.handleSubmit}
        onReset={formikResetHandler}
        className='w-full flex flex-col'
      >
        {/* Modal Header */}
        <div className='p-4 flex items-center justify-between gap-2 border-b border-gray-300'>
          <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>

        {/* Modal Body */}
        <div className='p-4 flex flex-col gap-1.5'>
          <div>
            <label className='block text-xs font-semibold text-base-content py-2'>
              Tanggal
            </label>
            <div className='flex flex-row gap-1.5 items-center justify-between'>
              <DateInput
                name='start_date'
                value={formik.values.start_date || ''}
                onChange={handleStartDateChange}
                className={{ wrapper: 'w-full' }}
                isNestedModal
              />
              <hr className='w-full max-w-3 h-px border-base-content/10' />
              <DateInput
                name='end_date'
                value={formik.values.end_date || ''}
                onChange={handleEndDateChange}
                className={{ wrapper: 'w-full' }}
                isNestedModal
                isError={hasDateError}
              />
            </div>
          </div>

          <SelectInputRadio
            label='Filter Berdasarkan'
            placeholder='Pilih Filter Berdasarkan'
            options={filterByOptions}
            value={formik.values.filter_by ?? null}
            onChange={(val) =>
              formik.setFieldValue(
                'filter_by',
                !Array.isArray(val) ? (val ?? null) : null
              )
            }
            isClearable
          />

          {/* select multiple product */}
          <SelectInputCheckbox
            label='Product'
            isClearable
            placeholder='Pilih product'
            options={productsOptions}
            isLoading={isLoadingProductsOptions}
            value={formik.values.product_ids}
            onChange={productChangeHandler}
            onInputChange={setProductsInputValue}
            onMenuScrollToBottom={loadMoreProducts}
            isMulti
          />
          {/* select status */}
          <SelectInput
            label='Status'
            isClearable
            placeholder='Pilih status'
            options={statusOptions}
            value={formik.values.status}
            onChange={statusChangeHandler}
          />
          {/* select customer */}
          <SelectInput
            label='Customer'
            isClearable
            placeholder='Pilih customer'
            options={customersOptions}
            isLoading={isLoadingCustomersOptions}
            value={formik.values.customer}
            onChange={customerChangeHandler}
            onInputChange={setCustomersInputValue}
            onMenuScrollToBottom={loadMoreCustomers}
          />
          <SelectInput
            label='Project Flock'
            isClearable
            placeholder='Pilih Project Flock'
            options={projectFlockOptions}
            isLoading={isLoadingProjectFlockOptions}
            value={formik.values.project_flock}
            onChange={(val) => {
              formik.setFieldValue(
                'project_flock',
                !Array.isArray(val) ? (val as OptionType<number> | null) : null
              );
              formik.setFieldValue('project_flock_kandang', null);
            }}
            onInputChange={setProjectFlockInputValue}
            onMenuScrollToBottom={loadMoreProjectFlocks}
          />
          <SelectInput
            label='Kandang'
            isClearable
            placeholder='Pilih Kandang'
            options={projectFlockKandangOptions}
            value={formik.values.project_flock_kandang}
            onChange={(val) =>
              formik.setFieldValue(
                'project_flock_kandang',
                !Array.isArray(val) ? (val as OptionType<number> | null) : null
              )
            }
            isDisabled={!formik.values.project_flock}
          />
          <SelectInput
            label='Gudang'
            isClearable
            placeholder='Pilih Gudang'
            options={warehouseOptions}
            isLoading={isLoadingWarehouseOptions}
            value={formik.values.warehouse}
            onChange={(val) =>
              formik.setFieldValue(
                'warehouse',
                !Array.isArray(val) ? (val as OptionType<number> | null) : null
              )
            }
            onInputChange={setWarehouseInputValue}
            onMenuScrollToBottom={loadMoreWarehouses}
          />
        </div>

        {/* Modal Footer */}
        <div className='p-4 flex justify-between gap-4 border-t border-gray-300 bg-gray-100'>
          <Button
            type='reset'
            variant='ghost'
            color='none'
            className='p-3 rounded-lg text-base-content/65'
          >
            Reset Filter
          </Button>

          <Button
            type='submit'
            className='p-3 rounded-lg w-fit sm:w-full max-w-40 text-base-100 text-sm'
            disabled={hasDateError}
          >
            Apply Filter
          </Button>
        </div>
      </form>
    </Modal>
  );
};

export default MarketingFilterModal;
