import { createContext, useState, useEffect, useCallback, type ReactNode } from 'react';
import { apiClient } from '../api/client';

const TOKEN_KEY = 'ayos_token';

export interface UserResponse {
  id: string;
  username: string;
  email: string;
}

interface AuthState {
  user: UserResponse | null;
  token: string | null;
  loading: boolean;
}

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

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

interface LoginResponse {
  token: string;
  user: UserResponse;
}

interface RegisterResponse {
  token: string;
  user: UserResponse;
}

export function AuthProvider({ children }: { children: ReactNode }) {
  const [state, setState] = useState<AuthState>({
    user: null,
    token: localStorage.getItem(TOKEN_KEY),
    loading: true,
  });

  useEffect(() => {
    const token = localStorage.getItem(TOKEN_KEY);
    if (!token) {
      setState({ user: null, token: null, loading: false });
      return;
    }

    apiClient
      .get<UserResponse>('/api/me')
      .then((user) => {
        setState({ user, token, loading: false });
      })
      .catch(() => {
        localStorage.removeItem(TOKEN_KEY);
        setState({ user: null, token: null, loading: false });
      });
  }, []);

  const login = useCallback(async (email: string, password: string) => {
    const data = await apiClient.post<LoginResponse>('/api/login', {
      email,
      password,
    });
    localStorage.setItem(TOKEN_KEY, data.token);
    setState({ user: data.user, token: data.token, loading: false });
  }, []);

  const register = useCallback(
    async (username: string, email: string, password: string) => {
      const data = await apiClient.post<RegisterResponse>('/api/register', {
        username,
        email,
        password,
      });
      localStorage.setItem(TOKEN_KEY, data.token);
      setState({ user: data.user, token: data.token, loading: false });
    },
    [],
  );

  const logout = useCallback(() => {
    localStorage.removeItem(TOKEN_KEY);
    setState({ user: null, token: null, loading: false });
  }, []);

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