/// Dialogue de paiement de contribution
/// Formulaire pour enregistrer un paiement de contribution.
/// Pour Wave : appelle l'API Checkout, ouvre wave_launch_url (app Wave), retour automatique via deep link.
library payment_dialog;

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../shared/design_system/tokens/color_tokens.dart';
import '../../../../shared/design_system/tokens/app_colors.dart';
import '../../../../core/config/environment.dart';
import 'package:intl/intl.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:unionflow_mobile_apps/core/di/injection.dart';
import 'package:unionflow_mobile_apps/shared/constants/payment_method_assets.dart';
import '../../bloc/contributions_bloc.dart';
import '../../bloc/contributions_event.dart';
import '../../data/models/contribution_model.dart';
import '../../domain/repositories/contribution_repository.dart';
import '../../data/repositories/contribution_repository.dart' show ContributionRepositoryImpl;

/// Dialogue de paiement de contribution
class PaymentDialog extends StatefulWidget {
  final ContributionModel cotisation;
  
  const PaymentDialog({
    super.key,
    required this.cotisation,
  });

  @override
  State<PaymentDialog> createState() => _PaymentDialogState();
}

class _PaymentDialogState extends State<PaymentDialog> {
  final _formKey = GlobalKey<FormState>();
  final _montantController = TextEditingController();
  final _referenceController = TextEditingController();
  final _notesController = TextEditingController();
  final _wavePhoneController = TextEditingController();

  PaymentMethod _selectedMethode = PaymentMethod.waveMoney;
  DateTime _datePaiement = DateTime.now();
  bool _waveLoading = false;

  @override
  void initState() {
    super.initState();
    _montantController.text = widget.cotisation.montantRestant.toStringAsFixed(0);
  }

