'use client';

import Button from '@/components/Button';
import { Icon } from '@iconify/react';
import Modal, { useModal } from '@/components/Modal';
import DateInput from '@/components/input/DateInput';
import SelectInput, {
  OptionType,
  useSelect,
} from '@/components/input/SelectInput';
import { useState, useEffect, useRef, useCallback } from 'react';
import useSWR from 'swr';
import { DashboardApi } from '@/services/api/dashboard';
import { useFormik } from 'formik';
import { ProjectFlockApi } from '@/services/api/production';
import { KandangApi, LocationApi } from '@/services/api/master-data';
import { generateDashboardPDF } from '@/components/pages/dashboard/export/DashboardPDF';
import {
  DashboardFilterType,
  getDashboardFilterSchema,
} from '@/components/pages/dashboard/filter/DashboardProductionFilter.schema';
import DashboardLineChart from '@/components/pages/dashboard/chart/DashboardLineChart';
import DashboardLineChartSkeleton from '@/components/pages/dashboard/skeleton/DashboardLineChartSkeleton';
import DashboardAllCharts, {
  DashboardAllChartsRef,
} from '@/components/pages/dashboard/chart/DashboardAllCharts';
import { RadioGroup, RadioGroupItem } from '@/components/input/RadioInput';
import {
  DashboardFilter,
  DashboardMeta,
} from '@/types/api/dashboard/dashboard';
import DashboardStats from '@/components/pages/dashboard/chart/DashboardStats';
import { isResponseSuccess } from '@/lib/api-helper';
import AlertErrorList from '@/components/helper/form/FormErrors';
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
import ButtonFilter from '@/components/helper/ButtonFilter';
import Dropdown from '@/components/Dropdown';
import Menu from '@/components/menu/Menu';
import MenuItem from '@/components/menu/MenuItem';
import { useDashboardStore } from '@/stores/dashboard';
import SelectInputRadio from '@/components/input/SelectInputRadio';
import SelectInputCheckbox from '@/components/input/SelectInputCheckbox';

// Helper function to normalize values to array
const normalizeToArray = (
  value: OptionType | OptionType[] | null | undefined
): number[] => {
  if (!value) return [];
  if (Array.isArray(value)) {
    return value.map((v) => Number(v.value));
  }
  return [Number(value.value)];
};

