/**
 * Services API pour BTP Xpress
 */

import axios, { AxiosInstance, AxiosResponse } from 'axios';
import { API_CONFIG } from '../config/api';
import { keycloak, KEYCLOAK_TIMEOUTS } from '../config/keycloak';
import { CacheService, CacheKeys } from './cacheService';
import {
  Client,
  Chantier,
  Devis,
  Facture,
  DashboardStats,
  ChantierRecent,
  FactureEnRetard,
  DevisEnAttente,
  FilterOptions,
  SearchResult,
  Employe,
  Equipe,
  Materiel,
  MaintenanceMateriel,
  PlanningEvent,
  PlanningCalendrierView,
  PlanningConflict,
  PlanningStats
} from '../types/btp';
import { UserInfo } from '../types/auth';

class ApiService {
  private api: AxiosInstance;
  private serverStatusListeners: ((isOnline: boolean) => void)[] = [];

  constructor() {
    this.api = axios.create({
      baseURL: API_CONFIG.baseURL,
      timeout: API_CONFIG.timeout,
      headers: API_CONFIG.headers,
    });

    // Interceptor pour les requêtes - ajouter le token d'authentification
    this.api.interceptors.request.use(
      async (config) => {
        // Utiliser le token stocké dans localStorage (nouveau système)
        if (typeof window !== 'undefined') {
          const accessToken = localStorage.getItem('accessToken');

          if (accessToken) {
            config.headers['Authorization'] = `Bearer ${accessToken}`;
            console.log('🔐 API Request avec token:', config.url);
          } else {
            console.log('⚠️ API Request sans token:', config.url);
          }
        }

        // Ajouter des en-têtes par défaut
        config.headers['X-Requested-With'] = 'XMLHttpRequest';

        return config;
      },
      (error) => {
        return Promise.reject(error);
      }
    );

    // Interceptor pour les réponses
    this.api.interceptors.response.use(
      (response: AxiosResponse) => response,
      async (error) => {
        // Ne pas logger les 404 sur les endpoints de chantiers par client (pas encore implémentés)
        const is404OnChantiersByClient = error.response?.status === 404 && 
                                         error.config?.url?.includes('/chantiers/client/');
        
        if (!is404OnChantiersByClient) {
          // Utiliser console.warn au lieu de console.error pour éviter les erreurs React DevTools
          console.warn('API Error:', error.response?.status, error.response?.data || error.message);
        }
        
        // Gérer les erreurs de connexion réseau
        if (!error.response) {
          // Erreur réseau (serveur indisponible, pas de connexion, etc.)
          if (error.code === 'ECONNABORTED') {
            error.userMessage = 'Délai d\'attente dépassé. Le serveur backend met trop de temps à répondre.';
            error.statusCode = 'TIMEOUT';
          } else if (error.code === 'ERR_NETWORK') {
            error.userMessage = 'Impossible de joindre le serveur backend. Vérifiez votre connexion internet et que le serveur backend est démarré (mvn quarkus:dev).';
            error.statusCode = 'NETWORK_ERROR';
          } else {
            error.userMessage = 'Serveur backend indisponible. Vérifiez que le serveur backend est démarré (mvn quarkus:dev) et accessible sur le port 8080.';
            error.statusCode = 'SERVER_UNAVAILABLE';
          }
          
          // Émettre un événement global pour notifier l'application
          this.notifyServerStatus(false);
          return Promise.reject(error);
        }
        
        // Serveur répond, donc il est disponible
        this.notifyServerStatus(true);
        
        if (error.response?.status === 401) {
          // Gestion des erreurs d'authentification
          if (typeof window !== 'undefined') {
            const currentUrl = window.location.href;
            const hasAuthCode = currentUrl.includes('code=') && currentUrl.includes('/dashboard');

            if (!hasAuthCode) {
              console.log('🔄 Token expiré, redirection vers la connexion...');
              // Sauvegarder la page actuelle pour y revenir après reconnexion
              const currentPath = window.location.pathname + window.location.search;
              localStorage.setItem('returnUrl', currentPath);

              // Nettoyer les tokens expirés
              localStorage.removeItem('accessToken');
              localStorage.removeItem('refreshToken');
              localStorage.removeItem('idToken');

              // Rediriger vers la page de connexion
              window.location.href = '/api/auth/login';
            } else {
              console.log('🔄 API Service: Erreur 401 ignorée car authentification en cours...');
            }
          }
        }
        
        // Créer une erreur plus propre pour l'affichage
        const errorMessage = error.response?.data?.message || 
                           error.response?.data?.error || 
                           error.message || 
                           'Une erreur est survenue';
        
        const enhancedError = {
          ...error,
          userMessage: errorMessage,
          statusCode: error.response?.status
        };
        
        return Promise.reject(enhancedError);
      }
    );
  }

