import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:url_launcher/url_launcher.dart';

import '../../../../core/constants/lcb_ft_constants.dart';
import '../../../../core/data/repositories/parametres_lcb_ft_repository.dart';
import '../../data/models/transaction_epargne_request.dart';
import '../../data/repositories/transaction_epargne_repository.dart';

/// Dialogue de dépôt sur un compte épargne.
/// Deux modes : enregistrement manuel (LCB-FT) ou paiement via Wave (mobile money, même flux que cotisations).
class DepotEpargneDialog extends StatefulWidget {
  final String compteId;
  final VoidCallback? onSuccess;

  const DepotEpargneDialog({
    super.key,
    required this.compteId,
    this.onSuccess,
  });

  @override
  State<DepotEpargneDialog> createState() => _DepotEpargneDialogState();
}

enum _DepotMode { manual, wave }

class _DepotEpargneDialogState extends State<DepotEpargneDialog> {
  final _formKey = GlobalKey<FormState>();
  final _montantController = TextEditingController();
  final _motifController = TextEditingController();
  final _origineFondsController = TextEditingController();
  final _wavePhoneController = TextEditingController();
  bool _loading = false;
  bool _waveLoading = false;
  _DepotMode _mode = _DepotMode.manual;
  late TransactionEpargneRepository _repository;
  late ParametresLcbFtRepository _parametresRepository;

  /// Seuil LCB-FT récupéré depuis l'API (fallback à 500k XOF).
  double _seuilLcbFt = kSeuilOrigineFondsObligatoireXOF;
  bool _seuilLoaded = false;

  @override
  void initState() {
    super.initState();
    _repository = GetIt.I<TransactionEpargneRepository>();
    _parametresRepository = GetIt.I<ParametresLcbFtRepository>();
    _chargerSeuil();
  }

  /// Charge le seuil LCB-FT depuis l'API au chargement du dialog.
  Future<void> _chargerSeuil() async {
    final seuil = await _parametresRepository.getSeuilJustification();
    if (mounted) {
      setState(() {
        _seuilLcbFt = seuil.montantSeuil;
        _seuilLoaded = true;
      });
    }
  }

  bool get _origineFondsRequis {
    final m = double.tryParse(_montantController.text.replaceAll(',', '.'));
    return m != null && m >= _seuilLcbFt;
  }

  @override
  void dispose() {
    _montantController.dispose();
    _motifController.dispose();
    _origineFondsController.dispose();
    _wavePhoneController.dispose();
    super.dispose();
  }

