import 'dart:io';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:flutter/services.dart';
import '../models/dashboard_stats_model.dart';

/// Service d'export de rapports PDF pour le Dashboard
class DashboardExportService {
  static const String _reportsFolder = 'UnionFlow_Reports';
  
  /// Exporte un rapport complet du dashboard en PDF
  Future<String> exportDashboardReport({
    required DashboardDataModel dashboardData,
    required String organizationName,
    required String reportTitle,
    bool includeCharts = true,
    bool includeActivities = true,
    bool includeEvents = true,
  }) async {
    final pdf = pw.Document();
    
    // Charger les polices personnalisées si disponibles
    final font = await _loadFont();
    
    // Page 1: Couverture et statistiques principales
    pdf.addPage(
      pw.MultiPage(
        pageFormat: PdfPageFormat.a4,
        theme: _createTheme(font),
        build: (context) => [
          _buildHeader(organizationName, reportTitle),
          pw.SizedBox(height: 20),
          _buildStatsSection(dashboardData.stats),
          pw.SizedBox(height: 20),
          _buildSummarySection(dashboardData),
        ],
      ),
    );
    
    // Page 2: Activités récentes (si incluses)
    if (includeActivities && dashboardData.recentActivities.isNotEmpty) {
      pdf.addPage(
        pw.MultiPage(
          pageFormat: PdfPageFormat.a4,
          theme: _createTheme(font),
          build: (context) => [
            _buildSectionTitle('Activités Récentes'),
            pw.SizedBox(height: 10),
            _buildActivitiesSection(dashboardData.recentActivities),
          ],
        ),
      );
    }
    
    // Page 3: Événements à venir (si inclus)
    if (includeEvents && dashboardData.upcomingEvents.isNotEmpty) {
      pdf.addPage(
        pw.MultiPage(
          pageFormat: PdfPageFormat.a4,
          theme: _createTheme(font),
          build: (context) => [
            _buildSectionTitle('Événements à Venir'),
            pw.SizedBox(height: 10),
            _buildEventsSection(dashboardData.upcomingEvents),
          ],
        ),
      );
    }
    
    // Page 4: Graphiques et analyses (si inclus)
    if (includeCharts) {
      pdf.addPage(
        pw.MultiPage(
          pageFormat: PdfPageFormat.a4,
          theme: _createTheme(font),
          build: (context) => [
            _buildSectionTitle('Analyses et Tendances'),
            pw.SizedBox(height: 10),
            _buildAnalyticsSection(dashboardData.stats),
          ],
        ),
      );
    }
    
    // Sauvegarder le PDF
    final fileName = _generateFileName(reportTitle);
    final filePath = await _savePdf(pdf, fileName);
    
    return filePath;
  }
  
  /// Exporte uniquement les statistiques en PDF
  Future<String> exportStatsReport({
    required DashboardStatsModel stats,
    required String organizationName,
    String? customTitle,
  }) async {
    final pdf = pw.Document();
    final font = await _loadFont();
    final title = customTitle ?? 'Rapport Statistiques - ${DateTime.now().day}/${DateTime.now().month}/${DateTime.now().year}';
    
    pdf.addPage(
      pw.MultiPage(
        pageFormat: PdfPageFormat.a4,
        theme: _createTheme(font),
        build: (context) => [
          _buildHeader(organizationName, title),
          pw.SizedBox(height: 30),
          _buildStatsSection(stats),
          pw.SizedBox(height: 30),
          _buildStatsAnalysis(stats),
        ],
      ),
    );
    
    final fileName = _generateFileName('Stats_${DateTime.now().millisecondsSinceEpoch}');
    final filePath = await _savePdf(pdf, fileName);
    
    return filePath;
  }
  
  /// Charge une police personnalisée
  Future<pw.Font?> _loadFont() async {
    try {
      final fontData = await rootBundle.load('assets/fonts/Inter-Regular.ttf');
      return pw.Font.ttf(fontData);
    } catch (e) {
      // Police par défaut si la police personnalisée n'est pas disponible
      return null;
    }
  }
  
  /// Crée le thème PDF
  pw.ThemeData _createTheme(pw.Font? font) {
    return pw.ThemeData.withFont(
      base: font ?? pw.Font.helvetica(),
      bold: font ?? pw.Font.helveticaBold(),
    );
  }
  