  // === GESTION STATUT SERVEUR ===
  private notifyServerStatus(isOnline: boolean) {
    this.serverStatusListeners.forEach(listener => {
      try {
        listener(isOnline);
      } catch (error) {
        console.error('Erreur dans listener de statut serveur:', error);
      }
    });
  }

  public onServerStatusChange(callback: (isOnline: boolean) => void) {
    this.serverStatusListeners.push(callback);
    return () => {
      const index = this.serverStatusListeners.indexOf(callback);
      if (index > -1) {
        this.serverStatusListeners.splice(index, 1);
      }
    };
  }

  public async checkServerHealth(urgentCheck: boolean = false): Promise<boolean> {
    const timeout = urgentCheck ? 3000 : 8000; // Timeout plus long pour checks de routine
    
    try {
      // Endpoint dédié health check ultra-léger
      await this.api.get('/api/v1/health', {
        timeout,
        headers: { 'Cache-Control': 'no-cache' },
        params: { _t: Date.now() } // Cache busting
      });
      this.notifyServerStatus(true);
      return true;
    } catch (error) {
      // Fallback sur endpoint Quarkus standard puis clients
      try {
        await this.api.get('/q/health', { timeout: timeout * 0.8 });
        this.notifyServerStatus(true);
        return true;
      } catch (secondError) {
        try {
          await this.api.get('/api/v1/clients', {
            timeout: timeout * 0.6,
            params: { size: 1 }
          });
          this.notifyServerStatus(true);
          return true;
        } catch (thirdError) {
          this.notifyServerStatus(false);
          return false;
        }
      }
    }
  }

  // === CLIENTS ===
  async getClients(): Promise<Client[]> {
    return CacheService.getOrSet(
      CacheKeys.CLIENTS,
      async () => {
        const response = await this.api.get<Client[]>('/api/v1/clients');
        return Array.isArray(response.data) ? response.data : [];
      },
      5 * 60 * 1000 // 5 minutes
    );
  }

  async getClient(id: string): Promise<Client> {
    const response = await this.api.get<Client>(`/api/v1/clients/${id}`);
    return response.data;
  }

  async createClient(client: Partial<Client>): Promise<Client> {
    const response = await this.api.post<Client>('/api/v1/clients', client);
    return response.data;
  }

  async updateClient(id: string, client: Partial<Client>): Promise<Client> {
    const response = await this.api.put<Client>(`/api/v1/clients/${id}`, client);
    return response.data;
  }

  async deleteClient(id: string): Promise<void> {
    await this.api.delete(`/api/v1/clients/${id}`);
  }

  async searchClients(params: {
    nom?: string;
    entreprise?: string;
    ville?: string;
    email?: string;
  }): Promise<Client[]> {
    const response = await this.api.get<Client[]>('/api/v1/clients/search', { params });
    return response.data;
  }

  async searchClientsByNom(nom: string): Promise<Client[]> {
    const response = await this.api.get<Client[]>('/api/v1/clients/search', { params: { nom } });
    return response.data;
  }

  async searchClientsByEntreprise(entreprise: string): Promise<Client[]> {
    const response = await this.api.get<Client[]>('/api/v1/clients/search', { params: { entreprise } });
    return response.data;
  }

  async searchClientsByVille(ville: string): Promise<Client[]> {
    const response = await this.api.get<Client[]>('/api/v1/clients/search', { params: { ville } });
    return response.data;
  }

  async searchClientsByEmail(email: string): Promise<Client[]> {
    const response = await this.api.get<Client[]>('/api/v1/clients/search', { params: { email } });
    return response.data;
  }

  async getClientsCount(): Promise<number> {
    const response = await this.api.get<number>('/api/v1/clients/count');
    return response.data;
  }

  // === CHANTIERS ===
  async getChantiers(): Promise<Chantier[]> {
    const response = await this.api.get<Chantier[]>('/api/v1/chantiers');
    return Array.isArray(response.data) ? response.data : [];
  }

  async getChantiersActifs(): Promise<Chantier[]> {
    const response = await this.api.get<Chantier[]>('/api/v1/chantiers/actifs');
    return Array.isArray(response.data) ? response.data : [];
  }

  async getChantier(id: string): Promise<Chantier> {
    const response = await this.api.get<Chantier>(`/api/v1/chantiers/${id}`);
    return response.data;
  }

  async createChantier(chantier: Partial<Chantier>): Promise<Chantier> {
    const response = await this.api.post<Chantier>('/api/v1/chantiers', chantier);
    return response.data;
  }

  async updateChantier(id: string, chantier: Partial<Chantier>): Promise<Chantier> {
    const response = await this.api.put<Chantier>(`/api/v1/chantiers/${id}`, chantier);
    return response.data;
  }

