import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { tap, catchError, finalize } from 'rxjs/operators';

// Core services
import { EstairService } from '../../../core/services/estair.service';
import { ChapsService } from '../../../core/services/chaps.service';

// Environment
import { environment } from '../../../../environments/environment';

/**
 * Service spécialisé pour la gestion des données billets
 */
@Injectable()
export class BilletsService {

  // État du service
  private loadingSubject = new BehaviorSubject<boolean>(false);
  private etatsdeventesSubject = new BehaviorSubject<any[]>([]);
  private pnrSubject = new BehaviorSubject<any[]>([]);

  // Observables publics
  public loading$ = this.loadingSubject.asObservable();
  public etatsdeventes$ = this.etatsdeventesSubject.asObservable();
  public pnr$ = this.pnrSubject.asObservable();

  // Cache local
  private etatsdeventesCache: any[] = [];
  private pnrCache: any[] = [];
  private lastUpdate: number = 0;
  private readonly CACHE_DURATION = 5 * 60 * 1000; // 5 minutes

  constructor(
    private estairService: EstairService,
    private chapsService: ChapsService
  ) {}

  /**
   * Récupère les états de ventes
   */
  getEtatsdeventes(): Observable<any[]> {
    if (this.isCacheValid() && this.etatsdeventesCache.length > 0) {
      return new Observable<any[]>(observer => {
        observer.next(this.etatsdeventesCache);
        observer.complete();
      });
    }
    return this.loadEtatsdeventes();
  }

  /**
   * Récupère les PNR
   */
  getPnr(): Observable<any[]> {
    if (this.isCacheValid() && this.pnrCache.length > 0) {
      return new Observable<any[]>(observer => {
        observer.next(this.pnrCache);
        observer.complete();
      });
    }
    return this.loadPnr();
  }

  /**
   * Charge les états de ventes
   */
  loadEtatsdeventes(): Observable<any[]> {
    this.loadingSubject.next(true);

    // En mode développement, utiliser des données de test
    if (!environment.production) {
      return new Observable<any[]>(observer => {
        setTimeout(() => {
          const testData = this.generateEtatsdeventesTestData();
          this.etatsdeventesCache = testData;
          this.lastUpdate = Date.now();
          this.etatsdeventesSubject.next(testData);
          observer.next(testData);
          observer.complete();
          this.loadingSubject.next(false);
        }, 1000);
      });
    }

    return this.estairService.getAll('etatsdeventes').pipe(
      tap(data => {
        this.etatsdeventesCache = data;
        this.lastUpdate = Date.now();
        this.etatsdeventesSubject.next(data);
      }),
      catchError(error => {
        console.error('Erreur lors du chargement des états de ventes:', error);
        const testData = this.generateEtatsdeventesTestData();
        this.etatsdeventesCache = testData;
        this.etatsdeventesSubject.next(testData);
        return new Observable<any[]>(observer => {
          observer.next(testData);
          observer.complete();
        });
      }),
      finalize(() => this.loadingSubject.next(false))
    );
  }

  /**
   * Charge les PNR
   */
  loadPnr(): Observable<any[]> {
    this.loadingSubject.next(true);

    // En mode développement, utiliser des données de test
    if (!environment.production) {
      return new Observable<any[]>(observer => {
        setTimeout(() => {
          const testData = this.generatePnrTestData();
          this.pnrCache = testData;
          this.lastUpdate = Date.now();
          this.pnrSubject.next(testData);
          observer.next(testData);
          observer.complete();
          this.loadingSubject.next(false);
        }, 800);
      });
    }

    return this.estairService.getAll('pnr').pipe(
      tap(data => {
        this.pnrCache = data;
        this.lastUpdate = Date.now();
        this.pnrSubject.next(data);
      }),
      catchError(error => {
        console.error('Erreur lors du chargement des PNR:', error);
        const testData = this.generatePnrTestData();
        this.pnrCache = testData;
        this.pnrSubject.next(testData);
        return new Observable<any[]>(observer => {
          observer.next(testData);
          observer.complete();
        });
      }),
      finalize(() => this.loadingSubject.next(false))
    );
  }