  /// Construit l'en-tête du rapport
  pw.Widget _buildHeader(String organizationName, String reportTitle) {
    return pw.Container(
      width: double.infinity,
      padding: const pw.EdgeInsets.all(20),
      decoration: pw.BoxDecoration(
        gradient: pw.LinearGradient(
          colors: [
            PdfColor.fromHex('#4169E1'), // Bleu Roi
            PdfColor.fromHex('#008B8B'), // Bleu Pétrole
          ],
        ),
        borderRadius: pw.BorderRadius.circular(10),
      ),
      child: pw.Column(
        crossAxisAlignment: pw.CrossAxisAlignment.start,
        children: [
          pw.Text(
            organizationName,
            style: pw.TextStyle(
              fontSize: 24,
              fontWeight: pw.FontWeight.bold,
              color: PdfColors.white,
            ),
          ),
          pw.SizedBox(height: 5),
          pw.Text(
            reportTitle,
            style: const pw.TextStyle(
              fontSize: 16,
              color: PdfColors.white,
            ),
          ),
          pw.SizedBox(height: 10),
          pw.Text(
            'Généré le ${DateTime.now().day}/${DateTime.now().month}/${DateTime.now().year} à ${DateTime.now().hour}:${DateTime.now().minute.toString().padLeft(2, '0')}',
            style: const pw.TextStyle(
              fontSize: 12,
              color: PdfColors.white,
            ),
          ),
        ],
      ),
    );
  }
  
  /// Construit la section des statistiques
  pw.Widget _buildStatsSection(DashboardStatsModel stats) {
    return pw.Column(
      crossAxisAlignment: pw.CrossAxisAlignment.start,
      children: [
        _buildSectionTitle('Statistiques Principales'),
        pw.SizedBox(height: 15),
        pw.Row(
          children: [
            pw.Expanded(
              child: _buildStatCard('Membres Total', stats.totalMembers.toString(), PdfColor.fromHex('#4169E1')),
            ),
            pw.SizedBox(width: 10),
            pw.Expanded(
              child: _buildStatCard('Membres Actifs', stats.activeMembers.toString(), PdfColor.fromHex('#10B981')),
            ),
          ],
        ),
        pw.SizedBox(height: 10),
        pw.Row(
          children: [
            pw.Expanded(
              child: _buildStatCard('Événements', stats.totalEvents.toString(), PdfColor.fromHex('#008B8B')),
            ),
            pw.SizedBox(width: 10),
            pw.Expanded(
              child: _buildStatCard('Contributions', stats.formattedContributionAmount, PdfColor.fromHex('#F59E0B')),
            ),
          ],
        ),
        pw.SizedBox(height: 10),
        pw.Row(
          children: [
            pw.Expanded(
              child: _buildStatCard('Croissance', '${stats.monthlyGrowth.toStringAsFixed(1)}%', 
                  stats.hasGrowth ? PdfColor.fromHex('#10B981') : PdfColor.fromHex('#EF4444')),
            ),
            pw.SizedBox(width: 10),
            pw.Expanded(
              child: _buildStatCard('Engagement', '${(stats.engagementRate * 100).toStringAsFixed(1)}%', 
                  stats.isHighEngagement ? PdfColor.fromHex('#10B981') : PdfColor.fromHex('#F59E0B')),
            ),
          ],
        ),
      ],
    );
  }
  
  /// Construit une carte de statistique
  pw.Widget _buildStatCard(String title, String value, PdfColor color) {
    return pw.Container(
      padding: const pw.EdgeInsets.all(15),
      decoration: pw.BoxDecoration(
        border: pw.Border.all(color: color, width: 2),
        borderRadius: pw.BorderRadius.circular(8),
      ),
      child: pw.Column(
        crossAxisAlignment: pw.CrossAxisAlignment.start,
        children: [
          pw.Text(
            title,
            style: const pw.TextStyle(
              fontSize: 12,
              color: PdfColors.grey700,
            ),
          ),
          pw.SizedBox(height: 5),
          pw.Text(
            value,
            style: pw.TextStyle(
              fontSize: 20,
              fontWeight: pw.FontWeight.bold,
              color: color,
            ),
          ),
        ],
      ),
    );
  }
  
  /// Construit un titre de section
  pw.Widget _buildSectionTitle(String title) {
    return pw.Text(
      title,
      style: pw.TextStyle(
        fontSize: 18,
        fontWeight: pw.FontWeight.bold,
        color: PdfColor.fromHex('#1F2937'),
      ),
    );
  }
  
