"use client";
/**
 * AuthContext：基于 XState v5 的 React Context Provider
 *
 * 业务事件（`Auth*Submitted`）通过 `useMachine(authMachine).send()` 派发。
 * XState 自动处理异步副作用（invoke + fromPromise actors）。
 *
 * 兼容性：保持原 `useAuthState()` / `useAuthDispatch()` API，
 * 内部将 XState 状态机快照映射回原 `AuthState` 形状。
 */
import {
  type Dispatch,
  type ReactNode,
  createContext,
  useContext,
  useMemo,
} from "react";
import { useMachine } from "@xstate/react";

import { authMachine } from "./auth-machine";
import type { AuthEvent, AuthState as MachineContext } from "./auth-machine";

/**
 * 对外暴露的 State 形状
 */
interface AuthState {
  authPanelMode: MachineContext["authPanelMode"];
  authMode: MachineContext["authMode"];
  email: string;
  password: string;
  username: string;
  confirmPassword: string;
  isLoading: boolean;
  errorMessage: string | null;
  /** 当前登录状态（未登录 / 游客 / OAuth / 邮箱） */
  loginStatus: MachineContext["loginStatus"];
  /** 启动时的本地登录态恢复是否已经完成 */
  hasInitialized: MachineContext["hasInitialized"];
  /**
   * 一次性的"刚按了"信号 —— Skip / Facebook / 邮箱登录按钮派完业务事件后置 true，
   * splash-screen / auth-screen 看到 `pendingRedirect && loginStatus !== "notLoggedIn"`
   * 触发跳转 + 调 `AuthClearPendingRedirect` 置 false。
   */
  pendingRedirect: boolean;
}

const AuthStateCtx = createContext<AuthState | null>(null);
const AuthDispatchCtx = createContext<Dispatch<AuthEvent> | null>(null);

export interface AuthProviderProps {
  children: ReactNode;
}

export function AuthProvider({ children }: AuthProviderProps) {
  const [state, send] = useMachine(authMachine);

  // 映射 XState 状态机快照 → 原 AuthState 形状
  const authState = useMemo<AuthState>(
    () => ({
      authPanelMode: state.context.authPanelMode,
      authMode: state.context.authMode,
      email: state.context.email,
      password: state.context.password,
      username: state.context.username,
      confirmPassword: state.context.confirmPassword,
      // isLoading 覆盖邮箱登录 / 邮箱注册 / OAuth 跳转（NextAuth 重定向期间）/
      // OAuth 回调后端 sync / 显式游客登录
      isLoading:
        state.matches("loadingEmailLogin") ||
        state.matches("loadingEmailRegister") ||
        state.matches("loadingOAuth") ||
        state.matches("initializing") ||
        state.matches("loggingOut") ||
        state.matches("syncingGoogleBackend") ||
        state.matches("syncingFacebookBackend") ||
        state.matches("loadingGuestLogin"),
      errorMessage: state.context.errorMessage,
      loginStatus: state.context.loginStatus,
      hasInitialized: state.context.hasInitialized,
      pendingRedirect: state.context.pendingRedirect,
    }),
    [state],
  );

  return (
    <AuthStateCtx.Provider value={authState}>
      <AuthDispatchCtx.Provider value={send}>{children}</AuthDispatchCtx.Provider>
    </AuthStateCtx.Provider>
  );
}

export function useAuthState(): AuthState {
  const ctx = useContext(AuthStateCtx);
  if (!ctx) throw new Error("useAuthState must be used inside <AuthProvider>");
  return ctx;
}

export function useAuthDispatch(): Dispatch<AuthEvent> {
  const ctx = useContext(AuthDispatchCtx);
  if (!ctx)
    throw new Error("useAuthDispatch must be used inside <AuthProvider>");
  return ctx;
}
