import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:nfc_google_sheet/context/app_colors.dart';
import 'package:nfc_google_sheet/database/attendance_dao.dart';
import 'package:nfc_google_sheet/services/google_drive_service.dart';
import 'package:file_picker/file_picker.dart';

class SheetPage extends StatefulWidget {
  const SheetPage({super.key});
  static String? selectedProgram;
  static String? selectedSubject;

  @override
  State<SheetPage> createState() => _SheetPageState();
}

class _SheetPageState extends State<SheetPage> {
  late Future<List<Map<String, dynamic>>> _attendanceData;
  int _sortColumnIndex = 5;
  bool _sortAscending = false;

  static const _columnKeys = ['studentNumber', 'firstName', 'name', 'promotion', 'subject', 'date'];

  @override
  void initState() {
    super.initState();
    _refreshData();
  }

  void _refreshData() {
    _attendanceData = AttendanceDao.instance.queryWithStudents();
  }

  void _showSnackBar(String message, Color color) {
    if (!mounted) return;
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), backgroundColor: color),
    );
  }

  List<Map<String, dynamic>> _sortRecords(List<Map<String, dynamic>> records) {
    final key = _columnKeys[_sortColumnIndex];
    final sorted = List<Map<String, dynamic>>.from(records);
    sorted.sort((a, b) {
      final va = (a[key] ?? '').toString().toLowerCase();
      final vb = (b[key] ?? '').toString().toLowerCase();
      return _sortAscending ? va.compareTo(vb) : vb.compareTo(va);
    });
    return sorted;
  }

  DropdownButtonFormField<String> _buildDropdown({
    required String label,
    required List<String> items,
    required bool enabled,
    required ValueChanged<String?>? onChanged,
    Key? key,
  }) {
    final color = enabled ? AppColors.unselected : AppColors.unselected.withValues(alpha: 0.3);
    return DropdownButtonFormField<String>(
      key: key,
      dropdownColor: AppColors.background,
      style: TextStyle(color: color),
      decoration: InputDecoration(
        labelText: label,
        labelStyle: TextStyle(color: color),
        enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: AppColors.unselected)),
      ),
      items: items.map((v) => DropdownMenuItem(value: v, child: Text(v))).toList(),
      onChanged: onChanged,
    );
  }

  void _showExportDialog() async {
    final promotions = await AttendanceDao.instance.getDistinctPromotions();
    if (promotions.isEmpty) {
      _showSnackBar('Aucune donnée à exporter.', Colors.red);
      return;
    }

    if (!mounted) return;
    showDialog(
      context: context,
      builder: (BuildContext dialogContext) {
        String? selectedPromotion;
        String? selectedSubject;
        String? selectedDate;
        List<String> subjects = [];
        List<String> dates = [];
        bool includeCardId = false;

        return StatefulBuilder(
          builder: (context, setDialogState) {
            final bool canExport = selectedPromotion != null && selectedSubject != null && selectedDate != null;

            return AlertDialog(
              backgroundColor: AppColors.background,
              title: Text("Générer le fichier", style: TextStyle(color: AppColors.selected)),
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  _buildDropdown(
                    label: 'Promotion',
                    items: promotions,
                    enabled: true,
                    onChanged: (value) async {
                      final subs = await AttendanceDao.instance.getSubjectsByPromotion(value!);
                      setDialogState(() {
                        selectedPromotion = value;
                        selectedSubject = null;
                        selectedDate = null;
                        subjects = subs;
                        dates = [];
                      });
                    },
                  ),
                  SizedBox(height: 8),
                  _buildDropdown(
                    key: ValueKey('subject_$selectedPromotion'),
                    label: 'Matière',
                    items: subjects,
                    enabled: selectedPromotion != null,
                    onChanged: selectedPromotion != null ? (value) async {
                      final d = await AttendanceDao.instance.getDatesByPromotionAndSubject(selectedPromotion!, value!);
                      setDialogState(() {
                        selectedSubject = value;
                        selectedDate = null;
                        dates = d;
                      });
                    } : null,
                  ),
                  SizedBox(height: 8),
                  _buildDropdown(
                    key: ValueKey('date_${selectedPromotion}_$selectedSubject'),
                    label: 'Date',
                    items: dates,
                    enabled: selectedSubject != null,
                    onChanged: selectedSubject != null ? (value) {
                      setDialogState(() {
                        selectedDate = value;
                      });
                    } : null,
                  ),
                  SizedBox(height: 12),
                  CheckboxListTile(
                    title: Text("Inclure l'ID Carte", style: TextStyle(color: AppColors.unselected)),
                    value: includeCardId,
                    activeColor: AppColors.selected,
                    checkColor: AppColors.background,
                    contentPadding: EdgeInsets.zero,
                    onChanged: (value) {
                      setDialogState(() {
                        includeCardId = value ?? false;
                      });
                    },
                  ),
                  SizedBox(height: 16),
                  Row(
                    children: [
                      Expanded(
                        child: ElevatedButton.icon(
                          style: ElevatedButton.styleFrom(
                            backgroundColor: canExport ? AppColors.selected : AppColors.selected.withValues(alpha: 0.3),
                            padding: EdgeInsets.symmetric(vertical: 12),
                          ),
                          icon: Icon(Icons.save, color: AppColors.background, size: 18),
                          label: Text("Local", style: TextStyle(color: AppColors.background)),
                          onPressed: canExport ? () {
                            Navigator.of(dialogContext).pop();
                            _exportLocal(includeCardId, selectedPromotion!, selectedSubject!, selectedDate!);
                          } : null,
                        ),
                      ),
                      SizedBox(width: 12),
                      Expanded(
                        child: ElevatedButton.icon(
                          style: ElevatedButton.styleFrom(
                            backgroundColor: canExport ? Colors.blue.shade600 : Colors.blue.shade600.withValues(alpha: 0.3),
                            padding: EdgeInsets.symmetric(vertical: 12),
                          ),
                          icon: Icon(Icons.cloud_upload, color: Colors.white, size: 18),
                          label: Text("Drive", style: TextStyle(color: Colors.white)),
                          onPressed: canExport ? () {
                            Navigator.of(dialogContext).pop();
                            _exportToDrive(includeCardId, selectedPromotion!, selectedSubject!, selectedDate!);
                          } : null,
                        ),
                      ),
                    ],
                  ),
                ],
              ),
              actions: [
                TextButton(
                  child: Text("Annuler", style: TextStyle(color: AppColors.unselected)),
                  onPressed: () => Navigator.of(dialogContext).pop(),
                ),
              ],
            );
          },
        );
      },
    );
  }

  Future<List<int>?> _generateExcelBytes(bool includeCardId, String promotion, String subject, String date) async {
    final bytes = await AttendanceDao.instance.generateExcel(
      includeCardId,
      promotion: promotion,
      subject: subject,
      date: date,
    );
    if (bytes == null) {
      _showSnackBar('Aucune donnée à exporter.', Colors.red);
    }
    return bytes;
  }

  void _onExportSuccess(String promotion, String subject, String date) async {
    await AttendanceDao.instance.delete(promotion, subject, date);
    setState(() {
      _refreshData();
    });
  }

  void _exportLocal(bool includeCardId, String promotion, String subject, String date) async {
    final excelBytes = await _generateExcelBytes(includeCardId, promotion, subject, date);
    if (excelBytes == null) return;

    String? filePath = await FilePicker.platform.saveFile(
      dialogTitle: 'Veuillez sélectionner un emplacement de sortie',
      fileName: '${promotion}_${subject}_$date.xlsx',
      bytes: Uint8List.fromList(excelBytes),
    );

    if (filePath != null) {
      _onExportSuccess(promotion, subject, date);
      _showSnackBar('Fichier exporté et données supprimées.', AppColors.selected);
    } else {
      _showSnackBar('Enregistrement annulé.', Colors.orange);
    }
  }

  void _exportToDrive(bool includeCardId, String promotion, String subject, String date) async {
    final excelBytes = await _generateExcelBytes(includeCardId, promotion, subject, date);
    if (excelBytes == null) return;

    _showSnackBar('Connexion à Google Drive...', Colors.blue.shade600);

    try {
      final fileId = await GoogleDriveService.instance.uploadAsGoogleSheet(
        excelBytes,
        '${promotion}_${subject}_$date',
      );

      if (fileId != null) {
        _onExportSuccess(promotion, subject, date);
        _showSnackBar('Fichier importé sur Drive et données supprimées.', AppColors.selected);
      } else {
        _showSnackBar('Connexion annulée.', Colors.orange);
      }
    } catch (e) {
      _showSnackBar('Erreur lors de l\'import : $e', Colors.red);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColors.background,
      appBar: AppBar(
        title: Text('Données des étudiants', style: TextStyle(color: AppColors.selected)),
        backgroundColor: AppColors.background,
        elevation: 0,
        centerTitle: true,
      ),
      body: FutureBuilder<List<Map<String, dynamic>>>(
        future: _attendanceData,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(child: CircularProgressIndicator(color: AppColors.selected));
          } else if (snapshot.hasError) {
            return Center(child: Text('Erreur: ${snapshot.error}', style: TextStyle(color: Colors.red)));
          } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
            return Center(child: Text('Aucun émargement enregistré.', style: TextStyle(color: AppColors.unselected)));
          } else {
            final records = _sortRecords(snapshot.data!);
            final headerStyle = TextStyle(color: AppColors.selected, fontWeight: FontWeight.bold);

            DataColumn sortableColumn(String label) {
              return DataColumn(
                label: Text(label, style: headerStyle),
                onSort: (columnIndex, ascending) {
                  setState(() {
                    _sortColumnIndex = columnIndex;
                    _sortAscending = ascending;
                  });
                },
              );
            }

            return SingleChildScrollView(
              child: SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: DataTable(
                  columnSpacing: 20.0,
                  sortColumnIndex: _sortColumnIndex,
                  sortAscending: _sortAscending,
                  headingRowColor: WidgetStateColor.resolveWith((states) => AppColors.subtitle),
                  columns: [
                    sortableColumn('ID Étudiant'),
                    sortableColumn('Prénom'),
                    sortableColumn('Nom'),
                    sortableColumn('Promotion'),
                    sortableColumn('Matière'),
                    sortableColumn('Date'),
                  ],
                  rows: records.map((record) => DataRow(
                    cells: _columnKeys.map((key) =>
                      DataCell(Text(record[key] ?? '', style: TextStyle(color: AppColors.unselected))),
                    ).toList(),
                  )).toList(),
                ),
              ),
            );
          }
        },
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: _showExportDialog,
        label: Text('Générer le fichier', style: TextStyle(color: AppColors.background)),
        icon: Icon(Icons.download, color: AppColors.background),
        backgroundColor: AppColors.selected,
      ),
    );
  }
}