  async deleteChantier(id: string, permanent: boolean = false): Promise<void> {
    await this.api.delete(`/api/v1/chantiers/${id}`, {
      params: { permanent }
    });
  }

  async getChantiersByClient(clientId: string): Promise<Chantier[]> {
    try {
      const response = await this.api.get<Chantier[]>(`/api/v1/chantiers/client/${clientId}`);
      return response.data;
    } catch (error: any) {
      // Si l'endpoint n'existe pas encore côté backend (404)
      if (error.response?.status === 404) {
        console.debug(`Endpoint /api/v1/chantiers/client/${clientId} non implémenté, retour d'une liste vide`);
        // Retourner une liste vide en attendant l'implémentation backend
        return [];
      }
      // Relancer l'erreur pour les autres cas
      throw error;
    }
  }

  async getChantiersRecents(): Promise<ChantierRecent[]> {
    const response = await this.api.get<ChantierRecent[]>('/api/v1/chantiers/recent');
    return response.data;
  }

  // === DEVIS ===
  async getDevis(): Promise<Devis[]> {
    return CacheService.getOrSet(
      CacheKeys.DEVIS,
      async () => {
        const response = await this.api.get<Devis[]>('/api/v1/devis');
        return Array.isArray(response.data) ? response.data : [];
      },
      3 * 60 * 1000 // 3 minutes (plus court car données plus volatiles)
    );
  }

  async getDevisById(id: string): Promise<Devis> {
    const response = await this.api.get<Devis>(`/api/v1/devis/${id}`);
    return response.data;
  }

  async getDevisEnAttente(): Promise<DevisEnAttente[]> {
    const response = await this.api.get<DevisEnAttente[]>('/api/v1/devis/en-attente');
    return response.data;
  }

  async createDevis(devis: Partial<Devis>): Promise<Devis> {
    const response = await this.api.post<Devis>('/api/v1/devis', devis);
    // Invalider le cache des devis
    CacheService.delete(CacheKeys.DEVIS);
    CacheService.invalidatePattern('devis_.*');
    return response.data;
  }

  async updateDevis(id: string, devis: Partial<Devis>): Promise<Devis> {
    const response = await this.api.put<Devis>(`/api/v1/devis/${id}`, devis);
    // Invalider le cache des devis
    CacheService.delete(CacheKeys.DEVIS);
    CacheService.delete(CacheKeys.devisById(id));
    CacheService.invalidatePattern('devis_.*');
    return response.data;
  }

  async deleteDevis(id: string): Promise<void> {
    await this.api.delete(`/api/v1/devis/${id}`);
    // Invalider le cache des devis
    CacheService.delete(CacheKeys.DEVIS);
    CacheService.delete(CacheKeys.devisById(id));
    CacheService.invalidatePattern('devis_.*');
  }

  // === FACTURES ===
  async getFactures(): Promise<Facture[]> {
    return CacheService.getOrSet(
      CacheKeys.FACTURES,
      async () => {
        const response = await this.api.get<Facture[]>('/api/v1/factures');
        return Array.isArray(response.data) ? response.data : [];
      },
      3 * 60 * 1000 // 3 minutes
    );
  }

  async getFacture(id: string): Promise<Facture> {
    const response = await this.api.get<Facture>(`/api/v1/factures/${id}`);
    return response.data;
  }

  async getFacturesEnRetard(): Promise<FactureEnRetard[]> {
    const response = await this.api.get<FactureEnRetard[]>('/api/v1/factures/en-retard');
    return response.data;
  }

  async createFacture(facture: Partial<Facture>): Promise<Facture> {
    const response = await this.api.post<Facture>('/api/v1/factures', facture);
    // Invalider le cache des factures
    CacheService.delete(CacheKeys.FACTURES);
    CacheService.invalidatePattern('factures_.*');
    return response.data;
  }

  async updateFacture(id: string, facture: Partial<Facture>): Promise<Facture> {
    const response = await this.api.put<Facture>(`/api/v1/factures/${id}`, facture);
    // Invalider le cache des factures
    CacheService.delete(CacheKeys.FACTURES);
    CacheService.delete(CacheKeys.factureById(id));
    CacheService.invalidatePattern('factures_.*');
    return response.data;
  }

  async deleteFacture(id: string): Promise<void> {
    await this.api.delete(`/api/v1/factures/${id}`);
    // Invalider le cache des factures
    CacheService.delete(CacheKeys.FACTURES);
    CacheService.delete(CacheKeys.factureById(id));
    CacheService.invalidatePattern('factures_.*');
  }

  // === DASHBOARD ===
  async getDashboardStats(): Promise<DashboardStats> {
    const response = await this.api.get<DashboardStats>('/api/v1/dashboard/stats');
    return response.data;
  }