  /// Construit la section de résumé
  pw.Widget _buildSummarySection(DashboardDataModel data) {
    return pw.Column(
      crossAxisAlignment: pw.CrossAxisAlignment.start,
      children: [
        _buildSectionTitle('Résumé Exécutif'),
        pw.SizedBox(height: 10),
        pw.Text(
          'Ce rapport présente un aperçu complet de l\'activité de l\'organisation. '
          'Avec ${data.stats.totalMembers} membres dont ${data.stats.activeMembers} actifs '
          '(${data.stats.activeMemberPercentage.toStringAsFixed(1)}%), l\'organisation maintient '
          'un niveau d\'engagement de ${(data.stats.engagementRate * 100).toStringAsFixed(1)}%.',
          style: const pw.TextStyle(fontSize: 12, lineSpacing: 1.5),
        ),
        pw.SizedBox(height: 10),
        pw.Text(
          'La croissance mensuelle de ${data.stats.monthlyGrowth.toStringAsFixed(1)}% '
          '${data.stats.hasGrowth ? 'indique une tendance positive' : 'nécessite une attention particulière'}. '
          'Les contributions totales s\'élèvent à ${data.stats.formattedContributionAmount} XOF.',
          style: const pw.TextStyle(fontSize: 12, lineSpacing: 1.5),
        ),
      ],
    );
  }
  
  /// Construit la section des activités
  pw.Widget _buildActivitiesSection(List<RecentActivityModel> activities) {
    return pw.Table(
      border: pw.TableBorder.all(color: PdfColors.grey300),
      children: [
        // En-tête
        pw.TableRow(
          decoration: pw.BoxDecoration(color: PdfColor.fromHex('#F3F4F6')),
          children: [
            _buildTableHeader('Type'),
            _buildTableHeader('Description'),
            _buildTableHeader('Utilisateur'),
            _buildTableHeader('Date'),
          ],
        ),
        // Données
        ...activities.take(10).map((activity) => pw.TableRow(
          children: [
            _buildTableCell(activity.type),
            _buildTableCell(activity.title),
            _buildTableCell(activity.userName),
            _buildTableCell(activity.timeAgo),
          ],
        )),
      ],
    );
  }
  
  /// Construit la section des événements
  pw.Widget _buildEventsSection(List<UpcomingEventModel> events) {
    return pw.Table(
      border: pw.TableBorder.all(color: PdfColors.grey300),
      children: [
        // En-tête
        pw.TableRow(
          decoration: pw.BoxDecoration(color: PdfColor.fromHex('#F3F4F6')),
          children: [
            _buildTableHeader('Événement'),
            _buildTableHeader('Date'),
            _buildTableHeader('Lieu'),
            _buildTableHeader('Participants'),
          ],
        ),
        // Données
        ...events.take(10).map((event) => pw.TableRow(
          children: [
            _buildTableCell(event.title),
            _buildTableCell('${event.startDate.day}/${event.startDate.month}'),
            _buildTableCell(event.location),
            _buildTableCell('${event.currentParticipants}/${event.maxParticipants}'),
          ],
        )),
      ],
    );
  }
  
  /// Construit l'en-tête de tableau
  pw.Widget _buildTableHeader(String text) {
    return pw.Padding(
      padding: const pw.EdgeInsets.all(8),
      child: pw.Text(
        text,
        style: pw.TextStyle(
          fontWeight: pw.FontWeight.bold,
          fontSize: 10,
        ),
      ),
    );
  }
  
  /// Construit une cellule de tableau
  pw.Widget _buildTableCell(String text) {
    return pw.Padding(
      padding: const pw.EdgeInsets.all(8),
      child: pw.Text(
        text,
        style: const pw.TextStyle(fontSize: 9),
      ),
    );
  }
  
  /// Construit la section d'analyse des statistiques
  pw.Widget _buildStatsAnalysis(DashboardStatsModel stats) {
    return pw.Column(
      crossAxisAlignment: pw.CrossAxisAlignment.start,
      children: [
        _buildSectionTitle('Analyse des Performances'),
        pw.SizedBox(height: 10),
        _buildAnalysisPoint('Taux d\'activité des membres', 
            '${stats.activeMemberPercentage.toStringAsFixed(1)}%',
            stats.activeMemberPercentage > 70 ? 'Excellent' : 'À améliorer'),
        _buildAnalysisPoint('Croissance mensuelle', 
            '${stats.monthlyGrowth.toStringAsFixed(1)}%',
            stats.hasGrowth ? 'Positive' : 'Négative'),
        _buildAnalysisPoint('Niveau d\'engagement', 
            '${(stats.engagementRate * 100).toStringAsFixed(1)}%',
            stats.isHighEngagement ? 'Élevé' : 'Modéré'),
      ],
    );
  }
  
