import { Component, inject, OnInit, Input, Output, EventEmitter, ChangeDetectorRef, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgIcon } from '@ng-icons/core';
import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
import { Subject, takeUntil } from 'rxjs';

import { 
  Subscription,
  SubscriptionPayment,
  SubscriptionStatus,
  SubscriptionPeriodicity,
  Currency
} from '@core/models/dcb-bo-hub-subscription.model';

import { SubscriptionsService } from '../subscriptions.service';
import { AuthService } from '@core/services/auth.service';

@Component({
  selector: 'app-subscription-payments',
  standalone: true,
  imports: [CommonModule, FormsModule, NgIcon, NgbAlertModule],
  templateUrl: './subscription-payments.html',
  styles: [`
    .avatar-lg {
      width: 80px;
      height: 80px;
    }
    .fs-24 {
      font-size: 24px;
    }
  `]
})
export class SubscriptionPayments implements OnInit, OnDestroy {
  private subscriptionsService = inject(SubscriptionsService);
  private authService = inject(AuthService);
  private cdRef = inject(ChangeDetectorRef);
  private destroy$ = new Subject<void>();

  readonly SubscriptionStatus = SubscriptionStatus;
  readonly SubscriptionPeriodicity = SubscriptionPeriodicity;
  readonly Currency = Currency;

  @Input() subscriptionId!: string;
  @Output() back = new EventEmitter<void>();

  subscription: Subscription | null = null;
  payments: SubscriptionPayment[] = [];
  loading = false;
  loadingPayments = false;
  error = '';
  success = '';

  // Gestion des permissions
  currentUserRole: string | null = null;
  
  merchantPartnerId: number | undefined;
  
  // Filtres
  statusFilter: 'all' | 'SUCCESS' | 'FAILED' | 'PENDING' = 'all';
  dateFilter: 'all' | 'week' | 'month' | 'quarter' = 'all';