  // === HEALTH ===
  async getHealth(): Promise<{ status: string; timestamp: string }> {
    const response = await this.api.get('/api/v1/health');
    return response.data;
  }

  async getVersion(): Promise<{ version: string; environment: string }> {
    const response = await this.api.get('/api/v1/version');
    return response.data;
  }

  // === AUTH ===
  async getCurrentUser(): Promise<UserInfo> {
    const response = await this.api.get('/api/v1/auth/user');
    return response.data;
  }

  async getAuthStatus(): Promise<{ authenticated: boolean; principal: string | null; hasJWT: boolean; timestamp: number }> {
    const response = await this.api.get('/api/v1/auth/status');
    return response.data;
  }

  // === BUDGETS ===
  async getBudgets(params?: { search?: string; statut?: string; tendance?: string }) {
    const response = await this.api.get('/api/v1/budgets', { params });
    return response.data;
  }

  async getBudget(id: string) {
    const response = await this.api.get(`/api/v1/budgets/${id}`);
    return response.data;
  }

  async getBudgetByChantier(chantierId: string) {
    const response = await this.api.get(`/api/v1/budgets/chantier/${chantierId}`);
    return response.data;
  }

  async getBudgetsEnDepassement() {
    const response = await this.api.get('/api/v1/budgets/depassement');
    return response.data;
  }

  async getBudgetsNecessitantAttention() {
    const response = await this.api.get('/api/v1/budgets/attention');
    return response.data;
  }

  async createBudget(budget: any) {
    const response = await this.api.post('/api/v1/budgets', budget);
    return response.data;
  }

  async updateBudget(id: string, budget: any) {
    const response = await this.api.put(`/api/v1/budgets/${id}`, budget);
    return response.data;
  }

  async deleteBudget(id: string) {
    const response = await this.api.delete(`/api/v1/budgets/${id}`);
    return response.data;
  }

  async updateBudgetDepenses(id: string, depense: number) {
    const response = await this.api.put(`/api/v1/budgets/${id}/depenses`, { depense });
    return response.data;
  }

  async updateBudgetAvancement(id: string, avancement: number) {
    const response = await this.api.put(`/api/v1/budgets/${id}/avancement`, { avancement });
    return response.data;
  }

  async ajouterAlerteBudget(id: string, description: string) {
    const response = await this.api.post(`/api/v1/budgets/${id}/alertes`, { description });
    return response.data;
  }

  async supprimerAlertesBudget(id: string) {
    const response = await this.api.delete(`/api/v1/budgets/${id}/alertes`);
    return response.data;
  }

  // === EMPLOYÉS ===
  async getEmployes(): Promise<Employe[]> {
    const response = await this.api.get<Employe[]>('/api/v1/employes');
    return Array.isArray(response.data) ? response.data : [];
  }

  async getEmploye(id: string): Promise<Employe> {
    const response = await this.api.get<Employe>(`/api/v1/employes/${id}`);
    return response.data;
  }

  async createEmploye(employe: Partial<Employe>): Promise<Employe> {
    const response = await this.api.post<Employe>('/api/v1/employes', employe);
    return response.data;
  }

  async updateEmploye(id: string, employe: Partial<Employe>): Promise<Employe> {
    const response = await this.api.put<Employe>(`/api/v1/employes/${id}`, employe);
    return response.data;
  }

  async deleteEmploye(id: string): Promise<void> {
    await this.api.delete(`/api/v1/employes/${id}`);
  }

  async searchEmployes(params: {
    nom?: string;
    poste?: string;
    specialite?: string;
    statut?: string;
  }): Promise<Employe[]> {
    const response = await this.api.get<Employe[]>('/api/v1/employes/search', { params });
    return response.data;
  }

  async getEmployesDisponibles(dateDebut?: string, dateFin?: string): Promise<Employe[]> {
    const response = await this.api.get<Employe[]>('/api/v1/employes/disponibles', {
      params: { dateDebut, dateFin }
    });
    return response.data;
  }

  async getEmployesByEquipe(equipeId: string): Promise<Employe[]> {
    const response = await this.api.get<Employe[]>(`/api/v1/employes/by-equipe/${equipeId}`);
    return response.data;
  }

  async getEmployesCount(): Promise<number> {
    const response = await this.api.get<number>('/api/v1/employes/count');
    return response.data;
  }

  async getEmployesStats(): Promise<any> {
    const response = await this.api.get('/api/v1/employes/stats');
    return response.data;
  }

  // === ÉQUIPES ===
  async getEquipes(): Promise<Equipe[]> {
    const response = await this.api.get<Equipe[]>('/api/v1/equipes');
    return Array.isArray(response.data) ? response.data : [];
  }