  /// Construit un point d'analyse
  pw.Widget _buildAnalysisPoint(String metric, String value, String assessment) {
    return pw.Padding(
      padding: const pw.EdgeInsets.symmetric(vertical: 5),
      child: pw.Row(
        children: [
          pw.Expanded(flex: 2, child: pw.Text(metric, style: const pw.TextStyle(fontSize: 11))),
          pw.Expanded(flex: 1, child: pw.Text(value, style: pw.TextStyle(fontSize: 11, fontWeight: pw.FontWeight.bold))),
          pw.Expanded(flex: 1, child: pw.Text(assessment, style: const pw.TextStyle(fontSize: 11))),
        ],
      ),
    );
  }
  
  /// Construit la section d'analytics
  pw.Widget _buildAnalyticsSection(DashboardStatsModel stats) {
    return pw.Column(
      crossAxisAlignment: pw.CrossAxisAlignment.start,
      children: [
        pw.Text('Tendances et Projections', style: pw.TextStyle(fontSize: 14, fontWeight: pw.FontWeight.bold)),
        pw.SizedBox(height: 15),
        pw.Text('Basé sur les données actuelles, voici les principales tendances observées:', style: const pw.TextStyle(fontSize: 11)),
        pw.SizedBox(height: 10),
        pw.Bullet(text: 'Évolution du nombre de membres: ${stats.hasGrowth ? 'Croissance' : 'Déclin'} de ${stats.monthlyGrowth.abs().toStringAsFixed(1)}% ce mois'),
        pw.Bullet(text: 'Participation aux événements: ${stats.upcomingEvents} événements programmés'),
        pw.Bullet(text: 'Volume des contributions: ${stats.formattedContributionAmount} XOF collectés'),
        pw.Bullet(text: 'Demandes en attente: ${stats.pendingRequests} nécessitent un traitement'),
      ],
    );
  }
  
  /// Génère un nom de fichier unique
  String _generateFileName(String baseName) {
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final cleanName = baseName.replaceAll(RegExp(r'[^\w\s-]'), '').replaceAll(' ', '_');
    return '${cleanName}_$timestamp.pdf';
  }
  
  /// Sauvegarde le PDF et retourne le chemin
  Future<String> _savePdf(pw.Document pdf, String fileName) async {
    final directory = await getApplicationDocumentsDirectory();
    final reportsDir = Directory('${directory.path}/$_reportsFolder');
    
    if (!await reportsDir.exists()) {
      await reportsDir.create(recursive: true);
    }
    
    final file = File('${reportsDir.path}/$fileName');
    await file.writeAsBytes(await pdf.save());
    
    return file.path;
  }
  
  /// Partage un rapport PDF
  Future<void> shareReport(String filePath, {String? subject}) async {
    await Share.shareXFiles(
      [XFile(filePath)],
      subject: subject ?? 'Rapport Dashboard UnionFlow',
      text: 'Rapport généré par l\'application UnionFlow',
    );
  }
  
  /// Obtient la liste des rapports sauvegardés
  Future<List<File>> getSavedReports() async {
    final directory = await getApplicationDocumentsDirectory();
    final reportsDir = Directory('${directory.path}/$_reportsFolder');
    
    if (!await reportsDir.exists()) {
      return [];
    }
    
    final files = await reportsDir.list().where((entity) => 
        entity is File && entity.path.endsWith('.pdf')).cast<File>().toList();
    
    // Trier par date de modification (plus récent en premier)
    files.sort((a, b) => b.lastModifiedSync().compareTo(a.lastModifiedSync()));
    
    return files;
  }
  
  /// Supprime un rapport
  Future<void> deleteReport(String filePath) async {
    final file = File(filePath);
    if (await file.exists()) {
      await file.delete();
    }
  }
  
  /// Supprime tous les rapports anciens (plus de 30 jours)
  Future<void> cleanupOldReports() async {
    final reports = await getSavedReports();
    final cutoffDate = DateTime.now().subtract(const Duration(days: 30));
    
    for (final report in reports) {
      final lastModified = await report.lastModified();
      if (lastModified.isBefore(cutoffDate)) {
        await report.delete();
      }
    }
  }
}
