import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { loginRequest, getMeRequest } from '../api/auth';

const TOKEN_KEY = 'auth_token';

export interface AuthUser {
  user_id: string;
  username: string;
  role: string;
}

interface AuthContextValue {
  token: string | null;
  user: AuthUser | null;
  loading: boolean;
  login: (username: string, password: string) => Promise<void>;
  logout: () => void;
}

const AuthContext = createContext<AuthContextValue>({
  token: null,
  user: null,
  loading: true,
  login: async () => {},
  logout: () => {},
});

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [token, setToken] = useState<string | null>(() => localStorage.getItem(TOKEN_KEY));
  const [user, setUser] = useState<AuthUser | null>(null);
  const [loading, setLoading] = useState(true);

  // Validate the stored token on mount by calling /auth/me.
  useEffect(() => {
    if (!token) {
      setLoading(false);
      return;
    }
    getMeRequest(token)
      .then(setUser)
      .catch(() => {
        // Token is expired or invalid — force re-login.
        localStorage.removeItem(TOKEN_KEY);
        setToken(null);
      })
      .finally(() => setLoading(false));
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const login = useCallback(async (username: string, password: string) => {
    const resp = await loginRequest(username, password);
    const me = await getMeRequest(resp.access_token);
    localStorage.setItem(TOKEN_KEY, resp.access_token);
    setToken(resp.access_token);
    setUser(me);
  }, []);

  const logout = useCallback(() => {
    localStorage.removeItem(TOKEN_KEY);
    setToken(null);
    setUser(null);
  }, []);

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

export function useAuth() {
  return useContext(AuthContext);
}