  async getEquipe(id: string): Promise<Equipe> {
    const response = await this.api.get<Equipe>(`/api/v1/equipes/${id}`);
    return response.data;
  }

  async createEquipe(equipe: Partial<Equipe>): Promise<Equipe> {
    const response = await this.api.post<Equipe>('/api/v1/equipes', equipe);
    return response.data;
  }

  async updateEquipe(id: string, equipe: Partial<Equipe>): Promise<Equipe> {
    const response = await this.api.put<Equipe>(`/api/v1/equipes/${id}`, equipe);
    return response.data;
  }

  async deleteEquipe(id: string): Promise<void> {
    await this.api.delete(`/api/v1/equipes/${id}`);
  }

  async searchEquipes(params: {
    nom?: string;
    specialite?: string;
    statut?: string;
  }): Promise<Equipe[]> {
    const response = await this.api.get<Equipe[]>('/api/v1/equipes/search', { params });
    return response.data;
  }

  async getEquipesDisponibles(dateDebut?: string, dateFin?: string): Promise<Equipe[]> {
    const response = await this.api.get<Equipe[]>('/api/v1/equipes/disponibles', {
      params: { dateDebut, dateFin }
    });
    return response.data;
  }

  async getMembresEquipe(equipeId: string): Promise<Employe[]> {
    const response = await this.api.get<Employe[]>(`/api/v1/equipes/${equipeId}/membres`);
    return response.data;
  }

  async ajouterMembreEquipe(equipeId: string, employeId: string): Promise<void> {
    await this.api.post(`/api/v1/equipes/${equipeId}/membres/${employeId}`);
  }

  async retirerMembreEquipe(equipeId: string, employeId: string): Promise<void> {
    await this.api.delete(`/api/v1/equipes/${equipeId}/membres/${employeId}`);
  }

  async getEquipesCount(): Promise<number> {
    const response = await this.api.get<number>('/api/v1/equipes/count');
    return response.data;
  }

  async getEquipesStats(): Promise<any> {
    const response = await this.api.get('/api/v1/equipes/stats');
    return response.data;
  }

  // === MATÉRIELS ===
  async getMateriels(): Promise<Materiel[]> {
    const response = await this.api.get<Materiel[]>('/api/v1/materiels');
    return Array.isArray(response.data) ? response.data : [];
  }

  async getMateriel(id: string): Promise<Materiel> {
    const response = await this.api.get<Materiel>(`/api/v1/materiels/${id}`);
    return response.data;
  }

  async createMateriel(materiel: Partial<Materiel>): Promise<Materiel> {
    const response = await this.api.post<Materiel>('/api/v1/materiels', materiel);
    return response.data;
  }

  async updateMateriel(id: string, materiel: Partial<Materiel>): Promise<Materiel> {
    const response = await this.api.put<Materiel>(`/api/v1/materiels/${id}`, materiel);
    return response.data;
  }

  async deleteMateriel(id: string): Promise<void> {
    await this.api.delete(`/api/v1/materiels/${id}`);
  }

  async searchMateriels(params: {
    nom?: string;
    type?: string;
    marque?: string;
    statut?: string;
    localisation?: string;
  }): Promise<Materiel[]> {
    const response = await this.api.get<Materiel[]>('/api/v1/materiels/search', { params });
    return response.data;
  }

  async getMaterielsDisponibles(dateDebut?: string, dateFin?: string, type?: string): Promise<Materiel[]> {
    const response = await this.api.get<Materiel[]>('/api/v1/materiels/disponibles', {
      params: { dateDebut, dateFin, type }
    });
    return response.data;
  }

  async getMaterielsMaintenancePrevue(jours: number = 30): Promise<Materiel[]> {
    const response = await this.api.get<Materiel[]>('/api/v1/materiels/maintenance-prevue', {
      params: { jours }
    });
    return response.data;
  }

  async getMaterielsByType(type: string): Promise<Materiel[]> {
    const response = await this.api.get<Materiel[]>(`/api/v1/materiels/by-type/${type}`);
    return response.data;
  }

  async reserverMateriel(id: string, dateDebut: string, dateFin: string): Promise<void> {
    await this.api.post(`/api/v1/materiels/${id}/reserve`, null, {
      params: { dateDebut, dateFin }
    });
  }

  async libererMateriel(id: string): Promise<void> {
    await this.api.post(`/api/v1/materiels/${id}/liberer`);
  }

  async getMaterielsCount(): Promise<number> {
    const response = await this.api.get<number>('/api/v1/materiels/count');
    return response.data;
  }

  async getMaterielsStats(): Promise<any> {
    const response = await this.api.get('/api/v1/materiels/stats');
    return response.data;
  }