  Future<void> _submitWave() async {
    final montant = double.tryParse(_montantController.text.replaceAll(',', '.'));
    if (montant == null || montant <= 0) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Indiquez un montant valide')),
      );
      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)')),
      );
      return;
    }
    setState(() => _waveLoading = true);
    try {
      final result = await _repository.initierDepotEpargneEnLigne(
        compteId: widget.compteId,
        montant: montant,
        numeroTelephone: phone,
      );
      final url = result.waveLaunchUrl.isNotEmpty ? result.waveLaunchUrl : result.redirectUrl;
      if (url.isEmpty) throw Exception('URL Wave non reçue');
      final uri = Uri.parse(url);
      if (await canLaunchUrl(uri)) {
        await launchUrl(uri, mode: LaunchMode.externalApplication);
      } else {
        await launchUrl(uri);
      }
      if (!mounted) return;
      Navigator.of(context).pop(true);
      widget.onSuccess?.call();
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(result.message)),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Wave: ${e.toString().replaceFirst('Exception: ', '')}')),
      );
    } finally {
      if (mounted) setState(() => _waveLoading = false);
    }
  }

  Future<void> _submit() async {
    if (!_formKey.currentState!.validate()) return;
    final montant = double.tryParse(_montantController.text.replaceAll(',', '.'));
    if (montant == null || montant <= 0) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Montant invalide')),
      );
      return;
    }
    if (_origineFondsRequis && (_origineFondsController.text.trim().isEmpty)) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(
            'L\'origine des fonds est obligatoire pour les opérations à partir de ${_seuilLcbFt.toStringAsFixed(0)} XOF (LCB-FT).',
          ),
        ),
      );
      return;
    }
    setState(() => _loading = true);
    try {
      final request = TransactionEpargneRequest(
        compteId: widget.compteId,
        typeTransaction: 'DEPOT',
        montant: montant,
        motif: _motifController.text.trim().isEmpty ? null : _motifController.text.trim(),
        origineFonds: _origineFondsController.text.trim().isEmpty ? null : _origineFondsController.text.trim(),
      );
      await _repository.executer(request);
      if (!mounted) return;
      Navigator.of(context).pop(true);
      widget.onSuccess?.call();
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Dépôt enregistré')),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Erreur: $e')),
      );
    } finally {
      if (mounted) setState(() => _loading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: const Text('Dépôt sur compte épargne'),
      content: Form(
        key: _formKey,
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              SegmentedButton<_DepotMode>(
                segments: const [
                  ButtonSegment(value: _DepotMode.manual, label: Text('Manuel'), icon: Icon(Icons.edit_note)),
                  ButtonSegment(value: _DepotMode.wave, label: Text('Wave'), icon: Icon(Icons.phone_android)),
                ],
                selected: {_mode},
                onSelectionChanged: (s) => setState(() => _mode = s.first),
              ),
              const SizedBox(height: 16),
              TextFormField(
                controller: _montantController,
                decoration: const InputDecoration(
                  labelText: 'Montant (XOF)',
                  border: OutlineInputBorder(),
                ),
                keyboardType: const TextInputType.numberWithOptions(decimal: true),
                validator: _mode == _DepotMode.manual
                    ? (v) {
                        if (v == null || v.isEmpty) return 'Obligatoire';
                        final n = double.tryParse(v.replaceAll(',', '.'));
                        if (n == null || n <= 0) return 'Montant invalide';
                        return null;
                      }
                    : null,
                onChanged: (_) => setState(() {}),
              ),
              if (_mode == _DepotMode.wave) ...[
                const SizedBox(height: 16),
                TextFormField(
                  controller: _wavePhoneController,
                  decoration: const InputDecoration(
                    labelText: 'Numéro Wave (9 chiffres) *',
                    hintText: 'Ex: 771234567',
                    border: OutlineInputBorder(),
                  ),
                  keyboardType: TextInputType.phone,
                  maxLength: 12,
                ),
              ] else ...[
                const SizedBox(height: 16),
                TextFormField(
                  controller: _motifController,
                  decoration: const InputDecoration(
                    labelText: 'Motif (optionnel)',
                    border: OutlineInputBorder(),
                  ),
                  maxLines: 2,
                ),
                const SizedBox(height: 16),
                TextFormField(
                  controller: _origineFondsController,
                  decoration: InputDecoration(
                    labelText: 'Origine des fonds (LCB-FT)',
                    hintText: _origineFondsRequis ? 'Obligatoire au-dessus du seuil' : 'Optionnel',
                    border: const OutlineInputBorder(),
                  ),
                  onChanged: (_) => setState(() {}),
                ),
                if (_origineFondsRequis)
                  Padding(
                    padding: const EdgeInsets.only(top: 8.0),
                    child: Text(
                      'Requis pour les opérations ≥ ${_seuilLcbFt.toStringAsFixed(0)} XOF',
                      style: Theme.of(context).textTheme.bodySmall?.copyWith(
                            color: Theme.of(context).colorScheme.primary,
                          ),
                    ),
                  ),
              ],
            ],
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: (_loading || _waveLoading) ? null : () => Navigator.of(context).pop(),
          child: const Text('Annuler'),
        ),
        if (_mode == _DepotMode.wave)
          FilledButton(
            onPressed: _waveLoading ? null : _submitWave,
            child: _waveLoading
                ? const SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2))
                : const Text('Ouvrir Wave'),
          )
        else
          FilledButton(
            onPressed: _loading ? null : _submit,
            child: _loading
                ? const SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2))
                : const Text('Enregistrer'),
          ),
      ],
    );
  }
}
