import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { ReportsService } from '../../../core/services/reports.service';
import {
  DashboardResponse,
  ReportFilters,
  ReportCardData,
  DashboardAlert
} from '../../../core/models/reports.models';
import { MatDialog } from '@angular/material/dialog';
import { ToastService } from '../../../services/toast.service';

interface CardState {
  refreshing: boolean;
  refreshError: string | null;
  exporting: boolean;
  exportFormat: string | null;
}

@Component({
  selector: 'app-reports-dashboard',
  templateUrl: './reports-dashboard.component.html',
  styleUrls: ['./reports-dashboard.component.scss']
})
export class ReportsDashboardComponent implements OnInit {
  // Filtres
  filters: ReportFilters = {
    date_from: this.getDefaultDateFrom(),
    date_to: this.getDefaultDateTo()
  };

  // Données du dashboard
  dashboard: DashboardResponse | null = null;
  reports: ReportCardData[] = [];

  // États
  isLoading = false;
  error: string | null = null;

  // Stats badges pour les cartes du haut
  statsBadges: any[] = [];

  // État par carte (refresh/export)
  cardStates: Map<string, CardState> = new Map();

  // Panneau latéral de détails
  detailPanelVisible = false;
  selectedReportType: string | null = null;
  selectedReportTitle = '';

  // Configuration des rapports
  reportsConfig = [
    {
      type: 'banques_mouvements',
      title: 'Banques ↔ Mouvements',
      icon: 'account_balance',
      description: 'Dépôts et mouvements associés'
    },
    {
      type: 'financial_requests_mouvements',
      title: 'Req. Financières ↔ Mouvements',
      icon: 'request_quote',
      description: 'Requêtes et mouvements associés'
    },
    {
      type: 'etatsdeventes_mouvements',
      title: 'États de ventes ↔ Mouvements',
      icon: 'receipt_long',
      description: 'États de vente et mouvements'
    },
    {
      type: 'soldesbmp_soldes',
      title: 'Soldes BMP ↔ Soldes Estair',
      icon: 'account_balance_wallet',
      description: 'Cohérence des soldes'
    },
    {
      type: 'bmps_etatsdeventes',
      title: 'BMP ↔ États de ventes',
      icon: 'description',
      description: 'BMPs et états de vente'
    },
    {
      type: 'bspdetails_etatsdeventes',
      title: 'Bsp details ↔ États de ventes',
      icon: 'fact_check',
      description: 'Bsp details et états de vente'
    }
  ];

  constructor(
    private reportsService: ReportsService,
    private cdr: ChangeDetectorRef,
    private dialog: MatDialog,
    private toastService: ToastService
  ) {}

  ngOnInit(): void {
    console.log('📊 Initialisation du dashboard des rapports');

    // Initialiser les états par carte
    this.reportsConfig.forEach(config => {
      this.cardStates.set(config.type, {
        refreshing: false,
        refreshError: null,
        exporting: false,
        exportFormat: null
      });
    });

    this.loadDashboard();
  }

  /**
   * Charge le dashboard complet
   */
  async loadDashboard(): Promise<void> {
    this.isLoading = true;
    this.error = null;

    try {
      console.log('🔄 Chargement du dashboard avec les filtres:', this.filters);

      this.dashboard = await this.reportsService.getDashboard(this.filters).toPromise();

      // Convertir les rapports en tableau
      if (this.dashboard) {
        this.reports = Object.values(this.dashboard.reports);

        console.log('✅ Dashboard chargé:', {
          reports: this.reports.length,
          global_health: this.dashboard.global_health,
          alerts: this.dashboard.alerts?.length || 0
        });

        this.generateStatsBadges();
      }

    } catch (error: any) {
      console.error('❌ Erreur lors du chargement du dashboard:', error);
      this.error = error.message || 'Erreur lors du chargement des rapports';
    } finally {
      this.isLoading = false;
      this.cdr.markForCheck();
    }
  }

  /**
   * Rafraîchit le dashboard
   */
  refresh(): void {
    console.log('🔄 Rafraîchissement manuel du dashboard');
    this.loadDashboard();
  }

  /**
   * Applique les filtres et recharge
   */
  applyFilters(): void {
    console.log('🔍 Application des filtres:', this.filters);
    this.loadDashboard();
  }

  // ─── CTA 1 : Refresh Links ──────────────────────────────

