import { createContext, useCallback, useContext, useMemo, useState, type ReactNode } from "react";
import type { MeData, PapelUsuario } from "@/services/fechamento/authMe";

export type AccessBlockReason = "nao_cadastrado" | "inativo" | "erro" | "bootstrap";

type AuthAccessState = {
  loading: boolean;
  isAuthenticated: boolean;
  hasAccess: boolean;
  papel: PapelUsuario | null;
  me: MeData | null;
  reason: AccessBlockReason | null;
  errorMessage: string | null;
};

type AuthAccessContextValue = AuthAccessState & {
  setAuthState: (state: Partial<AuthAccessState>) => void;
  resetAuthState: () => void;
};

const initialState: AuthAccessState = {
  loading: true,
  isAuthenticated: false,
  hasAccess: false,
  papel: null,
  me: null,
  reason: null,
  errorMessage: null,
};

const AuthAccessContext = createContext<AuthAccessContextValue | undefined>(undefined);

export function AuthAccessProvider({ children }: { children: ReactNode }) {
  const [state, setState] = useState<AuthAccessState>(initialState);
  const setAuthState = useCallback((partial: Partial<AuthAccessState>) => {
    setState((prev) => ({ ...prev, ...partial }));
  }, []);
  const resetAuthState = useCallback(() => {
    setState(initialState);
  }, []);

  const value = useMemo<AuthAccessContextValue>(
    () => ({
      ...state,
      setAuthState,
      resetAuthState,
    }),
    [state, setAuthState, resetAuthState],
  );

  return <AuthAccessContext.Provider value={value}>{children}</AuthAccessContext.Provider>;
}

export function useAuthAccess() {
  const ctx = useContext(AuthAccessContext);
  if (!ctx) {
    throw new Error("useAuthAccess deve ser usado dentro de AuthAccessProvider.");
  }
  return ctx;
}
