import React, {
  createContext,
  useContext,
  useState,
  useEffect,
  useCallback,
  type ReactNode,
} from "react";
import type { User, TokenResponse } from "@cloud-reader/shared";
import { apiClient, saveTokens, loadTokens, clearTokens } from "../api/client";

interface AuthState {
  user: User | null;
  isLoading: boolean;
  isAuthenticated: boolean;
}

interface AuthContextValue extends AuthState {
  login: (email: string, password: string) => Promise<void>;
  register: (
    email: string,
    username: string,
    password: string,
  ) => Promise<void>;
  logout: () => Promise<void>;
}

const AuthContext = createContext<AuthContextValue | null>(null);

export function AuthProvider({ children }: { children: ReactNode }) {
  const [state, setState] = useState<AuthState>({
    user: null,
    isLoading: true,
    isAuthenticated: false,
  });

  // Restore session on mount
  useEffect(() => {
    (async () => {
      try {
        const tokens = await loadTokens();
        if (tokens?.access) {
          const response = await apiClient.get<User>("/api/auth/profile/");
          setState({
            user: response.data,
            isLoading: false,
            isAuthenticated: true,
          });
          return;
        }
      } catch {
        await clearTokens();
      }
      setState({ user: null, isLoading: false, isAuthenticated: false });
    })();
  }, []);

  const login = useCallback(async (email: string, password: string) => {
    const response = await apiClient.post<TokenResponse>(
      "/api/auth/login/",
      { email, password },
    );
    await saveTokens(response.data);
    const profile = await apiClient.get<User>("/api/auth/profile/");
    setState({
      user: profile.data,
      isLoading: false,
      isAuthenticated: true,
    });
  }, []);

  const register = useCallback(
    async (email: string, username: string, password: string) => {
      await apiClient.post("/api/auth/register/", {
        email,
        username,
        password,
        password2: password,
      });
      // Auto-login after registration
      await login(email, password);
    },
    [login],
  );

  const logout = useCallback(async () => {
    await clearTokens();
    setState({ user: null, isLoading: false, isAuthenticated: false });
  }, []);

  return (
    <AuthContext.Provider value={{ ...state, login, register, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth(): AuthContextValue {
  const ctx = useContext(AuthContext);
  if (!ctx) {
    throw new Error("useAuth must be used within an AuthProvider");
  }
  return ctx;
}