  /**
   * Rafraîchit les liens pour un type de rapport spécifique
   */
  async refreshLinks(reportType: string): Promise<void> {
    const state = this.cardStates.get(reportType);
    if (!state || state.refreshing) return;

    state.refreshing = true;
    state.refreshError = null;
    this.cdr.markForCheck();

    try {
      console.log(`🔗 Rafraîchissement des liens pour ${reportType}`);
      await this.reportsService.refreshLinks(reportType, this.filters).toPromise();

      this.toastService.showSuccess(`Liens "${this.getReportTitleByType(reportType)}" recalculés avec succès`);

      // Recharger le dashboard pour voir les nouvelles données
      await this.reloadDashboard();

    } catch (error: any) {
      state.refreshError = error.message || 'Erreur lors du rafraîchissement';
      this.toastService.showError(`Échec du rafraîchissement: ${state.refreshError}`);
    } finally {
      state.refreshing = false;
      this.cdr.markForCheck();
    }
  }

  isCardRefreshing(reportType: string): boolean {
    return this.cardStates.get(reportType)?.refreshing || false;
  }

  canRefreshLinks(reportType: string): boolean {
    return this.reportsService.hasRefreshableLinks(reportType);
  }

  // ─── CTA 2 : View Details (Side Panel) ──────────────────

  /**
   * Ouvre les détails d'un rapport dans le panneau latéral
   */
  viewReportDetails(reportType: string): void {
    console.log('📋 Ouverture du panneau détaillé pour:', reportType);
    this.selectedReportType = reportType;
    this.selectedReportTitle = this.getReportTitleByType(reportType);
    this.detailPanelVisible = true;
  }

  /**
   * Ferme le panneau de détails
   */
  closeDetailPanel(): void {
    this.detailPanelVisible = false;
    this.selectedReportType = null;
  }

  // ─── CTA 3 : Export ─────────────────────────────────────

