import AsyncStorage from '@react-native-async-storage/async-storage';
import api from './api';

export interface User {
  id: number;
  nom: string;
  prenom: string;
  email: string;
  role: 'admin' | 'user';
  statut: 'actif' | 'inactif';
  dernier_connexion?: string;
}

export interface AuthResponse {
  message: string;
  user: User;
  token: string;
}

export interface LoginCredentials {
  email: string;
  mot_de_passe: string;
}

export interface RegisterData {
  nom: string;
  prenom: string;
  email: string;
  mot_de_passe: string;
  role?: 'admin' | 'user';
}

// Clés de stockage
const TOKEN_KEY = '@bnar_token';
const USER_KEY = '@bnar_user';

class AuthService {
  private token: string | null = null;
  private user: User | null = null;

  // Initialiser le service au démarrage de l'app
  async initialize(): Promise<void> {
    try {
      const [storedToken, storedUser] = await Promise.all([
        AsyncStorage.getItem(TOKEN_KEY),
        AsyncStorage.getItem(USER_KEY)
      ]);

      if (storedToken && storedUser) {
        this.token = storedToken;
        this.user = JSON.parse(storedUser);
        
        // Configurer le token dans axios
        this.setAuthToken(storedToken);
      }
    } catch (error) {
      console.error('Erreur lors de l\'initialisation de l\'auth:', error);
    }
  }

  // Configurer le token d'authentification dans axios
  private setAuthToken(token: string): void {
    api.defaults.headers.common['Authorization'] = `Bearer ${token}`;
  }

  // Supprimer le token d'authentification d'axios
  private clearAuthToken(): void {
    delete api.defaults.headers.common['Authorization'];
  }

  // Connexion
  async login(credentials: LoginCredentials): Promise<AuthResponse> {
    try {
      const response = await api.post('/auth/login', credentials);
      const { user, token } = response.data;

      // Stocker les données
      await this.storeAuthData(user, token);

      return response.data;
    } catch (error: any) {
      console.error('Erreur de connexion:', error);
      throw new Error(error.response?.data?.message || 'Erreur de connexion');
    }
  }

  // Inscription
  async register(data: RegisterData): Promise<AuthResponse> {
    try {
      const response = await api.post('/auth/register', data);
      const { user, token } = response.data;

      // Stocker les données
      await this.storeAuthData(user, token);

      return response.data;
    } catch (error: any) {
      console.error('Erreur d\'inscription:', error);
      throw new Error(error.response?.data?.message || 'Erreur d\'inscription');
    }
  }

  // Déconnexion
  async logout(): Promise<void> {
    try {
      // Supprimer les données du stockage
      await Promise.all([
        AsyncStorage.removeItem(TOKEN_KEY),
        AsyncStorage.removeItem(USER_KEY)
      ]);

      // Nettoyer les variables
      this.token = null;
      this.user = null;

      // Supprimer le token d'axios
      this.clearAuthToken();
    } catch (error) {
      console.error('Erreur lors de la déconnexion:', error);
    }
  }

  // Stocker les données d'authentification
  private async storeAuthData(user: User, token: string): Promise<void> {
    try {
      await Promise.all([
        AsyncStorage.setItem(TOKEN_KEY, token),
        AsyncStorage.setItem(USER_KEY, JSON.stringify(user))
      ]);

      this.token = token;
      this.user = user;

      // Configurer le token dans axios
      this.setAuthToken(token);
    } catch (error) {
      console.error('Erreur lors du stockage des données d\'auth:', error);
      throw error;
    }
  }

  // Obtenir le token actuel
  getToken(): string | null {
    return this.token;
  }

  // Obtenir l'utilisateur actuel
  getUser(): User | null {
    return this.user;
  }

  // Vérifier si l'utilisateur est connecté
  isAuthenticated(): boolean {
    return !!(this.token && this.user);
  }

  // Vérifier si l'utilisateur est administrateur
  isAdmin(): boolean {
    return this.user?.role === 'admin';
  }

  // Vérifier si l'utilisateur est un utilisateur standard
  isUser(): boolean {
    return this.user?.role === 'user';
  }

  // Obtenir le nom complet de l'utilisateur
  getUserDisplayName(): string {
    if (!this.user) return '';
    return `${this.user.prenom} ${this.user.nom}`;
  }

  // Mettre à jour le profil utilisateur
  async updateProfile(data: Partial<User>): Promise<User> {
    try {
      const response = await api.put('/auth/profile', data);
      const updatedUser = response.data.user;

      // Mettre à jour les données stockées
      this.user = updatedUser;
      await AsyncStorage.setItem(USER_KEY, JSON.stringify(updatedUser));

      return updatedUser;
    } catch (error: any) {
      console.error('Erreur lors de la mise à jour du profil:', error);
      throw new Error(error.response?.data?.message || 'Erreur de mise à jour');
    }
  }

  // Obtenir le profil utilisateur depuis le serveur
  async getProfile(): Promise<User> {
    try {
      const response = await api.get('/auth/profile');
      const user = response.data;

      // Mettre à jour les données stockées
      this.user = user;
      await AsyncStorage.setItem(USER_KEY, JSON.stringify(user));

      return user;
    } catch (error: any) {
      console.error('Erreur lors de la récupération du profil:', error);
      throw new Error(error.response?.data?.message || 'Erreur de récupération');
    }
  }
}

// Instance singleton
export const authService = new AuthService();
export default authService;