  async getValeurTotaleMateriels(): Promise<number> {
    const response = await this.api.get<number>('/api/v1/materiels/valeur-totale');
    return response.data;
  }

  // === MAINTENANCES ===
  async getMaintenances(): Promise<MaintenanceMateriel[]> {
    const response = await this.api.get<MaintenanceMateriel[]>('/api/v1/maintenances');
    return Array.isArray(response.data) ? response.data : [];
  }

  async getMaintenance(id: string): Promise<MaintenanceMateriel> {
    const response = await this.api.get<MaintenanceMateriel>(`/api/v1/maintenances/${id}`);
    return response.data;
  }

  async createMaintenance(maintenance: Partial<MaintenanceMateriel>): Promise<MaintenanceMateriel> {
    const response = await this.api.post<MaintenanceMateriel>('/api/v1/maintenances', maintenance);
    return response.data;
  }

  async updateMaintenance(id: string, maintenance: Partial<MaintenanceMateriel>): Promise<MaintenanceMateriel> {
    const response = await this.api.put<MaintenanceMateriel>(`/api/v1/maintenances/${id}`, maintenance);
    return response.data;
  }

  async deleteMaintenance(id: string): Promise<void> {
    await this.api.delete(`/api/v1/maintenances/${id}`);
  }

  async getMaintenancesByMateriel(materielId: string): Promise<MaintenanceMateriel[]> {
    const response = await this.api.get<MaintenanceMateriel[]>(`/api/v1/maintenances/by-materiel/${materielId}`);
    return response.data;
  }

  // === PLANNING ===
  async getPlanningEvents(params?: {
    dateDebut?: string;
    dateFin?: string;
    type?: string;
    statut?: string;
  }): Promise<PlanningEvent[]> {
    const response = await this.api.get<PlanningEvent[]>('/api/v1/planning/events', { params });
    return Array.isArray(response.data) ? response.data : [];
  }

  async getPlanningEvent(id: string): Promise<PlanningEvent> {
    const response = await this.api.get<PlanningEvent>(`/api/v1/planning/events/${id}`);
    return response.data;
  }

  async createPlanningEvent(event: Partial<PlanningEvent>): Promise<PlanningEvent> {
    const response = await this.api.post<PlanningEvent>('/api/v1/planning/events', event);
    return response.data;
  }

  async updatePlanningEvent(id: string, event: Partial<PlanningEvent>): Promise<PlanningEvent> {
    const response = await this.api.put<PlanningEvent>(`/api/v1/planning/events/${id}`, event);
    return response.data;
  }

  async deletePlanningEvent(id: string): Promise<void> {
    await this.api.delete(`/api/v1/planning/events/${id}`);
  }

  async getCalendrierView(annee: number, mois: number): Promise<PlanningCalendrierView> {
    const response = await this.api.get<PlanningCalendrierView>('/api/v1/planning/calendrier', {
      params: { annee, mois }
    });
    return response.data;
  }

  async detecterConflitsPlanification(dateDebut?: string, dateFin?: string): Promise<PlanningConflict[]> {
    const response = await this.api.get<PlanningConflict[]>('/api/v1/planning/conflits', {
      params: { dateDebut, dateFin }
    });
    return response.data;
  }

  async getPlanningEmploye(employeId: string, dateDebut?: string, dateFin?: string): Promise<PlanningEvent[]> {
    const response = await this.api.get<PlanningEvent[]>(`/api/v1/planning/employe/${employeId}`, {
      params: { dateDebut, dateFin }
    });
    return response.data;
  }

  async getPlanningEquipe(equipeId: string, dateDebut?: string, dateFin?: string): Promise<PlanningEvent[]> {
    const response = await this.api.get<PlanningEvent[]>(`/api/v1/planning/equipe/${equipeId}`, {
      params: { dateDebut, dateFin }
    });
    return response.data;
  }

  async getPlanningMateriel(materielId: string, dateDebut?: string, dateFin?: string): Promise<PlanningEvent[]> {
    const response = await this.api.get<PlanningEvent[]>(`/api/v1/planning/materiel/${materielId}`, {
      params: { dateDebut, dateFin }
    });
    return response.data;
  }

  async assignEmployesToEvent(eventId: string, employeIds: string[]): Promise<void> {
    await this.api.post(`/api/v1/planning/events/${eventId}/assign-employes`, employeIds);
  }

  async assignMaterielsToEvent(eventId: string, materielIds: string[]): Promise<void> {
    await this.api.post(`/api/v1/planning/events/${eventId}/assign-materiels`, materielIds);
  }

  async getPlanningStats(): Promise<PlanningStats> {
    const response = await this.api.get<PlanningStats>('/api/v1/planning/stats');
    return response.data;
  }