  /**
   * Génère des données de test pour les états de ventes
   */
  private generateEtatsdeventesTestData(): any[] {
    return [
      {
        id: 1,
        uuid: 'evt-001',
        pnr: 'ABC123',
        passenger_name: 'Jean Dupont',
        destination: 'Dakar → Paris',
        flight_date: new Date('2024-02-15'),
        amount: 450.75,
        commission: 45.08,
        tax: 67.61,
        status: 'issued',
        account_name: 'Agence Voyage Plus',
        created_at: new Date('2024-01-20'),
        updated_at: new Date('2024-01-20')
      },
      {
        id: 2,
        uuid: 'evt-002',
        pnr: 'DEF456',
        passenger_name: 'Marie Martin',
        destination: 'Abidjan → Londres',
        flight_date: new Date('2024-02-18'),
        amount: 680.50,
        commission: 68.05,
        tax: 102.08,
        status: 'pending',
        account_name: 'Travel Express SARL',
        created_at: new Date('2024-01-21'),
        updated_at: new Date('2024-01-21')
      },
      {
        id: 3,
        uuid: 'evt-003',
        pnr: 'GHI789',
        passenger_name: 'Ahmed Diallo',
        destination: 'Casablanca → Madrid',
        flight_date: new Date('2024-02-25'),
        amount: 320.25,
        commission: 32.03,
        tax: 48.04,
        status: 'cancelled',
        account_name: 'Mondial Tours',
        created_at: new Date('2024-01-22'),
        updated_at: new Date('2024-01-23')
      },
      {
        id: 4,
        uuid: 'evt-004',
        pnr: 'JKL012',
        passenger_name: 'Fatou Sow',
        destination: 'Bamako → Dubai',
        flight_date: new Date('2024-03-01'),
        amount: 890.00,
        commission: 89.00,
        tax: 133.50,
        status: 'issued',
        account_name: 'Agence Voyage Plus',
        created_at: new Date('2024-01-24'),
        updated_at: new Date('2024-01-24')
      }
    ];
  }

  /**
   * Génère des données de test pour les PNR
   */
  private generatePnrTestData(): any[] {
    return [
      {
        id: 1,
        uuid: 'pnr-001',
        code: 'ABC123',
        passenger_count: 1,
        main_passenger: 'Jean Dupont',
        departure: 'Dakar (DKR)',
        arrival: 'Paris (CDG)',
        departure_date: new Date('2024-02-15'),
        return_date: null,
        airline: 'Air France',
        flight_number: 'AF718',
        booking_class: 'Economy',
        total_amount: 450.75,
        status: 'confirmed',
        account_name: 'Agence Voyage Plus',
        created_at: new Date('2024-01-20'),
        updated_at: new Date('2024-01-20')
      },
      {
        id: 2,
        uuid: 'pnr-002',
        code: 'DEF456',
        passenger_count: 2,
        main_passenger: 'Marie Martin',
        departure: 'Abidjan (ABJ)',
        arrival: 'Londres (LHR)',
        departure_date: new Date('2024-02-18'),
        return_date: new Date('2024-02-25'),
        airline: 'British Airways',
        flight_number: 'BA081',
        booking_class: 'Business',
        total_amount: 680.50,
        status: 'pending',
        account_name: 'Travel Express SARL',
        created_at: new Date('2024-01-21'),
        updated_at: new Date('2024-01-21')
      },
      {
        id: 3,
        uuid: 'pnr-003',
        code: 'GHI789',
        passenger_count: 1,
        main_passenger: 'Ahmed Diallo',
        departure: 'Casablanca (CMN)',
        arrival: 'Madrid (MAD)',
        departure_date: new Date('2024-02-25'),
        return_date: null,
        airline: 'Royal Air Maroc',
        flight_number: 'AT950',
        booking_class: 'Economy',
        total_amount: 320.25,
        status: 'cancelled',
        account_name: 'Mondial Tours',
        created_at: new Date('2024-01-22'),
        updated_at: new Date('2024-01-23')
      }
    ];
  }

  /**
   * Rafraîchit les données
   */
  refreshData(): void {
    this.invalidateCache();
    this.loadEtatsdeventes().subscribe();
    this.loadPnr().subscribe();
  }

  /**
   * Vérifie si le cache est valide
   */
  private isCacheValid(): boolean {
    const age = Date.now() - this.lastUpdate;
    return age < this.CACHE_DURATION;
  }

  /**
   * Invalide le cache
   */
  private invalidateCache(): void {
    this.lastUpdate = 0;
    this.etatsdeventesCache = [];
    this.pnrCache = [];
  }

  /**
   * Nettoie le service
   */
  cleanup(): void {
    this.loadingSubject.complete();
    this.etatsdeventesSubject.complete();
    this.pnrSubject.complete();
  }
}


