import { useReducer, useCallback, useEffect, useRef } from "react";
import type { CartesSnapshot, CartesKpiPeriodMode } from "../shared/types";
import { getCartesSnapshot } from "../services/reportService";
import { defaultReferencePeriod } from "../utils/referencePeriod";

export const CARTES_PERIOD_MODE_STORAGE_KEY = "reports-cartes-period-mode";

interface State {
  year: number;
  month: number;
  mode: CartesKpiPeriodMode;
  snapshot: CartesSnapshot | null;
  isLoading: boolean;
  error: string | null;
}

type Action =
  | { type: "SET_REFERENCE_PERIOD"; payload: { year: number; month: number } }
  | { type: "SET_MODE"; payload: CartesKpiPeriodMode }
  | { type: "SET_LOADING"; payload: boolean }
  | { type: "SET_SNAPSHOT"; payload: CartesSnapshot }
  | { type: "SET_ERROR"; payload: string };

/**
 * Re-exported so older imports keep working. New code should import
 * `defaultReferencePeriod` from `../utils/referencePeriod`.
 */
export const defaultCartesReferencePeriod = defaultReferencePeriod;

/**
 * Read the persisted period mode from localStorage. Unrecognised values fall
 * back to "month" so a corrupted/legacy key never breaks the page.
 */
export function readCartesPeriodMode(
  storageKey: string = CARTES_PERIOD_MODE_STORAGE_KEY,
  fallback: CartesKpiPeriodMode = "month",
): CartesKpiPeriodMode {
  if (typeof localStorage === "undefined") return fallback;
  const saved = localStorage.getItem(storageKey);
  return saved === "month" || saved === "ytd" ? saved : fallback;
}

const defaultRef = defaultReferencePeriod();
const initialState: State = {
  year: defaultRef.year,
  month: defaultRef.month,
  mode: "month",
  snapshot: null,
  isLoading: false,
  error: null,
};

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "SET_REFERENCE_PERIOD":
      return { ...state, year: action.payload.year, month: action.payload.month };
    case "SET_MODE":
      return { ...state, mode: action.payload };
    case "SET_LOADING":
      return { ...state, isLoading: action.payload };
    case "SET_SNAPSHOT":
      return { ...state, snapshot: action.payload, isLoading: false, error: null };
    case "SET_ERROR":
      return { ...state, error: action.payload, isLoading: false };
    default:
      return state;
  }
}

export function useCartes() {
  const [state, dispatch] = useReducer(reducer, initialState, (init) => ({
    ...init,
    mode: readCartesPeriodMode(),
  }));
  const fetchIdRef = useRef(0);

  const fetch = useCallback(async (year: number, month: number, mode: CartesKpiPeriodMode) => {
    const id = ++fetchIdRef.current;
    dispatch({ type: "SET_LOADING", payload: true });
    try {
      const snapshot = await getCartesSnapshot(year, month, mode);
      if (id !== fetchIdRef.current) return;
      dispatch({ type: "SET_SNAPSHOT", payload: snapshot });
    } catch (e) {
      if (id !== fetchIdRef.current) return;
      dispatch({ type: "SET_ERROR", payload: e instanceof Error ? e.message : String(e) });
    }
  }, []);

  useEffect(() => {
    fetch(state.year, state.month, state.mode);
  }, [fetch, state.year, state.month, state.mode]);

  const setReferencePeriod = useCallback((year: number, month: number) => {
    dispatch({ type: "SET_REFERENCE_PERIOD", payload: { year, month } });
  }, []);

  const setMode = useCallback((mode: CartesKpiPeriodMode) => {
    if (typeof localStorage !== "undefined") {
      localStorage.setItem(CARTES_PERIOD_MODE_STORAGE_KEY, mode);
    }
    dispatch({ type: "SET_MODE", payload: mode });
  }, []);

  return {
    ...state,
    setReferencePeriod,
    setMode,
  };
}
