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 financières
 */
@Injectable()
export class FinanceService {

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

  // Observables publics
  public loading$ = this.loadingSubject.asObservable();
  public transactions$ = this.transactionsSubject.asObservable();
  public soldes$ = this.soldesSubject.asObservable();

  // Cache local
  private transactionsCache: any[] = [];
  private soldesCache: 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 transactions
   */
  getTransactions(): Observable<any[]> {
    if (this.isCacheValid() && this.transactionsCache.length > 0) {
      return this.transactions$;
    }
    return this.loadTransactions();
  }

  /**
   * Récupère les soldes
   */
  getSoldes(): Observable<any[]> {
    if (this.isCacheValid() && this.soldesCache.length > 0) {
      return this.soldes$;
    }
    return this.loadSoldes();
  }

  /**
   * Charge les transactions
   */
  loadTransactions(): 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.generateTransactionsTestData();
          this.transactionsCache = testData;
          this.lastUpdate = Date.now();
          this.transactionsSubject.next(testData);
          observer.next(testData);
          observer.complete();
          this.loadingSubject.next(false);
        }, 800);
      });
    }

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

  /**
   * Charge les soldes
   */
  loadSoldes(): 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.generateSoldesTestData();
          this.soldesCache = testData;
          this.lastUpdate = Date.now();
          this.soldesSubject.next(testData);
          observer.next(testData);
          observer.complete();
          this.loadingSubject.next(false);
        }, 600);
      });
    }

    return this.estairService.getAll('soldes').pipe(
      tap(data => {
        this.soldesCache = data;
        this.lastUpdate = Date.now();
        this.soldesSubject.next(data);
      }),
      catchError(error => {
        console.error('Erreur lors du chargement des soldes:', error);
        const testData = this.generateSoldesTestData();
        this.soldesCache = testData;
        this.soldesSubject.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 transactions
   */
  private generateTransactionsTestData(): any[] {
    return [
      {
        id: 1,
        uuid: 'txn-001',
        account_name: 'Agence Voyage Plus',
        type: 'credit',
        amount: 1500.00,
        description: 'Paiement commission billets',
        reference: 'COM-2024-001',
        date: new Date('2024-01-20'),
        status: 'completed',
        bank_name: 'Banque Atlantique',
        created_at: new Date('2024-01-20')
      },
      {
        id: 2,
        uuid: 'txn-002',
        account_name: 'Travel Express SARL',
        type: 'debit',
        amount: -850.25,
        description: 'Débit commission service',
        reference: 'DEB-2024-002',
        date: new Date('2024-01-21'),
        status: 'pending',
        bank_name: 'BCEAO',
        created_at: new Date('2024-01-21')
      },
      {
        id: 3,
        uuid: 'txn-003',
        account_name: 'Mondial Tours',
        type: 'transfer',
        amount: 2200.00,
        description: 'Virement approvisionnement',
        reference: 'VIR-2024-003',
        date: new Date('2024-01-22'),
        status: 'completed',
        bank_name: 'Ecobank',
        created_at: new Date('2024-01-22')
      },
      {
        id: 4,
        uuid: 'txn-004',
        account_name: 'Agence Voyage Plus',
        type: 'credit',
        amount: 750.50,
        description: 'Remboursement annulation',
        reference: 'RMB-2024-004',
        date: new Date('2024-01-23'),
        status: 'completed',
        bank_name: 'Banque Atlantique',
        created_at: new Date('2024-01-23')
      }
    ];
  }

  /**
   * Génère des données de test pour les soldes
   */
  private generateSoldesTestData(): any[] {
    return [
      {
        id: 1,
        account_name: 'Agence Voyage Plus',
        balance: 12450.75,
        credit_limit: 15000.00,
        available: 2549.25,
        outstanding: 8500.00,
        last_update: new Date('2024-01-24'),
        status: 'active'
      },
      {
        id: 2,
        account_name: 'Travel Express SARL',
        balance: 8750.20,
        credit_limit: 10000.00,
        available: 1249.80,
        outstanding: 3200.00,
        last_update: new Date('2024-01-24'),
        status: 'active'
      },
      {
        id: 3,
        account_name: 'Mondial Tours',
        balance: -1250.00,
        credit_limit: 5000.00,
        available: 3750.00,
        outstanding: 6250.00,
        last_update: new Date('2024-01-23'),
        status: 'warning'
      },
      {
        id: 4,
        account_name: 'Safari Adventures',
        balance: 25600.00,
        credit_limit: 30000.00,
        available: 4400.00,
        outstanding: 0.00,
        last_update: new Date('2024-01-24'),
        status: 'active'
      }
    ];
  }

  /**
   * Rafraîchit les données
   */
  refreshData(): void {
    this.invalidateCache();
    this.loadTransactions().subscribe();
    this.loadSoldes().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.transactionsCache = [];
    this.soldesCache = [];
  }

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