  @override
  void dispose() {
    _montantController.dispose();
    _referenceController.dispose();
    _notesController.dispose();
    _wavePhoneController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Dialog(
      child: Container(
        width: MediaQuery.of(context).size.width * 0.9,
        constraints: const BoxConstraints(maxHeight: 500),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            // En-tête
            Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(
                color: ColorTokens.successLight,
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(4),
                  topRight: Radius.circular(4),
                ),
              ),
              child: Row(
                children: [
                  const Icon(Icons.payment, color: Colors.white),
                  const SizedBox(width: 12),
                  const Text(
                    'Enregistrer un paiement',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 18,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  const Spacer(),
                  IconButton(
                    icon: const Icon(Icons.close, color: Colors.white),
                    onPressed: () => Navigator.pop(context),
                  ),
                ],
              ),
            ),
            
            // Informations de la cotisation
            Container(
              padding: const EdgeInsets.all(16),
              color: Theme.of(context).colorScheme.surfaceContainerHighest,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    widget.cotisation.membreNomComplet,
                    style: TextStyle(
                      fontSize: 16,
                      fontWeight: FontWeight.bold,
                      color: Theme.of(context).colorScheme.onSurface,
                    ),
                  ),
                  const SizedBox(height: 4),
                  Text(
                    widget.cotisation.libellePeriode,
                    style: TextStyle(
                      fontSize: 14,
                      color: Theme.of(context).colorScheme.onSurfaceVariant,
                    ),
                  ),
                  const SizedBox(height: 8),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        'Montant total:',
                        style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant),
                      ),
                      Text(
                        '${NumberFormat('#,###').format(widget.cotisation.montant)} ${widget.cotisation.devise}',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          color: Theme.of(context).colorScheme.onSurface,
                        ),
                      ),
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        'Déjà payé:',
                        style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant),
                      ),
                      Text(
                        '${NumberFormat('#,###').format(widget.cotisation.montantPaye ?? 0)} ${widget.cotisation.devise}',
                        style: TextStyle(color: ColorTokens.success),
                      ),
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        'Restant:',
                        style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant),
                      ),
                      Text(
                        '${NumberFormat('#,###').format(widget.cotisation.montantRestant)} ${widget.cotisation.devise}',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          color: ColorTokens.error,
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
            
            // Formulaire
            Expanded(
              child: SingleChildScrollView(
                padding: const EdgeInsets.all(16),
                child: Form(
                  key: _formKey,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      // Montant
                      TextFormField(
                        controller: _montantController,
                        decoration: InputDecoration(
                          labelText: 'Montant à payer *',
                          border: const OutlineInputBorder(),
                          prefixIcon: const Icon(Icons.attach_money),
                          suffixText: widget.cotisation.devise,
                        ),
                        keyboardType: TextInputType.number,
                        validator: (value) {
                          if (value == null || value.isEmpty) {
                            return 'Le montant est obligatoire';
                          }
                          final montant = double.tryParse(value);
                          if (montant == null || montant <= 0) {
                            return 'Montant invalide';
                          }
                          if (montant > widget.cotisation.montantRestant) {
                            return 'Montant supérieur au restant dû';
                          }
                          return null;
                        },
                      ),
                      const SizedBox(height: 12),
                      
                      // Méthode de paiement
                      DropdownButtonFormField<PaymentMethod>(
                        value: _selectedMethode,
                        decoration: const InputDecoration(
                          labelText: 'Méthode de paiement *',
                          border: OutlineInputBorder(),
                          prefixIcon: Icon(Icons.payment),
                        ),
                        items: PaymentMethod.values.map((methode) {
                          return DropdownMenuItem<PaymentMethod>(
                            value: methode,
                            child: Row(
                              children: [
                                PaymentMethodIcon(
                                  paymentMethodCode: methode.code,
                                  width: 24,
                                  height: 24,
                                ),
                                const SizedBox(width: 8),
                                Text(_getMethodeLabel(methode)),
                              ],
                            ),
                          );
                        }).toList(),
                        onChanged: (value) {
                          setState(() {
                            _selectedMethode = value!;
                          });
                        },
                      ),
                      if (_selectedMethode == PaymentMethod.waveMoney) ...[
                        const SizedBox(height: 12),
                        TextFormField(
                          controller: _wavePhoneController,
                          decoration: const InputDecoration(
                            labelText: 'Numéro Wave (9 chiffres) *',
                            border: OutlineInputBorder(),
                            prefixIcon: Icon(Icons.phone_android),
                            hintText: 'Ex: 771234567',
                          ),
                          keyboardType: TextInputType.number,
                          validator: (value) {
                            if (_selectedMethode != PaymentMethod.waveMoney) return null;
                            final digits = value?.replaceAll(RegExp(r'\D'), '') ?? '';
                            if (digits.length < 9) {
                              return 'Numéro Wave requis (9 chiffres) pour payer via Wave';
                            }
                            return null;
                          },
                        ),
                      ],
                      const SizedBox(height: 12),
                      // Date de paiement
                      InkWell(
                        onTap: () => _selectDate(context),
                        child: InputDecorator(
                          decoration: const InputDecoration(
                            labelText: 'Date de paiement *',
                            border: OutlineInputBorder(),
                            prefixIcon: Icon(Icons.calendar_today),
                          ),
                          child: Text(
                            DateFormat('dd/MM/yyyy').format(_datePaiement),
                          ),
                        ),
                      ),
                      const SizedBox(height: 12),
                      
                      // Référence
                      TextFormField(
                        controller: _referenceController,
                        decoration: const InputDecoration(
                          labelText: 'Référence de transaction',
                          border: OutlineInputBorder(),
                          prefixIcon: Icon(Icons.receipt),
                          hintText: 'Ex: TRX123456789',
                        ),
                      ),
                      const SizedBox(height: 12),
                      
                      // Notes
                      TextFormField(
                        controller: _notesController,
                        decoration: const InputDecoration(
                          labelText: 'Notes (optionnel)',
                          border: OutlineInputBorder(),
                          prefixIcon: Icon(Icons.note),
                        ),
                        maxLines: 2,
                      ),
                    ],
                  ),
                ),
              ),
            ),
            
            // Boutons d'action
            Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(
                color: Theme.of(context).colorScheme.surfaceContainerHighest,
                border: Border(top: BorderSide(color: Theme.of(context).colorScheme.outline)),
              ),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  TextButton(
                    onPressed: () => Navigator.pop(context),
                    child: const Text('Annuler'),
                  ),
                  const SizedBox(width: 12),
                  ElevatedButton(
                    onPressed: _waveLoading ? null : _submitForm,
                    style: ElevatedButton.styleFrom(
                      backgroundColor: ColorTokens.successLight,
                      foregroundColor: Colors.white,
                    ),
                    child: _waveLoading
                        ? const SizedBox(
                            width: 20,
                            height: 20,
                            child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white),
                          )
                        : Text(_selectedMethode == PaymentMethod.waveMoney
                            ? 'Ouvrir Wave pour payer'
                            : 'Enregistrer le paiement'),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  IconData _getMethodeIcon(PaymentMethod methode) {
    switch (methode) {
      case PaymentMethod.waveMoney:
        return Icons.phone_android;
      case PaymentMethod.orangeMoney:
        return Icons.phone_iphone;
      case PaymentMethod.freeMoney:
        return Icons.smartphone;
      case PaymentMethod.mobileMoney:
        return Icons.mobile_friendly;
      case PaymentMethod.especes:
        return Icons.money;
      case PaymentMethod.cheque:
        return Icons.receipt_long;
      case PaymentMethod.virement:
        return Icons.account_balance;
      case PaymentMethod.carteBancaire:
        return Icons.credit_card;
      case PaymentMethod.autre:
        return Icons.more_horiz;
    }
  }

  String _getMethodeLabel(PaymentMethod methode) {
    switch (methode) {
      case PaymentMethod.waveMoney:
        return 'Wave Money';
      case PaymentMethod.orangeMoney:
        return 'Orange Money';
      case PaymentMethod.freeMoney:
        return 'Free Money';
      case PaymentMethod.especes:
        return 'Espèces';
      case PaymentMethod.cheque:
        return 'Chèque';
      case PaymentMethod.virement:
        return 'Virement bancaire';
      case PaymentMethod.carteBancaire:
        return 'Carte bancaire';
      case PaymentMethod.mobileMoney:
        return 'Mobile Money (autre)';
      case PaymentMethod.autre:
        return 'Autre';
    }
  }

  Future<void> _selectDate(BuildContext context) async {
    final DateTime? picked = await showDatePicker(
      context: context,
      initialDate: _datePaiement,
      firstDate: DateTime(2020),
      lastDate: DateTime.now(),
    );
    if (picked != null && picked != _datePaiement) {
      setState(() {
        _datePaiement = picked;
      });
    }
  }

  Future<void> _submitForm() async {
    if (!_formKey.currentState!.validate()) return;

    if (_selectedMethode == PaymentMethod.waveMoney) {
      await _submitWavePayment();
      return;
    }

    final montant = double.parse(_montantController.text);
    // L’UI est rafraîchie par le BLoC après RecordPayment ; pas besoin de copyWith local.
    context.read<ContributionsBloc>().add(RecordPayment(
          contributionId: widget.cotisation.id!,
          montant: montant,
          methodePaiement: _selectedMethode,
          datePaiement: _datePaiement,
          reference: _referenceController.text.isNotEmpty ? _referenceController.text : null,
          notes: _notesController.text.isNotEmpty ? _notesController.text : null,
        ));
    Navigator.pop(context);
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text('Paiement enregistré avec succès'),
        backgroundColor: ColorTokens.success,
      ),
    );
  }

  /// Initie le paiement Wave : appel API Checkout, ouverture de l'app Wave, retour via deep link.
  Future<void> _submitWavePayment() async {
    if (widget.cotisation.id == null || widget.cotisation.id!.isEmpty) return;
    final phone = _wavePhoneController.text.replaceAll(RegExp(r'\D'), '');
    if (phone.length < 9) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Indiquez votre numéro Wave (9 chiffres)'), backgroundColor: AppColors.warning),
      );
      return;
    }
    setState(() => _waveLoading = true);
    try {
      final repo = getIt<IContributionRepository>();
      final result = await repo.initierPaiementEnLigne(
        cotisationId: widget.cotisation.id!,
        methodePaiement: 'WAVE',
        numeroTelephone: phone,
      );
      final url = result.waveLaunchUrl.isNotEmpty ? result.waveLaunchUrl : result.redirectUrl;
      if (url.isEmpty) throw Exception('URL Wave non reçue');

      // Mode dev/mock : simuler ET confirmer côté backend
      final isMock = url.contains('mock') || url.contains('localhost') || !AppConfig.isProd;
      if (isMock) {
        // Confirmer côté backend pour que la cotisation soit réellement payée
        final ref = (result.clientReference?.isNotEmpty == true)
            ? result.clientReference!
            : (result.intentionPaiementId ?? '');
        if (ref.isNotEmpty) {
          try {
            final repo = getIt<IContributionRepository>();
            // Appel direct via l'implémentation (confirmerMockPaiement n'est pas dans l'interface)
            if (repo is ContributionRepositoryImpl) {
              await repo.confirmerMockPaiement(ref);
            }
          } catch (_) {}
        }
        await Future.delayed(const Duration(milliseconds: 400));
        if (!mounted) return;
        Navigator.pop(context);
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Row(children: [
              Icon(Icons.science_rounded, color: AppColors.onPrimary, size: 16),
              const SizedBox(width: 8),
              const Expanded(child: Text('Paiement simulé et enregistré (mode dev)')),
            ]),
            backgroundColor: AppColors.success,
          ),
        );
        context.read<ContributionsBloc>().add(const LoadContributions());
        return;
      }

      // Mode prod : ouvrir Wave
      final uri = Uri.parse(url);
      if (await canLaunchUrl(uri)) {
        await launchUrl(uri, mode: LaunchMode.externalApplication);
      } else {
        await launchUrl(uri);
      }
      if (!mounted) return;
      Navigator.pop(context);
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(result.message),
          backgroundColor: AppColors.success,
        ),
      );
      context.read<ContributionsBloc>().add(const LoadContributions());
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Wave: ${e.toString().replaceFirst('Exception: ', '')}'),
          backgroundColor: AppColors.error,
        ),
      );
    } finally {
      if (mounted) setState(() => _waveLoading = false);
    }
  }
}