  ngOnInit() {
    if (this.subscriptionId) {
      this.loadCurrentUserPermissions();
      this.loadSubscriptionDetails();
    }
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  /**
   * Charge les permissions de l'utilisateur courant
   */
  private loadCurrentUserPermissions(): void {
    this.authService.getUserProfile()
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (profile) => {
          this.currentUserRole = this.authService.getCurrentUserRole();
          this.cdRef.detectChanges();
        },
        error: (error) => {
          console.error('Error loading user permissions:', error);
        }
      });
  }

  /**
   * Charge les détails de l'abonnement puis les paiements
   */
  loadSubscriptionDetails() {
    this.loading = true;
    this.error = '';

    this.subscriptionsService.getSubscriptionById(this.subscriptionId)
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (subscription) => {
          console.log('Subscription loaded:', {
            id: subscription.id,
            merchantPartnerId: subscription.merchantPartnerId,
            hasMerchantId: !!subscription.merchantPartnerId
          });

          this.merchantPartnerId = subscription.merchantPartnerId,

          console.log("loadSubscriptionDetails " + this.merchantPartnerId);

          this.subscription = subscription;
          this.loading = false;
          this.cdRef.detectChanges();
          
          // Passer explicitement le merchantPartnerId à loadPayments
          this.loadPayments(subscription.merchantPartnerId);
        },
        error: (error) => {
          this.error = 'Erreur lors du chargement des détails de l\'abonnement';
          this.loading = false;
          this.cdRef.detectChanges(); 
          console.error('Error loading subscription details:', error);
        }
      });
  }

  /**
   * Charge les paiements de l'abonnement
   */
  loadPayments(merchantPartnerId: number | undefined) {
    this.loadingPayments = true;

    console.log("loadPayments " + merchantPartnerId);

    // Utiliser le merchantPartnerId passé en paramètre ou celui de l'abonnement
    const merchantId = merchantPartnerId;

    // Vérifier que nous avons les IDs nécessaires
    if (!merchantId) {
      console.error('MerchantPartnerId manquant pour charger les paiements');
      this.error = 'Impossible de charger les paiements : Merchant ID manquant';
      this.loadingPayments = false;
      this.cdRef.detectChanges();
      return;
    }

    console.log('Loading payments with:', {
      merchantId: merchantId,
      subscriptionId: this.subscriptionId,
      merchantIdType: typeof merchantId
    });

    this.subscriptionsService.getSubscriptionPayments(merchantId, this.subscriptionId)
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (response) => {
          this.payments = response.payments || [];
          this.loadingPayments = false;
          this.cdRef.detectChanges(); 
        },
        error: (error) => {
          console.error('Error loading subscription payments:', error);
          
          // Message d'erreur plus spécifique
          if (error.status === 400) {
            this.error = 'Données invalides pour charger les paiements';
          } else if (error.status === 404) {
            this.error = 'Aucun paiement trouvé pour cet abonnement';
          } else {
            this.error = 'Erreur lors du chargement des paiements';
          }
          
          this.loadingPayments = false;
          this.cdRef.detectChanges(); 
        }
      });
  }
  /**
   * Applique les filtres aux paiements
   */
  applyFilters() {
    this.loadPayments(this.merchantPartnerId); // Recharger avec les filtres actuels
  }

  /**
   * Réinitialise les filtres
   */
  clearFilters() {
    this.statusFilter = 'all';
    this.dateFilter = 'all';
    this.applyFilters();
  }

  // ==================== UTILITAIRES D'AFFICHAGE ====================

  getStatusBadgeClass(status: SubscriptionStatus): string {
    const statusClasses = {
      [SubscriptionStatus.ACTIVE]: 'badge bg-success',
      [SubscriptionStatus.SUSPENDED]: 'badge bg-warning',
      [SubscriptionStatus.CANCELLED]: 'badge bg-danger',
      [SubscriptionStatus.EXPIRED]: 'badge bg-secondary',
      [SubscriptionStatus.PENDING]: 'badge bg-info'
    };
    return statusClasses[status] || 'badge bg-secondary';
  }

  getStatusDisplayName(status: SubscriptionStatus): string {
    const statusNames = {
      [SubscriptionStatus.ACTIVE]: 'Actif',
      [SubscriptionStatus.SUSPENDED]: 'Suspendu',
      [SubscriptionStatus.CANCELLED]: 'Annulé',
      [SubscriptionStatus.EXPIRED]: 'Expiré',
      [SubscriptionStatus.PENDING]: 'En attente'
    };
    return statusNames[status] || status;
  }

  getPaymentStatusBadgeClass(status: string): string {
    const statusClasses: { [key: string]: string } = {
      'SUCCESS': 'badge bg-success',
      'FAILED': 'badge bg-danger',
      'PENDING': 'badge bg-warning'
    };
    return statusClasses[status] || 'badge bg-secondary';
  }

  getPaymentStatusDisplayName(status: string): string {
    const statusNames: { [key: string]: string } = {
      'SUCCESS': 'Réussi',
      'FAILED': 'Échoué',
      'PENDING': 'En attente'
    };
    return statusNames[status] || status;
  }

  getPeriodicityDisplayName(periodicity: SubscriptionPeriodicity): string {
    const periodicityNames = {
      [SubscriptionPeriodicity.DAILY]: 'Quotidien',
      [SubscriptionPeriodicity.WEEKLY]: 'Hebdomadaire',
      [SubscriptionPeriodicity.MONTHLY]: 'Mensuel',
      [SubscriptionPeriodicity.YEARLY]: 'Annuel'
    };
    return periodicityNames[periodicity] || periodicity;
  }

  formatAmount(amount: number, currency: Currency): string {
    return new Intl.NumberFormat('fr-FR', {
      style: 'currency',
      currency: currency
    }).format(amount);
  }

  formatDate(dateString: string): string {
    return new Date(dateString).toLocaleDateString('fr-FR', {
      year: 'numeric',
      month: 'short',
      day: 'numeric'
    });
  }

  formatDateTime(dateString: string): string {
    return new Date(dateString).toLocaleDateString('fr-FR', {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    });
  }

  // ==================== STATISTIQUES ====================

  getTotalPayments(): number {
    return this.payments.length;
  }

  getSuccessfulPayments(): number {
    return this.payments.filter(p => p.status === 'SUCCESS').length;
  }

  getFailedPayments(): number {
    return this.payments.filter(p => p.status === 'FAILED').length;
  }

  getPendingPayments(): number {
    return this.payments.filter(p => p.status === 'PENDING').length;
  }

  getTotalAmount(): number {
    return this.payments
      .filter(p => p.status === 'SUCCESS')
      .reduce((sum, p) => sum + p.amount, 0);
  }

  getSuccessRate(): number {
    if (this.payments.length === 0) return 0;
    return (this.getSuccessfulPayments() / this.payments.length) * 100;
  }

  // ==================== MÉTHODES DE NAVIGATION ====================

  goBack() {
    this.back.emit();
  }

  // ==================== MÉTHODES UTILITAIRES ====================

  refresh() {
    this.loadSubscriptionDetails();
    this.loadPayments(this.merchantPartnerId);
  }

  clearMessages() {
    this.error = '';
    this.success = '';
    this.cdRef.detectChanges();
  }

  // Méthodes pour le template
  getPageTitle(): string {
    return `Paiements - Abonnement #${this.subscription?.id || '...'}`;
  }

  getContextDescription(): string {
    return 'Historique des paiements pour cet abonnement';
  }

  // Calculer les jours jusqu'au prochain paiement
  getDaysUntilNextPayment(): number {
    if (!this.subscription?.nextPaymentDate) return 0;
    const nextPayment = new Date(this.subscription.nextPaymentDate);
    const today = new Date();
    const diffTime = nextPayment.getTime() - today.getTime();
    return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
  }

  // Vérifier si l'abonnement est sur le point d'expirer
  isExpiringSoon(): boolean {
    if (!this.subscription?.endDate) return false;
    const endDate = new Date(this.subscription.endDate);
    const today = new Date();
    const diffTime = endDate.getTime() - today.getTime();
    const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
    return diffDays <= 7 && diffDays > 0;
  }

  // Vérifier si l'abonnement est expiré
  isExpired(): boolean {
    if (!this.subscription?.endDate) return false;
    return new Date(this.subscription.endDate) < new Date();
  }

  // Obtenir les paiements filtrés
  getFilteredPayments(): SubscriptionPayment[] {
    let filtered = this.payments;

    // Filtrer par statut
    if (this.statusFilter !== 'all') {
      filtered = filtered.filter(p => p.status === this.statusFilter);
    }

    // Filtrer par date
    if (this.dateFilter !== 'all') {
      const now = new Date();
      let startDate = new Date();

      switch (this.dateFilter) {
        case 'week':
          startDate.setDate(now.getDate() - 7);
          break;
        case 'month':
          startDate.setMonth(now.getMonth() - 1);
          break;
        case 'quarter':
          startDate.setMonth(now.getMonth() - 3);
          break;
      }

      filtered = filtered.filter(p => new Date(p.createdAt) >= startDate);
    }

    return filtered;
  }

  // Trier les paiements par date (plus récents en premier)
  getSortedPayments(): SubscriptionPayment[] {
    return this.getFilteredPayments().sort((a, b) => 
      new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
    );
  }

  // Méthodes pour les indicateurs visuels
  getSubscriptionHealth(): 'good' | 'warning' | 'danger' {
    if (!this.subscription) return 'good';
    
    if (this.subscription.failureCount > 3) return 'danger';
    if (this.subscription.failureCount > 0 || this.isExpiringSoon()) return 'warning';
    return 'good';
  }

  getSubscriptionHealthIcon(): string {
    const health = this.getSubscriptionHealth();
    const icons = {
      'good': 'lucideCheckCircle',
      'warning': 'lucideAlertTriangle',
      'danger': 'lucideXCircle'
    };
    return icons[health];
  }

  getSubscriptionHealthColor(): string {
    const health = this.getSubscriptionHealth();
    const colors = {
      'good': 'text-success',
      'warning': 'text-warning',
      'danger': 'text-danger'
    };
    return colors[health];
  }

  // Gestion des erreurs
  private getErrorMessage(error: any): string {
    if (error.error?.message) {
      return error.error.message;
    }
    if (error.status === 400) {
      return 'Données invalides.';
    }
    if (error.status === 403) {
      return 'Vous n\'avez pas les permissions pour accéder à ces informations.';
    }
    if (error.status === 404) {
      return 'Abonnement ou paiements non trouvés.';
    }
    return 'Erreur lors de l\'opération. Veuillez réessayer.';
  }
}