import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:mek_stripe_terminal/mek_stripe_terminal.dart';

import 'api_service.dart';
import 'device_info_service.dart';
import 'current_user_service.dart';
import 'current_amicale_service.dart';

/// Service simplifié pour Stripe Terminal (Tap to Pay)
/// Cette version se concentre sur les fonctionnalités essentielles
class StripeTerminalServiceSimple {
  static final StripeTerminalServiceSimple instance = StripeTerminalServiceSimple._internal();
  StripeTerminalServiceSimple._internal();

  bool _isInitialized = false;
  String? _stripeAccountId;
  String? _locationId;

  // Getters publics
  bool get isInitialized => _isInitialized;

  /// Initialise le service Stripe Terminal
  Future<bool> initialize() async {
    if (_isInitialized) {
      debugPrint('ℹ️ StripeTerminalService déjà initialisé');
      return true;
    }

    try {
      debugPrint('🚀 Initialisation de Stripe Terminal...');

      // 1. Vérifier que l'utilisateur est connecté
      if (!CurrentUserService.instance.isLoggedIn) {
        throw Exception('Utilisateur non connecté');
      }

      // 2. Vérifier que l'amicale a Stripe activé
      final amicale = CurrentAmicaleService.instance.currentAmicale;
      if (amicale == null) {
        throw Exception('Aucune amicale sélectionnée');
      }

      if (!amicale.chkStripe || amicale.stripeId.isEmpty) {
        throw Exception('L\'amicale n\'a pas de compte Stripe configuré');
      }

      _stripeAccountId = amicale.stripeId;

      // 3. Vérifier la compatibilité Tap to Pay
      final canUseTapToPay = DeviceInfoService.instance.canUseTapToPay();
      if (!canUseTapToPay) {
        debugPrint('⚠️ Cet appareil ne supporte pas Tap to Pay');
        return false;
      }

      // 4. Récupérer la configuration Stripe depuis l'API
      await _fetchStripeConfiguration();

      // 5. Initialiser le Terminal (sera fait à la demande)
      _isInitialized = true;
      debugPrint('✅ StripeTerminalService prêt');

      return true;

    } catch (e) {
      debugPrint('❌ Erreur lors de l\'initialisation Stripe Terminal: $e');
      _isInitialized = false;
      return false;
    }
  }

  /// Récupère la configuration Stripe depuis l'API
  Future<void> _fetchStripeConfiguration() async {
    try {
      final response = await ApiService.instance.get('/stripe/configuration');

      // Récupérer le location ID si disponible
      _locationId = response.data['location_id'];

      debugPrint('✅ Configuration Stripe récupérée');
    } catch (e) {
      debugPrint('❌ Erreur récupération config Stripe: $e');
      rethrow;
    }
  }

  /// Callback pour récupérer un token de connexion depuis l'API
  Future<String> _fetchConnectionToken() async {
    try {
      debugPrint('🔑 Récupération du token de connexion Stripe...');

      final response = await ApiService.instance.post(
        '/stripe/terminal/connection-token',
        data: {
          'amicale_id': CurrentAmicaleService.instance.amicaleId,
          'stripe_account': _stripeAccountId,
          'location_id': _locationId,
        }
      );

      final token = response.data['secret'];
      if (token == null || token.isEmpty) {
        throw Exception('Token de connexion invalide');
      }

      debugPrint('✅ Token de connexion récupéré');
      return token;

    } catch (e) {
      debugPrint('❌ Erreur récupération token: $e');
      throw Exception('Impossible de récupérer le token de connexion');
    }
  }

  /// Initialise le Terminal à la demande
  Future<void> _ensureTerminalInitialized() async {
    // Vérifier si Terminal.instance existe déjà
    try {
      // Tenter d'accéder à Terminal.instance
      Terminal.instance;
      debugPrint('✅ Terminal déjà initialisé');
    } catch (_) {
      // Si erreur, initialiser le Terminal
      debugPrint('📱 Initialisation du Terminal SDK...');
      await Terminal.initTerminal(
        fetchToken: _fetchConnectionToken,
      );
      debugPrint('✅ Terminal SDK initialisé');
    }
  }

  /// Processus simplifié de paiement par carte
  Future<PaymentResult> processCardPayment({
    required int amountInCents,
    String? description,
  }) async {
    if (!_isInitialized) {
      throw Exception('Service non initialisé');
    }

    try {
      debugPrint('💰 Démarrage du paiement de ${amountInCents / 100}€...');

      // 1. S'assurer que le Terminal est initialisé
      await _ensureTerminalInitialized();

      // 2. Créer le PaymentIntent côté serveur
      final response = await ApiService.instance.post(
        '/stripe/terminal/create-payment-intent',
        data: {
          'amount': amountInCents,
          'currency': 'eur',
          'description': description ?? 'Calendrier pompiers',
          'amicale_id': CurrentAmicaleService.instance.amicaleId,
          'member_id': CurrentUserService.instance.userId,
          'stripe_account': _stripeAccountId,
          'payment_method_types': ['card_present'],
          'capture_method': 'automatic',
        },
      );

      final paymentIntentId = response.data['payment_intent_id'];
      final clientSecret = response.data['client_secret'];

      if (clientSecret == null) {
        throw Exception('Client secret manquant');
      }

      debugPrint('✅ PaymentIntent créé: $paymentIntentId');

      // 3. Retourner le résultat avec les infos nécessaires
      // Le processus de paiement réel sera géré par l'UI
      return PaymentResult(
        success: true,
        paymentIntentId: paymentIntentId,
        clientSecret: clientSecret,
        amount: amountInCents,
      );

    } catch (e) {
      debugPrint('❌ Erreur lors du paiement: $e');
      return PaymentResult(
        success: false,
        errorMessage: e.toString(),
      );
    }
  }

  /// Confirme un paiement réussi auprès du serveur
  Future<void> confirmPaymentSuccess({
    required String paymentIntentId,
    required int amount,
  }) async {
    try {
      await ApiService.instance.post(
        '/stripe/terminal/payment-success',
        data: {
          'payment_intent_id': paymentIntentId,
          'amount': amount,
          'status': 'succeeded',
          'amicale_id': CurrentAmicaleService.instance.amicaleId,
          'member_id': CurrentUserService.instance.userId,
        },
      );
      debugPrint('✅ Paiement confirmé au serveur');
    } catch (e) {
      debugPrint('⚠️ Erreur notification succès paiement: $e');
      // Ne pas bloquer si la notification échoue
    }
  }

  /// Vérifie si l'appareil supporte Tap to Pay
  bool isTapToPaySupported() {
    return DeviceInfoService.instance.canUseTapToPay();
  }

  /// Vérifie si le service est prêt pour les paiements
  bool isReadyForPayments() {
    if (!_isInitialized) return false;
    if (!isTapToPaySupported()) return false;
    if (_stripeAccountId == null || _stripeAccountId!.isEmpty) return false;
    return true;
  }

  /// Récupère les informations de configuration
  Map<String, dynamic> getConfiguration() {
    return {
      'initialized': _isInitialized,
      'tap_to_pay_supported': isTapToPaySupported(),
      'stripe_account_id': _stripeAccountId,
      'location_id': _locationId,
      'device_info': DeviceInfoService.instance.getStoredDeviceInfo(),
    };
  }
}

/// Classe pour représenter le résultat d'un paiement
class PaymentResult {
  final bool success;
  final String? paymentIntentId;
  final String? clientSecret;
  final int? amount;
  final String? errorMessage;

  PaymentResult({
    required this.success,
    this.paymentIntentId,
    this.clientSecret,
    this.amount,
    this.errorMessage,
  });
}