  async getTauxOccupation(dateDebut?: string, dateFin?: string): Promise<any> {
    const response = await this.api.get('/api/v1/planning/occupation', {
      params: { dateDebut, dateFin }
    });
    return response.data;
  }

  // === TEST ===
  async testCreateChantier(chantier: any): Promise<string> {
    const response = await this.api.post('/api/v1/test/chantier', chantier);
    return response.data;
  }
}

// Instance singleton
export const apiService = new ApiService();

// Services spécialisés
export const clientService = {
  getAll: () => apiService.getClients(),
  getById: (id: string) => apiService.getClient(id),
  create: (client: Partial<Client>) => apiService.createClient(client),
  update: (id: string, client: Partial<Client>) => apiService.updateClient(id, client),
  delete: (id: string) => apiService.deleteClient(id),
  search: (params: any) => apiService.searchClients(params),
  searchByNom: (nom: string) => apiService.searchClientsByNom(nom),
  searchByEntreprise: (entreprise: string) => apiService.searchClientsByEntreprise(entreprise),
  searchByVille: (ville: string) => apiService.searchClientsByVille(ville),
  searchByEmail: (email: string) => apiService.searchClientsByEmail(email),
  count: () => apiService.getClientsCount(),
};

export const chantierService = {
  getAll: () => apiService.getChantiers(),
  getAllActive: () => apiService.getChantiersActifs(),
  getById: (id: string) => apiService.getChantier(id),
  create: (chantier: Partial<Chantier>) => apiService.createChantier(chantier),
  update: (id: string, chantier: Partial<Chantier>) => apiService.updateChantier(id, chantier),
  delete: (id: string, permanent: boolean = false) => apiService.deleteChantier(id, permanent),
  getByClient: (clientId: string) => apiService.getChantiersByClient(clientId),
  getRecents: () => apiService.getChantiersRecents(),
};

export const devisService = {
  getAll: () => apiService.getDevis(),
  getById: (id: string) => apiService.getDevisById(id),
  getEnAttente: () => apiService.getDevisEnAttente(),
  create: (devis: Partial<Devis>) => apiService.createDevis(devis),
  update: (id: string, devis: Partial<Devis>) => apiService.updateDevis(id, devis),
  delete: (id: string) => apiService.deleteDevis(id),
};

export const factureService = {
  getAll: () => apiService.getFactures(),
  getById: (id: string) => apiService.getFacture(id),
  getEnRetard: () => apiService.getFacturesEnRetard(),
  create: (facture: Partial<Facture>) => apiService.createFacture(facture),
  update: (id: string, facture: Partial<Facture>) => apiService.updateFacture(id, facture),
  delete: (id: string) => apiService.deleteFacture(id),
};

export const dashboardService = {
  getStats: () => apiService.getDashboardStats(),
};

export const employeService = {
  getAll: () => apiService.getEmployes(),
  getById: (id: string) => apiService.getEmploye(id),
  create: (employe: Partial<Employe>) => apiService.createEmploye(employe),
  update: (id: string, employe: Partial<Employe>) => apiService.updateEmploye(id, employe),
  delete: (id: string) => apiService.deleteEmploye(id),
  search: (params: any) => apiService.searchEmployes(params),
  getDisponibles: (dateDebut?: string, dateFin?: string) => apiService.getEmployesDisponibles(dateDebut, dateFin),
  getByEquipe: (equipeId: string) => apiService.getEmployesByEquipe(equipeId),
  count: () => apiService.getEmployesCount(),
  getStats: () => apiService.getEmployesStats(),
};

export const equipeService = {
  getAll: () => apiService.getEquipes(),
  getById: (id: string) => apiService.getEquipe(id),
  create: (equipe: Partial<Equipe>) => apiService.createEquipe(equipe),
  update: (id: string, equipe: Partial<Equipe>) => apiService.updateEquipe(id, equipe),
  delete: (id: string) => apiService.deleteEquipe(id),
  search: (params: any) => apiService.searchEquipes(params),
  getDisponibles: (dateDebut?: string, dateFin?: string) => apiService.getEquipesDisponibles(dateDebut, dateFin),
  getMembres: (equipeId: string) => apiService.getMembresEquipe(equipeId),
  ajouterMembre: (equipeId: string, employeId: string) => apiService.ajouterMembreEquipe(equipeId, employeId),
  retirerMembre: (equipeId: string, employeId: string) => apiService.retirerMembreEquipe(equipeId, employeId),
  count: () => apiService.getEquipesCount(),
  getStats: () => apiService.getEquipesStats(),
};