const DashboardProduction = () => {
  const filterModal = useModal();

  // ===== DASHBOARD STORE =====
  const { filterValues, setFilterValues, resetFilterValues } =
    useDashboardStore();

  const [analysisMode, setAnalysisMode] = useState<'OVERVIEW' | 'COMPARISON'>(
    (filterValues.analysisMode as 'OVERVIEW' | 'COMPARISON') || 'OVERVIEW'
  );
  const [endpointUrl, setEndpointUrl] = useState('/dashboards');
  const [selectedLocationIds, setSelectedLocationIds] = useState<number[]>(
    normalizeToArray(filterValues.location)
  );
  const [exporting, setExporting] = useState(false);
  const statsRef = useRef<HTMLDivElement>(null);
  const chartRef = useRef<HTMLDivElement>(null);
  const allChartsRef = useRef<DashboardAllChartsRef>(null);

  // ===== FETCH DATA =====
  const {
    data: dashboardProductionResponse,
    isLoading: isLoadingDashboardProductionData,
    mutate: refreshDashboardProductionData,
  } = useSWR(endpointUrl, () =>
    DashboardApi.getDashboardProductionFetcher(endpointUrl)
  );

  const dashboardProductionData = isResponseSuccess(dashboardProductionResponse)
    ? dashboardProductionResponse.data
    : undefined;

  // ===== SELECT =====
  const {
    setInputValue: setInputValueFlock,
    options: flockOptions,
    isLoadingOptions: isLoadingFlockOptions,
    loadMore: loadMoreFlock,
  } = useSelect(ProjectFlockApi.basePath, 'id', 'flock_name', '', {
    location_id: selectedLocationIds ? selectedLocationIds.toString() : '',
  });
  const {
    setInputValue: setInputValueLocation,
    options: locationOptions,
    isLoadingOptions: isLoadingLocationOptions,
    loadMore: loadMoreLocation,
  } = useSelect(LocationApi.basePath, 'id', 'name');
  const {
    setInputValue: setInputValueKandang,
    options: kandangOptions,
    isLoadingOptions: isLoadingKandangOptions,
    loadMore: loadMoreKandang,
  } = useSelect(KandangApi.basePath, 'id', 'name', '', {
    location_id: selectedLocationIds ? selectedLocationIds.toString() : '',
  });
  const comparisonTypeOptions = [
    { value: 'FARM', label: 'Farm' },
    { value: 'FLOCK', label: 'Flock' },
    { value: 'KANDANG', label: 'Kandang' },
  ];

  // ===== FORMIK =====
  const formik = useFormik({
    initialValues: {
      startDate: filterValues.startDate ?? '',
      endDate: filterValues.endDate ?? '',
      flock: filterValues.flock ?? ([] as OptionType[]),
      location: filterValues.location ?? ([] as OptionType[]),
      kandang: filterValues.kandang ?? ([] as OptionType[]),
      analysisMode: filterValues.analysisMode ?? analysisMode,
      comparisonType: filterValues.comparisonType ?? '',
      locationIds: filterValues.locationIds ?? [],
      flockIds: filterValues.flockIds ?? [],
      kandangIds: filterValues.kandangIds ?? [],
    } as DashboardFilterType,
    enableReinitialize: true,
    validationSchema: getDashboardFilterSchema(analysisMode),
    onSubmit: (values) => {
      // Save filter values to store
      setFilterValues(values);

      handleApplyFilter({
        start_date: values.startDate || '',
        end_date: values.endDate || '',
        analysis_mode: values.analysisMode as 'OVERVIEW' | 'COMPARISON',
        location_ids: normalizeToArray(values.location),
        flock_ids: normalizeToArray(values.flock),
        kandang_ids: normalizeToArray(values.kandang),
        comparison_type: values.comparisonType,
      });
    },
  });

  const handleResetFilter = useCallback(() => {
    formik.resetForm();
    resetFilterValues(); // Clear stored filter values
    setAnalysisMode('OVERVIEW');
    setEndpointUrl('/dashboards');
    setSelectedLocationIds([]);
  }, [resetFilterValues, filterValues, selectedLocationIds]);

  const handleApplyFilter = (values: DashboardFilter) => {
    // Build query params object, only include non-empty values
    const params: Record<string, string> = {};

    if (values.start_date) params.start_date = values.start_date;
    if (values.end_date) params.end_date = values.end_date;
    if (values.analysis_mode) params.analysis_mode = values.analysis_mode;
    if (values.location_ids.length > 0)
      params.location_ids = values.location_ids.toString();
    if (values.flock_ids.length > 0)
      params.flock_ids = values.flock_ids.toString();
    if (values.kandang_ids.length > 0)
      params.kandang_ids = values.kandang_ids.toString();
    if (values.comparison_type) params.comparison_type = values.comparison_type;

    setEndpointUrl(`/dashboards?${new URLSearchParams(params).toString()}`);
    filterModal.closeModal();
    refreshDashboardProductionData();
  };

  // ===== Load filter from store on mount =====
  useEffect(() => {
    if (!filterValues) return;
    handleApplyFilter({
      start_date: filterValues.startDate,
      end_date: filterValues.endDate,
      analysis_mode: filterValues.analysisMode as 'OVERVIEW' | 'COMPARISON',
      location_ids: normalizeToArray(filterValues.location),
      flock_ids: normalizeToArray(filterValues.flock),
      kandang_ids: normalizeToArray(filterValues.kandang),
      comparison_type: filterValues.comparisonType,
    });
  }, [filterValues]);

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

  // ===== Export PDF =====
  const handleExportPDF = async () => {
    await generateDashboardPDF({
      filterValues: formik.values,
      statsRef,
      allChartsRef,
      setExporting,
    });
  };

  if (isLoadingDashboardProductionData) {
    return (
      <div className='w-full min-h-screen flex items-center justify-center'>
        <span className='loading loading-spinner loading-xl'></span>
      </div>
    );
  }

  return (
    <>
      <section className='w-full p-4 space-y-6'>
        <div className='flex flex-col sm:flex-row items-center justify-between gap-4'>
          <div></div>

          <div className='flex flex-row justify-end gap-2'>
            <ButtonFilter
              values={{
                ...formik.values,
                analysisMode: undefined,
              }}
              variant='outline'
              className='min-w-28 rounded-lg'
              onClick={() => filterModal.openModal()}
            />
            <Dropdown
              trigger={
                <Button variant='outline' className='min-w-28 rounded-lg z-50'>
                  <Icon icon='heroicons:arrow-down-tray' />
                  Export
                  <Icon icon='heroicons:chevron-down' />
                </Button>
              }
              className={{
                content: 'w-full',
              }}
            >
              <Menu className={exporting ? 'hidden' : ''}>
                <MenuItem title='PDF' onClick={handleExportPDF} />
              </Menu>
            </Dropdown>
          </div>
        </div>

        {/* Dashboard Stats */}
        <div ref={statsRef}>
          <DashboardStats
            data={dashboardProductionData?.statistics_data ?? []}
          />
        </div>

        {/* Use DashboardLineChart component or skeleton */}
        <div ref={chartRef}>
          {isLoadingDashboardProductionData ? (
            <DashboardLineChartSkeleton />
          ) : dashboardProductionData &&
            dashboardProductionData.charts &&
            Object.keys(dashboardProductionData.charts).length > 0 ? (
            <DashboardLineChart
              analysisMode={
                isResponseSuccess(dashboardProductionResponse)
                  ? dashboardProductionResponse.meta
                    ? (
                        dashboardProductionResponse.meta as unknown as DashboardMeta
                      ).filters?.analysis_mode
                    : analysisMode
                  : analysisMode
              }
              data={dashboardProductionData}
              selectedKandang={
                analysisMode === 'OVERVIEW'
                  ? (formik.values.kandang as OptionType)
                  : undefined
              }
            />
          ) : (
            <DashboardLineChartSkeleton
              meta={
                isResponseSuccess(dashboardProductionResponse)
                  ? (dashboardProductionResponse.meta as unknown as DashboardMeta)
                  : undefined
              }
            />
          )}
        </div>

        {/* Hidden container for all charts (used for PDF export in OVERVIEW mode) */}
        {dashboardProductionData && (
          <div
            style={{
              position: 'absolute',
              left: '-9999px',
              top: 0,
              width: '1200px', // Fixed width for consistent PDF rendering
            }}
          >
            <DashboardAllCharts
              ref={allChartsRef}
              data={dashboardProductionData}
              analysisMode={
                isResponseSuccess(dashboardProductionResponse)
                  ? dashboardProductionResponse.meta
                    ? (
                        dashboardProductionResponse.meta as unknown as DashboardMeta
                      ).filters?.analysis_mode
                    : analysisMode
                  : analysisMode
              }
            />
          </div>
        )}
      </section>

      <Modal
        ref={filterModal.ref}
        className={{
          modal: 'p-0',
          modalBox: 'p-0 rounded-xl',
        }}
      >
        <div className='space-y-6'>
          {/* Modal Header */}
          <div className='flex items-center justify-between gap-2 py-3 border-b border-gray-300'>
            <div className='flex items-center gap-2 ms-4'>
              <Icon icon='heroicons:funnel' width={20} height={20} />
              <h3 className='font-semibold'>Filter Data</h3>
            </div>
            <Button
              variant='link'
              onClick={() => filterModal.closeModal()}
              className='text-gray-500 hover:text-gray-700 me-4 '
            >
              <Icon icon='heroicons:x-mark' width={20} height={20} />
            </Button>
          </div>

          <form
            className='space-y-4'
            onSubmit={handleFormSubmit}
            onReset={handleResetFilter}
          >
            {/* Rentang Waktu */}
            <div className='px-4'>
              <label className='flex items-center gap-2 mb-3'>Tanggal</label>
              <div className='flex items-start gap-2'>
                <DateInput
                  name='startDate'
                  placeholder='Tanggal Mulai'
                  value={formik.values.startDate}
                  errorMessage={formik.errors.startDate}
                  onChange={formik.handleChange}
                  className={{
                    inputWrapper: 'rounded-lg',
                  }}
                  isError={
                    Boolean(formik.errors.startDate) &&
                    Boolean(formik.touched.startDate)
                  }
                />
                <div className='hidden md:block mt-3 text-center'>—</div>
                <DateInput
                  name='endDate'
                  placeholder='Tanggal Akhir'
                  value={formik.values.endDate}
                  errorMessage={formik.errors.endDate}
                  onChange={formik.handleChange}
                  className={{
                    inputWrapper: 'rounded-lg',
                  }}
                  isError={
                    Boolean(formik.errors.endDate) &&
                    Boolean(formik.touched.endDate)
                  }
                />
              </div>
            </div>

            {/* Analysis Mode */}
            <div className='px-4'>
              <label className='block mb-3'>Analysis Mode</label>
              <RadioGroup
                name='analysisMode'
                value={formik.values.analysisMode}
                onChange={(e) => {
                  formik.handleChange(e);
                  setAnalysisMode(e.target.value as 'OVERVIEW' | 'COMPARISON');
                  // Reset all dependent fields when analysis mode changes
                  formik.setFieldValue('location', []);
                  formik.setFieldValue('flock', []);
                  formik.setFieldValue('kandang', []);
                  formik.setFieldValue('comparisonType', '');
                  setSelectedLocationIds([]);
                }}
                color='primary'
                className={{
                  wrapper: 'w-full my-6 font-semibold text-neutral-500',
                }}
              >
                <RadioGroupItem
                  color='primary'
                  value='OVERVIEW'
                  label='Performance Overview'
                />
                <RadioGroupItem
                  color='primary'
                  value='COMPARISON'
                  label='Performance Comparison'
                />
              </RadioGroup>
            </div>

            {formik.values.analysisMode === 'COMPARISON' && (
              <div className='px-4'>
                <SelectInputRadio
                  label='Compared By'
                  value={comparisonTypeOptions.find(
                    (option) => option.value === formik.values.comparisonType
                  )}
                  onChange={(selected) =>
                    formik.setFieldValue(
                      'comparisonType',
                      selected ? (selected as OptionType).value : ''
                    )
                  }
                  errorMessage={formik.errors.comparisonType as string}
                  options={comparisonTypeOptions}
                  isLoading={isLoadingLocationOptions}
                  isError={
                    Boolean(formik.errors.comparisonType) &&
                    Boolean(formik.touched.comparisonType)
                  }
                />
              </div>
            )}

            {/* Location */}
            <div className='px-4'>
              {comparisonTypeOptions.find(
                (option) => option.value === formik.values.comparisonType
              )?.value === 'FARM' ? (
                <SelectInputCheckbox
                  label='Farm'
                  value={
                    formik.values.location as
                      | { value: number; label: string }
                      | { value: number; label: string }[]
                      | null
                      | undefined
                  }
                  onInputChange={setInputValueLocation}
                  onMenuScrollToBottom={loadMoreLocation}
                  onChange={(selected) => {
                    formik.setFieldValue('location', selected);
                    // Update selectedLocationIds for kandang filter
                    setSelectedLocationIds(normalizeToArray(selected));
                    // Reset dependent fields when location changes
                    formik.setFieldValue('flock', []);
                    formik.setFieldValue('kandang', []);
                  }}
                  errorMessage={formik.errors.location as string}
                  options={locationOptions}
                  isLoading={isLoadingLocationOptions}
                  isError={
                    Boolean(formik.errors.location) &&
                    Boolean(formik.touched.location)
                  }
                />
              ) : (
                <SelectInputRadio
                  label='Farm'
                  value={
                    formik.values.location as
                      | { value: number; label: string }
                      | { value: number; label: string }[]
                      | null
                      | undefined
                  }
                  onInputChange={setInputValueLocation}
                  onMenuScrollToBottom={loadMoreLocation}
                  onChange={(selected) => {
                    formik.setFieldValue('location', selected);
                    // Update selectedLocationIds for kandang filter
                    setSelectedLocationIds(normalizeToArray(selected));
                    // Reset dependent fields when location changes
                    formik.setFieldValue('flock', []);
                    formik.setFieldValue('kandang', []);
                  }}
                  errorMessage={formik.errors.location as string}
                  options={locationOptions}
                  isLoading={isLoadingLocationOptions}
                  isError={
                    Boolean(formik.errors.location) &&
                    Boolean(formik.touched.location)
                  }
                />
              )}
            </div>

            {/* Flock */}
            {!(
              formik.values.analysisMode === 'COMPARISON' &&
              !(
                formik.values.comparisonType === 'FLOCK' ||
                formik.values.comparisonType === 'KANDANG'
              )
            ) && (
              <div className='px-4'>
                {comparisonTypeOptions.find(
                  (option) => option.value === formik.values.comparisonType
                )?.value === 'FLOCK' ? (
                  <SelectInputCheckbox
                    label='Flock'
                    value={
                      formik.values.flock as
                        | { value: number; label: string }
                        | { value: number; label: string }[]
                        | null
                        | undefined
                    }
                    onChange={(selected) =>
                      formik.setFieldValue('flock', selected)
                    }
                    errorMessage={formik.errors.flock as string}
                    onInputChange={setInputValueFlock}
                    onMenuScrollToBottom={loadMoreFlock}
                    options={flockOptions}
                    isLoading={isLoadingFlockOptions}
                    isError={
                      Boolean(formik.errors.flock) &&
                      Boolean(formik.touched.flock)
                    }
                  />
                ) : (
                  <SelectInputRadio
                    label='Flock'
                    value={
                      formik.values.flock as
                        | { value: number; label: string }
                        | { value: number; label: string }[]
                        | null
                        | undefined
                    }
                    onChange={(selected) =>
                      formik.setFieldValue('flock', selected)
                    }
                    errorMessage={formik.errors.flock as string}
                    onInputChange={setInputValueFlock}
                    onMenuScrollToBottom={loadMoreFlock}
                    options={flockOptions}
                    isLoading={isLoadingFlockOptions}
                    isError={
                      Boolean(formik.errors.flock) &&
                      Boolean(formik.touched.flock)
                    }
                  />
                )}
              </div>
            )}

            {/* Kandang */}
            {!(
              formik.values.analysisMode === 'COMPARISON' &&
              !(formik.values.comparisonType === 'KANDANG')
            ) && (
              <div className='px-4'>
                {comparisonTypeOptions.find(
                  (option) => option.value === formik.values.comparisonType
                )?.value === 'KANDANG' ? (
                  <SelectInputCheckbox
                    label='Kandang'
                    value={
                      formik.values.kandang as
                        | { value: number; label: string }
                        | { value: number; label: string }[]
                        | null
                        | undefined
                    }
                    onChange={(selected) =>
                      formik.setFieldValue('kandang', selected)
                    }
                    errorMessage={formik.errors.kandang as string}
                    onInputChange={setInputValueKandang}
                    onMenuScrollToBottom={loadMoreKandang}
                    options={kandangOptions}
                    isLoading={isLoadingKandangOptions}
                    isError={
                      Boolean(formik.errors.kandang) &&
                      Boolean(formik.touched.kandang)
                    }
                  />
                ) : (
                  <SelectInputRadio
                    label='Kandang'
                    value={
                      formik.values.kandang as
                        | { value: number; label: string }
                        | { value: number; label: string }[]
                        | null
                        | undefined
                    }
                    onChange={(selected) =>
                      formik.setFieldValue('kandang', selected)
                    }
                    errorMessage={formik.errors.kandang as string}
                    onInputChange={setInputValueKandang}
                    onMenuScrollToBottom={loadMoreKandang}
                    options={kandangOptions}
                    isLoading={isLoadingKandangOptions}
                    isError={
                      Boolean(formik.errors.kandang) &&
                      Boolean(formik.touched.kandang)
                    }
                  />
                )}
              </div>
            )}

            <div className='w-full p-4'>
              <AlertErrorList formErrorList={formErrorList} onClose={close} />
            </div>

            {/* Action Buttons */}
            <div className='flex justify-between gap-4 py-4 mt-8 border-t border-gray-300 bg-gray-100'>
              <Button
                type='reset'
                variant='soft'
                className='ms-4 min-w-36 rounded-lg'
              >
                Reset Filter
              </Button>
              <Button type='submit' className='me-4 min-w-36 rounded-lg'>
                Terapkan Filter
              </Button>
            </div>
          </form>
        </div>
      </Modal>
    </>
  );
};

export default DashboardProduction;