  /**
   * Exporte un rapport
   */
  async exportReport(reportType: string, format: 'csv' | 'excel'): Promise<void> {
    const state = this.cardStates.get(reportType);
    if (state) {
      state.exporting = true;
      state.exportFormat = format;
    }
    this.cdr.markForCheck();

    try {
      console.log(`📥 Export du rapport ${reportType} en ${format}`);

      const responseBlob = await this.reportsService.exportReport(reportType, format, this.filters).toPromise();

      if (responseBlob) {
        // Vérifier si la réponse est une erreur JSON déguisée en blob
        if (responseBlob.type === 'application/json' || responseBlob.size < 100) {
          const text = await responseBlob.text();
          try {
            const json = JSON.parse(text);
            throw new Error(json.message || json.detail || 'Erreur serveur lors de l\'export');
          } catch (e) {
            if (e instanceof SyntaxError) {
              // Pas du JSON, on continue
            } else {
              throw e;
            }
          }
        }

        // Forcer le bon type MIME
        const mimeType = format === 'excel'
          ? 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
          : 'text/csv;charset=utf-8';
        const typedBlob = new Blob([responseBlob], { type: mimeType });

        const url = window.URL.createObjectURL(typedBlob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `rapport_${reportType}_${this.filters.date_from}_${this.filters.date_to}.${format === 'excel' ? 'xlsx' : format}`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        window.URL.revokeObjectURL(url);

        this.toastService.showSuccess(`Export ${format.toUpperCase()} téléchargé`);
      }
    } catch (error) {
      console.error('❌ Erreur lors de l\'export:', error);
      this.toastService.showError('Erreur lors de l\'export du rapport');
    } finally {
      if (state) {
        state.exporting = false;
        state.exportFormat = null;
      }
      this.cdr.markForCheck();
    }
  }

  isCardExporting(reportType: string): boolean {
    return this.cardStates.get(reportType)?.exporting || false;
  }

  /**
   * Gère l'export demandé depuis le panneau de détails
   */
  onPanelExportRequested(event: { reportType: string; format: 'csv' | 'excel' }): void {
    this.exportReport(event.reportType, event.format);
  }

  // ─── Méthodes utilitaires ───────────────────────────────

  /**
   * Recharge les données du dashboard (après un refresh de liens)
   */
  private async reloadDashboard(): Promise<void> {
    try {
      const dashboard = await this.reportsService.getDashboard(this.filters).toPromise();
      if (dashboard) {
        this.dashboard = dashboard;
        this.reports = Object.values(this.dashboard.reports);
        this.generateStatsBadges();
      }
    } catch (error) {
      console.error('❌ Erreur rechargement dashboard:', error);
    }
  }

  private getReportTitleByType(reportType: string): string {
    const config = this.reportsConfig.find(c => c.type === reportType);
    return config?.title || reportType;
  }

  /**
   * Génère les badges de statistiques à partir des données du dashboard
   */
  generateStatsBadges(): void {
    if (!this.dashboard) {
      this.statsBadges = [];
      return;
    }

    const totalReports = this.reports.reduce((sum, r) => sum + this.getReportTotal(r), 0);
    const totalUnmatched = this.reports.reduce((sum, r) => sum + this.getReportUnmatched(r), 0);
    const avgMatch = this.reports.length > 0
      ? this.reports.reduce((sum, r) => sum + (r.matched_percentage || 0), 0) / this.reports.length
      : 0;

    this.statsBadges = [
      {
        title: 'Rapports Analysés',
        value: this.reports.length,
        trend: 'stable',
        variation: `${this.reports.length} types`
      },
      {
        title: 'Santé Globale',
        value: (this.dashboard.global_health.score || 0).toFixed(1) + '%',
        trend: this.dashboard.global_health.status === 'good' ? 'up' : this.dashboard.global_health.status === 'warning' ? 'stable' : 'down',
        variation: this.dashboard.global_health.status === 'good' ? 'Excellent' : this.dashboard.global_health.status === 'warning' ? 'Attention' : 'Critique'
      },
      {
        title: 'Alertes',
        value: this.dashboard.alerts?.length || 0,
        trend: (this.dashboard.alerts?.length || 0) > 0 ? 'down' : 'up',
        variation: (this.dashboard.alerts?.length || 0) === 0 ? 'Aucune' : `${this.dashboard.alerts.length} active(s)`
      },
      {
        title: 'Moyenne',
        value: avgMatch.toFixed(1) + '%',
        trend: avgMatch >= 90 ? 'up' : avgMatch >= 70 ? 'stable' : 'down',
        variation: `${totalReports - totalUnmatched}/${totalReports} appariés`
      }
    ];
  }

  trackByBadge(index: number, badge: any): string {
    return badge.title + badge.value;
  }

  /**
   * Retourne la couleur selon le statut de santé
   */
  getHealthColor(status: string): string {
    switch (status) {
      case 'good': return '#28a745';
      case 'warning': return '#ffc107';
      case 'critical': return '#dc3545';
      default: return '#6c757d';
    }
  }

  /**
   * Calcule le stroke-dasharray pour la jauge SVG circulaire
   */
  getGaugeDashArray(score: number): string {
    const circumference = 2 * Math.PI * 50;
    const filled = (score / 100) * circumference;
    return `${filled} ${circumference}`;
  }

  private getDefaultDateFrom(): string {
    const date = new Date();
    date.setDate(1);
    return date.toISOString().split('T')[0];
  }

  private getDefaultDateTo(): string {
    const date = new Date();
    return date.toISOString().split('T')[0];
  }

  getHealthClass(status: string): string {
    return `health-${status}`;
  }

  getAlertClass(severity: string): string {
    return `alert-${severity}`;
  }

  getAlertIcon(severity: string): string {
    switch (severity) {
      case 'critical': return 'error';
      case 'warning': return 'warning';
      case 'info': return 'info';
      default: return 'notifications';
    }
  }

  getReportIcon(reportType: string): string {
    const config = this.reportsConfig.find(c => c.type === reportType);
    return config?.icon || 'assessment';
  }

  getReportDescription(reportType: string): string {
    const config = this.reportsConfig.find(c => c.type === reportType);
    return config?.description || '';
  }

  getReportTotal(report: ReportCardData): number {
    switch (report.report_type) {
      case 'banques_mouvements':
        return report.total_depots || 0;
      case 'financial_requests_mouvements':
        return report.total_financial_requests || 0;
      case 'etatsdeventes_mouvements':
        return report.total_etatsdeventes || 0;
      case 'soldesbmp_soldes':
        return report.total_soldesbmp || 0;
      case 'bmps_etatsdeventes':
        return report.total_bmps || 0;
      case 'bspdetails_etatsdeventes':
        return report.total_bspdetails || 0;
      default:
        return 0;
    }
  }

  getReportUnmatched(report: ReportCardData): number {
    return report.unmatched || 0;
  }

  getReportTitle(report: ReportCardData): string {
    const config = this.reportsConfig.find(c => c.type === report.report_type);
    return config?.title || report.report_type;
  }

  getReportByName(reportName: string): ReportCardData | null {
    if (!this.dashboard) return null;
    const reportsMap = this.dashboard.reports as any;
    return reportsMap[reportName] || null;
  }

  getReportTitleByName(reportName: string): string {
    const report = this.getReportByName(reportName);
    return report ? this.getReportTitle(report) : reportName;
  }
}
