// services/platform_print_service.dart
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:itrimobe/models/command_detail.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:printing/printing.dart';
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:permission_handler/permission_handler.dart';
import '../models/command_detail.dart';

class PlatformPrintService {
  // Format spécifique 58mm pour petites imprimantes
  static const PdfPageFormat ticket58mmFormat = PdfPageFormat(
    58 * PdfPageFormat.mm, // Largeur exacte 58mm
    double.infinity, // Hauteur automatique
    marginLeft: 1 * PdfPageFormat.mm,
    marginRight: 1 * PdfPageFormat.mm,
    marginTop: 2 * PdfPageFormat.mm,
    marginBottom: 2 * PdfPageFormat.mm,
  );

  // Vérifier les permissions
  static Future<bool> _checkPermissions() async {
    if (!Platform.isAndroid) return true;

    final storagePermission = await Permission.storage.request();
    return storagePermission == PermissionStatus.granted;
  }

  // Vérifier si l'impression est possible
  static Future<bool> canPrint() async {
    try {
      return await Printing.info().then((info) => info.canPrint);
    } catch (e) {
      return false;
    }
  }

  // Générer PDF optimisé pour 58mm
  static Future<Uint8List> _generate58mmTicketPdf({
    required CommandeDetail commande,
    required String paymentMethod,
  }) async {
    final pdf = pw.Document();

    // Configuration pour 58mm (très petit)
    const double titleSize = 9;
    const double headerSize = 8;
    const double bodySize = 7;
    const double smallSize = 6;
    const double lineHeight = 1.2;

    final restaurantInfo = {
      'nom': 'RESTAURANT ITRIMOBE',
      'adresse': 'Moramanga, Antananarivo',
      'ville': 'Madagascar',
      'contact': '261348415301',
      'email': 'contact@careeragency.mg',
      'nif': '4002141594',
      'stat': '10715 33 2025 0 00414',
    };

    final factureNumber =
        'T${DateTime.now().millisecondsSinceEpoch.toString().substring(8)}';
    final dateTime = DateTime.now();

    pdf.addPage(
      pw.Page(
        pageFormat: ticket58mmFormat,
        build: (pw.Context context) {
          return pw.Column(
            crossAxisAlignment: pw.CrossAxisAlignment.center,
            children: [
              // En-tête Restaurant (centré et compact)
              pw.Text(
                restaurantInfo['nom']!,
                style: pw.TextStyle(
                  fontSize: titleSize,
                  fontWeight: pw.FontWeight.bold,
                ),
                textAlign: pw.TextAlign.center,
              ),

              pw.SizedBox(height: 1),

              pw.Text(
                restaurantInfo['adresse']!,
                style: pw.TextStyle(fontSize: smallSize),
                textAlign: pw.TextAlign.center,
              ),

              pw.Text(
                restaurantInfo['ville']!,
                style: pw.TextStyle(fontSize: smallSize),
                textAlign: pw.TextAlign.center,
              ),

              pw.Text(
                'Tel: ${restaurantInfo['contact']!}',
                style: pw.TextStyle(fontSize: smallSize),
                textAlign: pw.TextAlign.center,
              ),

              pw.SizedBox(height: 3),

              // Ligne de séparation
              pw.Container(
                width: double.infinity,
                height: 0.5,
                color: PdfColors.black,
              ),

              pw.SizedBox(height: 2),

              // Informations ticket
              pw.Row(
                mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
                children: [
                  pw.Text(
                    'Ticket: $factureNumber',
                    style: pw.TextStyle(
                      fontSize: bodySize,
                      fontWeight: pw.FontWeight.bold,
                    ),
                  ),
                  pw.Text(
                    'Via: ${commande.tablename ?? 'Table inconnue'}',
                    style: pw.TextStyle(fontSize: bodySize),
                  ),
                ],
              ),

              pw.SizedBox(height: 1),

              pw.Row(
                mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
                children: [
                  pw.Text(
                    _formatDate(dateTime),
                    style: pw.TextStyle(fontSize: smallSize),
                  ),
                  pw.Text(
                    _formatTime(dateTime),
                    style: pw.TextStyle(fontSize: smallSize),
                  ),
                ],
              ),

              pw.SizedBox(height: 2),

              // Ligne de séparation
              pw.Container(
                width: double.infinity,
                height: 0.5,
                color: PdfColors.black,
              ),

              pw.SizedBox(height: 2),

              // Articles (format très compact)
              ...commande.items
                  .map(
                    (item) => pw.Container(
                      margin: const pw.EdgeInsets.only(bottom: 1),
                      child: pw.Column(
                        crossAxisAlignment: pw.CrossAxisAlignment.start,
                        children: [
                          // Nom du plat
                          pw.Text(
                            '${item.menuNom}',
                            style: pw.TextStyle(fontSize: bodySize),
                            maxLines: 2,
                          ),

                          // Quantité, prix unitaire et total sur une ligne
                          pw.Row(
                            mainAxisAlignment:
                                pw.MainAxisAlignment.spaceBetween,
                            children: [
                              pw.Text(
                                '${item.quantite}x ${item.prixUnitaire.toStringAsFixed(2)}MGA',
                                style: pw.TextStyle(fontSize: smallSize),
                              ),
                              pw.Text(
                                '${(item.prixUnitaire * item.quantite).toStringAsFixed(2)}MGA',
                                style: pw.TextStyle(
                                  fontSize: bodySize,
                                  fontWeight: pw.FontWeight.bold,
                                ),
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                  )
                  .toList(),

              pw.SizedBox(height: 2),

              // Ligne de séparation
              pw.Container(
                width: double.infinity,
                height: 0.5,
                color: PdfColors.black,
              ),

              pw.SizedBox(height: 2),

              // Total
              pw.Row(
                mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
                children: [
                  pw.Text(
                    'TOTAL',
                    style: pw.TextStyle(
                      fontSize: titleSize,
                      fontWeight: pw.FontWeight.bold,
                    ),
                  ),
                  pw.Text(
                    '${commande.totalTtc.toStringAsFixed(2)}MGA',
                    style: pw.TextStyle(
                      fontSize: titleSize,
                      fontWeight: pw.FontWeight.bold,
                    ),
                  ),
                ],
              ),

              pw.SizedBox(height: 3),

              // Mode de paiement
              pw.Text(
                'Paiement: ${_getPaymentMethodText(paymentMethod)}',
                style: pw.TextStyle(fontSize: bodySize),
                textAlign: pw.TextAlign.center,
              ),

              pw.SizedBox(height: 3),

              // Ligne de séparation
              pw.Container(
                width: double.infinity,
                height: 0.5,
                color: PdfColors.black,
              ),

              pw.SizedBox(height: 2),

              // Message de remerciement
              pw.Text(
                'Merci de votre visite !',
                style: pw.TextStyle(
                  fontSize: bodySize,
                  fontStyle: pw.FontStyle.italic,
                ),
                textAlign: pw.TextAlign.center,
              ),

              pw.Text(
                'A bientôt !',
                style: pw.TextStyle(fontSize: smallSize),
                textAlign: pw.TextAlign.center,
              ),

              pw.SizedBox(height: 3),

              // Code de suivi (optionnel)
              pw.Text(
                'Code: ${factureNumber}',
                style: pw.TextStyle(fontSize: smallSize),
                textAlign: pw.TextAlign.center,
              ),

              pw.SizedBox(height: 4),

              // Ligne de découpe
              pw.Text(
                '- - - - - - - - - - - - - - - -',
                style: pw.TextStyle(fontSize: smallSize),
                textAlign: pw.TextAlign.center,
              ),

              pw.SizedBox(height: 2),
            ],
          );
        },
      ),
    );

    return pdf.save();
  }

  // Imprimer ticket 58mm
  static Future<bool> printTicket({
    required CommandeDetail commande,
    required String paymentMethod,
  }) async {
    try {
      final hasPermission = await _checkPermissions();
      if (!hasPermission) {
        throw Exception('Permissions requises pour l\'impression');
      }

      final pdfData = await _generate58mmTicketPdf(
        commande: commande,
        paymentMethod: paymentMethod,
      );

      final fileName =
          'Ticket_${commande.numeroCommande}_${DateTime.now().millisecondsSinceEpoch}';

      await Printing.layoutPdf(
        onLayout: (PdfPageFormat format) async => pdfData,
        name: fileName,
        format: ticket58mmFormat,
      );

      return true;
    } catch (e) {
      print('Erreur impression 58mm: $e');
      return false;
    }
  }

  // Sauvegarder ticket 58mm
  static Future<bool> saveTicketPdf({
    required CommandeDetail commande,
    required String paymentMethod,
  }) async {
    try {
      final hasPermission = await _checkPermissions();
      if (!hasPermission) return false;

      final pdfData = await _generate58mmTicketPdf(
        commande: commande,
        paymentMethod: paymentMethod,
      );

      Directory directory;
      if (Platform.isAndroid) {
        directory = Directory('/storage/emulated/0/Download');
        if (!directory.existsSync()) {
          directory =
              await getExternalStorageDirectory() ??
              await getApplicationDocumentsDirectory();
        }
      } else {
        directory = await getApplicationDocumentsDirectory();
      }

      final fileName =
          'Ticket_58mm_${commande.numeroCommande}_${DateTime.now().millisecondsSinceEpoch}.pdf';
      final file = File('${directory.path}/$fileName');

      await file.writeAsBytes(pdfData);

      await Share.shareXFiles(
        [XFile(file.path)],
        subject: 'Ticket ${commande.numeroCommande}',
        text: 'Ticket de caisse 58mm',
      );

      return true;
    } catch (e) {
      print('Erreur sauvegarde 58mm: $e');
      return false;
    }
  }

  // Méthodes pour compatibilité
  static Future<bool> saveFacturePdf({
    required CommandeDetail commande,
    required String paymentMethod,
  }) async {
    return await saveTicketPdf(
      commande: commande,
      paymentMethod: paymentMethod,
    );
  }

  static Future<bool> printFacture({
    required CommandeDetail commande,
    required String paymentMethod,
  }) async {
    return await printTicket(commande: commande, paymentMethod: paymentMethod);
  }

  // Utilitaires de formatageπ
  static String _formatDate(DateTime dateTime) {
    return '${dateTime.day.toString().padLeft(2, '0')}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.year}';
  }

  static String _formatTime(DateTime dateTime) {
    return '${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}';
  }

  static String _getPaymentMethodText(String method) {
    switch (method) {
      case 'cash':
        return 'Espèces';
      case 'card':
        return 'Carte bancaire';
      case 'mobile':
        return 'Paiement mobile';
      default:
        return 'Non spécifié';
    }
  }
}
