"use client";

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from "react";
import {
  getCrossPedigreeSnapshot,
  invalidateCrossPedigreeCache,
  loadCrossPedigreeSnapshot,
  type CrossPedigreeSnapshot,
} from "./crossPedigreeCache";

interface CrossPedigreeContextValue {
  snapshot: CrossPedigreeSnapshot | null;
  loading: boolean;
  error: string | null;
  refresh: (force?: boolean) => Promise<CrossPedigreeSnapshot>;
  invalidate: () => void;
}

const CrossPedigreeContext = createContext<CrossPedigreeContextValue | null>(null);

export function CrossPedigreeProvider({ children }: { children: ReactNode }) {
  const [snapshot, setSnapshot] = useState<CrossPedigreeSnapshot | null>(() => getCrossPedigreeSnapshot());
  const [loading, setLoading] = useState(() => !getCrossPedigreeSnapshot());
  const [error, setError] = useState<string | null>(null);

  const refresh = useCallback(async (force = false) => {
    const cached = getCrossPedigreeSnapshot();
    if (!force && cached) {
      setSnapshot(cached);
      return cached;
    }

    setLoading(true);
    setError(null);
    try {
      const next = await loadCrossPedigreeSnapshot(force);
      setSnapshot(next);
      return next;
    } catch (event) {
      const message = event instanceof Error ? event.message : "数据加载失败";
      setError(message);
      throw event;
    } finally {
      setLoading(false);
    }
  }, []);

  const invalidate = useCallback(() => {
    invalidateCrossPedigreeCache();
    setSnapshot(null);
  }, []);

  useEffect(() => {
    if (getCrossPedigreeSnapshot()) return;
    refresh(false).catch(() => {});
  }, [refresh]);

  const value = useMemo(
    () => ({ snapshot, loading, error, refresh, invalidate }),
    [snapshot, loading, error, refresh, invalidate],
  );

  return (
    <CrossPedigreeContext.Provider value={value}>
      {children}
    </CrossPedigreeContext.Provider>
  );
}

export function useCrossPedigree() {
  const context = useContext(CrossPedigreeContext);
  if (!context) {
    throw new Error("useCrossPedigree must be used within CrossPedigreeProvider");
  }
  return context;
}
