import { useState, useEffect, useCallback, useMemo } from "react";
import useHolidayService from "./useHolidayService";
import {
  type Holiday,
  type HolidayFilters,
  type CreateHolidayData,
  type UpdateHolidayData,
  type BulkCreateHolidaysData,
} from "../../services/holidayService";

interface UseHolidayState {
  holidays: Holiday[];
  total: number;
  selectedYear: number;
  loading: boolean;
  error: string | null;
}

interface UseHolidayActions {
  setSelectedYear: (year: number) => void;
  refreshData: () => Promise<void>;
  createHoliday: (data: CreateHolidayData) => Promise<boolean>;
  bulkCreateHolidays: (data: BulkCreateHolidaysData) => Promise<boolean>;
  updateHoliday: (data: UpdateHolidayData) => Promise<boolean>;
  deleteHoliday: (id: string) => Promise<boolean>;
  deleteHolidaysByYear: (year: number) => Promise<boolean>;
  getHolidayById: (id: string) => Promise<Holiday | null>;
}

const INITIAL_STATE: UseHolidayState = {
  holidays: [],
  total: 0,
  selectedYear: new Date().getFullYear(),
  loading: false,
  error: null,
};

function useHoliday() {
  const [state, setState] = useState<UseHolidayState>(INITIAL_STATE);
  const service = useHolidayService();

  // Memoize filters to prevent unnecessary API calls
  const filters = useMemo<HolidayFilters>(() => {
    return {
      year: state.selectedYear,
    };
  }, [state.selectedYear]);

  // Auto-fetch when filters change
  useEffect(() => {
    const fetchHolidays = async () => {
      setState((prev) => ({ ...prev, loading: true, error: null }));

      const result = await service.getHolidays(filters);

      if (result.success && result.data) {
        setState((prev) => ({
          ...prev,
          holidays: result.data!.data ?? [],
          total: result.data!.count ?? 0,
          loading: false,
          error: null,
        }));
      } else {
        setState((prev) => ({
          ...prev,
          holidays: [],
          total: 0,
          loading: false,
          error: result.message,
        }));
      }
    };

    fetchHolidays();
  }, [filters]);

  // Action handlers
  const setSelectedYear = useCallback((year: number) => {
    setState((prev) => ({ ...prev, selectedYear: year }));
  }, []);

  const refreshData = useCallback(async () => {
    setState((prev) => ({ ...prev, loading: true, error: null }));

    const result = await service.getHolidays(filters);

    if (result.success && result.data) {
      setState((prev) => ({
        ...prev,
        holidays: result.data!.data ?? [],
        total: result.data!.count ?? 0,
        loading: false,
        error: null,
      }));
    } else {
      setState((prev) => ({
        ...prev,
        holidays: [],
        total: 0,
        loading: false,
        error: result.message,
      }));
    }
  }, [service, filters]);

  // CRUD operations
  const createHoliday = useCallback(
    async (data: CreateHolidayData): Promise<boolean> => {
      const result = await service.createHoliday(data);
      if (result.success) {
        await refreshData();
      }
      return result.success;
    },
    [service, refreshData]
  );

  const bulkCreateHolidays = useCallback(
    async (data: BulkCreateHolidaysData): Promise<boolean> => {
      const result = await service.bulkCreateHolidays(data);
      if (result.success) {
        await refreshData();
      }
      return result.success;
    },
    [service, refreshData]
  );

  const updateHoliday = useCallback(
    async (data: UpdateHolidayData): Promise<boolean> => {
      const result = await service.updateHoliday(data);
      if (result.success) {
        await refreshData();
      }
      return result.success;
    },
    [service, refreshData]
  );

  const deleteHoliday = useCallback(
    async (id: string): Promise<boolean> => {
      const result = await service.deleteHoliday(id);
      if (result.success) {
        await refreshData();
      }
      return result.success;
    },
    [service, refreshData]
  );

  const deleteHolidaysByYear = useCallback(
    async (year: number): Promise<boolean> => {
      const result = await service.deleteHolidaysByYear(year);
      if (result.success) {
        await refreshData();
      }
      return result.success;
    },
    [service, refreshData]
  );

  const getHolidayById = useCallback(
    async (id: string): Promise<Holiday | null> => {
      const result = await service.getHolidayById(id);
      return result.success && result.data ? result.data : null;
    },
    [service]
  );

  const actions: UseHolidayActions = {
    setSelectedYear,
    refreshData,
    createHoliday,
    bulkCreateHolidays,
    updateHoliday,
    deleteHoliday,
    deleteHolidaysByYear,
    getHolidayById,
  };

  return {
    ...state,
    loading: state.loading || service.loading,
    ...actions,
  };
}

export default useHoliday;
