import AsyncStorage from "@react-native-async-storage/async-storage";
import React, {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import { loginApi, signUpApi } from "../api/auth";

const ACCESS_TOKEN_KEY = "accessToken";
const REFRESH_TOKEN_KEY = "refreshToken";

export type AuthContextValue = {
  accessToken: string | null;
  isAuthed: boolean;
  isHydrating: boolean;
  signIn: (loginId: string, password: string) => Promise<void>;
  signOut: () => Promise<void>;
  signUp: (loginId: string, password: string) => Promise<void>;
};

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

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [accessToken, setAccessToken] = useState<string | null>(null);
  const [isHydrating, setIsHydrating] = useState(true);

  useEffect(() => {
    (async () => {
      const stored = await AsyncStorage.getItem(ACCESS_TOKEN_KEY);
      setAccessToken(stored);
      setIsHydrating(false);
    })();
  }, []);

  const signIn = useCallback(async (loginId: string, password: string) => {
    const response = await loginApi({ loginId, password });
    setAccessToken(response.data.accessToken);
    await AsyncStorage.setItem(ACCESS_TOKEN_KEY, response.data.accessToken);
    await AsyncStorage.setItem(REFRESH_TOKEN_KEY, response.data.accessToken);
  }, []);

  const signOut = useCallback(async () => {
    setAccessToken(null);
    await AsyncStorage.removeItem(ACCESS_TOKEN_KEY);
  }, []);

  const signUp = useCallback(async (loginId: string, password: string) => {
    const response = await signUpApi({ loginId, password });
    setAccessToken(response.data.accessToken);
    await AsyncStorage.setItem(ACCESS_TOKEN_KEY, response.data.accessToken);
    await AsyncStorage.setItem(REFRESH_TOKEN_KEY, response.data.accessToken);
  }, []);

  const value = useMemo<AuthContextValue>(
    () => ({
      accessToken,
      isAuthed: accessToken != null,
      isHydrating,
      signIn,
      signOut,
      signUp,
    }),
    [accessToken, isHydrating, signIn, signOut]
  );

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

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