export const materielService = {
  getAll: () => apiService.getMateriels(),
  getById: (id: string) => apiService.getMateriel(id),
  create: (materiel: Partial<Materiel>) => apiService.createMateriel(materiel),
  update: (id: string, materiel: Partial<Materiel>) => apiService.updateMateriel(id, materiel),
  delete: (id: string) => apiService.deleteMateriel(id),
  search: (params: any) => apiService.searchMateriels(params),
  getDisponibles: (dateDebut?: string, dateFin?: string, type?: string) => apiService.getMaterielsDisponibles(dateDebut, dateFin, type),
  getMaintenancePrevue: (jours?: number) => apiService.getMaterielsMaintenancePrevue(jours),
  getByType: (type: string) => apiService.getMaterielsByType(type),
  reserver: (id: string, dateDebut: string, dateFin: string) => apiService.reserverMateriel(id, dateDebut, dateFin),
  liberer: (id: string) => apiService.libererMateriel(id),
  count: () => apiService.getMaterielsCount(),
  getStats: () => apiService.getMaterielsStats(),
  getValeurTotale: () => apiService.getValeurTotaleMateriels(),
};

export const budgetService = {
  getAll: (params?: { search?: string; statut?: string; tendance?: string }) => apiService.getBudgets(params),
  getById: (id: string) => apiService.getBudget(id),
  getByChantier: (chantierId: string) => apiService.getBudgetByChantier(chantierId),
  getEnDepassement: () => apiService.getBudgetsEnDepassement(),
  getNecessitantAttention: () => apiService.getBudgetsNecessitantAttention(),
  create: (budget: any) => apiService.createBudget(budget),
  update: (id: string, budget: any) => apiService.updateBudget(id, budget),
  delete: (id: string) => apiService.deleteBudget(id),
  updateDepenses: (id: string, depense: number) => apiService.updateBudgetDepenses(id, depense),
  updateAvancement: (id: string, avancement: number) => apiService.updateBudgetAvancement(id, avancement),
  ajouterAlerte: (id: string, description: string) => apiService.ajouterAlerteBudget(id, description),
  supprimerAlertes: (id: string) => apiService.supprimerAlertesBudget(id),
};

export const maintenanceService = {
  getAll: () => apiService.getMaintenances(),
  getById: (id: string) => apiService.getMaintenance(id),
  create: (maintenance: Partial<MaintenanceMateriel>) => apiService.createMaintenance(maintenance),
  update: (id: string, maintenance: Partial<MaintenanceMateriel>) => apiService.updateMaintenance(id, maintenance),
  delete: (id: string) => apiService.deleteMaintenance(id),
  getByMateriel: (materielId: string) => apiService.getMaintenancesByMateriel(materielId),
};

export const planningService = {
  getEvents: (params?: any) => apiService.getPlanningEvents(params),
  getEvent: (id: string) => apiService.getPlanningEvent(id),
  createEvent: (event: Partial<PlanningEvent>) => apiService.createPlanningEvent(event),
  updateEvent: (id: string, event: Partial<PlanningEvent>) => apiService.updatePlanningEvent(id, event),
  deleteEvent: (id: string) => apiService.deletePlanningEvent(id),
  getCalendrierView: (annee: number, mois: number) => apiService.getCalendrierView(annee, mois),
  detecterConflits: (dateDebut?: string, dateFin?: string) => apiService.detecterConflitsPlanification(dateDebut, dateFin),
  getPlanningEmploye: (employeId: string, dateDebut?: string, dateFin?: string) => apiService.getPlanningEmploye(employeId, dateDebut, dateFin),
  getPlanningEquipe: (equipeId: string, dateDebut?: string, dateFin?: string) => apiService.getPlanningEquipe(equipeId, dateDebut, dateFin),
  getPlanningMateriel: (materielId: string, dateDebut?: string, dateFin?: string) => apiService.getPlanningMateriel(materielId, dateDebut, dateFin),
  assignEmployes: (eventId: string, employeIds: string[]) => apiService.assignEmployesToEvent(eventId, employeIds),
  assignMateriels: (eventId: string, materielIds: string[]) => apiService.assignMaterielsToEvent(eventId, materielIds),
  getStats: () => apiService.getPlanningStats(),
  getTauxOccupation: (dateDebut?: string, dateFin?: string) => apiService.getTauxOccupation(dateDebut, dateFin),
};

// Service pour les types de chantier
// TODO: Implement proper methods in ApiService class
export const typeChantierService = {
  getAll: () => Promise.resolve([]),
  getByCategorie: () => Promise.resolve([]),
  getById: (id: string) => Promise.resolve(null),
  getByCode: (code: string) => Promise.resolve(null),
  create: (typeChantier: any) => Promise.resolve(typeChantier),
  update: (id: string, typeChantier: any) => Promise.resolve(typeChantier),
  delete: (id: string) => Promise.resolve(true),
  reactivate: (id: string) => Promise.resolve(true),
  getStatistiques: () => Promise.resolve({}),
};

export default apiService;