import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:file_picker/file_picker.dart';

import '../../../../core/constants/lcb_ft_constants.dart';
import '../../../../core/data/repositories/parametres_lcb_ft_repository.dart';
import '../../../../core/utils/error_formatter.dart';
import '../../data/models/compte_epargne_model.dart';
import '../../data/models/transaction_epargne_request.dart';
import '../../data/repositories/transaction_epargne_repository.dart';
import '../../data/services/document_upload_service.dart';
import '../../../../shared/design_system/unionflow_design_system.dart';

/// Dialogue de transfert entre deux comptes épargne du membre.
class TransfertEpargneDialog extends StatefulWidget {
  final CompteEpargneModel compteSource;
  final List<CompteEpargneModel> tousLesComptes;
  final VoidCallback? onSuccess;

  const TransfertEpargneDialog({
    super.key,
    required this.compteSource,
    required this.tousLesComptes,
    this.onSuccess,
  });

  @override
  State<TransfertEpargneDialog> createState() => _TransfertEpargneDialogState();
}

class _TransfertEpargneDialogState extends State<TransfertEpargneDialog> {
  final _formKey = GlobalKey<FormState>();
  final _montantController = TextEditingController();
  final _motifController = TextEditingController();
  final _origineFondsController = TextEditingController();
  bool _loading = false;
  bool _uploadingDocument = false;
  String? _compteDestinationId;
  late TransactionEpargneRepository _repository;
  late ParametresLcbFtRepository _parametresRepository;
  late DocumentUploadService _uploadService;

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

  /// Pièce justificative pour opérations au-dessus du seuil
  File? _pieceJustificative;
  String? _pieceJustificativeId;

  List<CompteEpargneModel> get _comptesDestination {
    if (widget.compteSource.id == null) return [];
    return widget.tousLesComptes
        .where((c) => c.id != null && c.id != widget.compteSource.id && c.statut == 'ACTIF')
        .toList();
  }

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

  @override
  void initState() {
    super.initState();
    _repository = GetIt.I<TransactionEpargneRepository>();
    _parametresRepository = GetIt.I<ParametresLcbFtRepository>();
    _uploadService = GetIt.I<DocumentUploadService>();
    if (_comptesDestination.isNotEmpty) _compteDestinationId = _comptesDestination.first.id;
    _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;
      });
    }
  }

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

  /// Choisir et uploader une pièce justificative (photo ou PDF)
  Future<void> _choisirPieceJustificative() async {
    try {
      final result = await FilePicker.platform.pickFiles(
        type: FileType.custom,
        allowedExtensions: ['jpg', 'jpeg', 'png', 'pdf'],
        allowMultiple: false,
      );

      if (result == null || result.files.isEmpty) return;

      final file = File(result.files.single.path!);
      setState(() {
        _uploadingDocument = true;
        _pieceJustificative = file;
      });

      // Upload du fichier
      final documentId = await _uploadService.uploadDocument(
        file: file,
        description: 'Pièce justificative - Transfert épargne',
        typeDocument: 'PIECE_JUSTIFICATIVE',
      );

      if (!mounted) return;
      setState(() {
        _pieceJustificativeId = documentId;
        _uploadingDocument = false;
      });

      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('✓ Pièce justificative uploadée avec succès'),
          backgroundColor: ColorTokens.success,
        ),
      );
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _uploadingDocument = false;
        _pieceJustificative = null;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Erreur upload : ${e.toString()}'),
          backgroundColor: ColorTokens.error,
        ),
      );
    }
  }

  Future<void> _submit() async {
    if (!_formKey.currentState!.validate()) return;
    if (_compteDestinationId == null || _compteDestinationId!.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Sélectionnez un compte de destination')),
      );
      return;
    }
    final montant = double.tryParse(_montantController.text.replaceAll(',', '.'));
    if (montant == null || montant <= 0) {
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Montant invalide')));
      return;
    }
    final soldeDispo = widget.compteSource.soldeActuel - widget.compteSource.soldeBloque;
    if (montant > soldeDispo) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Solde disponible insuffisant (${soldeDispo.toStringAsFixed(0)} XOF)')),
      );
      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;
    }
    if (_origineFondsRequis && _pieceJustificativeId == null) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(
            'Une pièce justificative est requise pour les opérations ≥ ${_seuilLcbFt.toStringAsFixed(0)} XOF (LCB-FT).',
          ),
          duration: const Duration(seconds: 4),
        ),
      );
      return;
    }
    setState(() => _loading = true);
    try {
      final request = TransactionEpargneRequest(
        compteId: widget.compteSource.id!,
        typeTransaction: 'TRANSFERT_SORTANT',
        montant: montant,
        compteDestinationId: _compteDestinationId,
        motif: _motifController.text.trim().isEmpty ? null : _motifController.text.trim(),
        origineFonds: _origineFondsController.text.trim().isEmpty ? null : _origineFondsController.text.trim(),
        pieceJustificativeId: _pieceJustificativeId,
      );
      await _repository.transferer(request);
      if (!mounted) return;
      Navigator.of(context).pop(true);
      widget.onSuccess?.call();
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Transfert effectué'), backgroundColor: ColorTokens.success),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(ErrorFormatter.format(e)),
          backgroundColor: ColorTokens.error,
          duration: ErrorFormatter.isLcbFtError(e) ? const Duration(seconds: 6) : const Duration(seconds: 3),
        ),
      );
    } finally {
      if (mounted) setState(() => _loading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    final destinations = _comptesDestination;
    if (destinations.isEmpty) {
      return AlertDialog(
        title: const Text('Transfert'),
        content: const Text(
          'Vous n\'avez pas d\'autre compte épargne actif pour effectuer un transfert.',
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('Fermer'),
          ),
        ],
      );
    }
    return AlertDialog(
      title: const Text('Transfert entre comptes'),
      content: Form(
        key: _formKey,
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'De: ${widget.compteSource.numeroCompte ?? widget.compteSource.id}',
                style: TypographyTokens.bodySmall.copyWith(color: ColorTokens.onSurfaceVariant),
              ),
              Text(
                'Solde disponible: ${(widget.compteSource.soldeActuel - widget.compteSource.soldeBloque).toStringAsFixed(0)} XOF',
                style: TypographyTokens.titleSmall,
              ),
              const SizedBox(height: 16),
              DropdownButtonFormField<String>(
                value: _compteDestinationId,
                isExpanded: true,
                decoration: const InputDecoration(
                  labelText: 'Compte de destination',
                  border: OutlineInputBorder(),
                ),
                items: destinations
                    .map((c) => DropdownMenuItem(
                          value: c.id,
                          child: Text(
                            '${c.numeroCompte ?? c.id} — ${c.soldeActuel.toStringAsFixed(0)} XOF',
                            overflow: TextOverflow.ellipsis,
                            maxLines: 1,
                          ),
                        ))
                    .toList(),
                onChanged: (v) => setState(() => _compteDestinationId = v),
              ),
              const SizedBox(height: 16),
              TextFormField(
                controller: _montantController,
                decoration: const InputDecoration(
                  labelText: 'Montant (XOF)',
                  border: OutlineInputBorder(),
                ),
                keyboardType: const TextInputType.numberWithOptions(decimal: true),
                validator: (v) {
                  if (v == null || v.isEmpty) return 'Obligatoire';
                  final n = double.tryParse(v.replaceAll(',', '.'));
                  if (n == null || n <= 0) return 'Montant invalide';
                  final solde = widget.compteSource.soldeActuel - widget.compteSource.soldeBloque;
                  if (n > solde) return 'Solde insuffisant';
                  return null;
                },
                onChanged: (_) => setState(() {}),
              ),
              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),
                  child: Text(
                    'Requis pour les opérations ≥ ${_seuilLcbFt.toStringAsFixed(0)} XOF',
                    style: TypographyTokens.bodySmall.copyWith(color: ColorTokens.primary),
                  ),
                ),
              if (_origineFondsRequis) ...[
                const SizedBox(height: 16),
                OutlinedButton.icon(
                  onPressed: _uploadingDocument ? null : _choisirPieceJustificative,
                  icon: _uploadingDocument
                      ? const SizedBox(
                          width: 16,
                          height: 16,
                          child: CircularProgressIndicator(strokeWidth: 2),
                        )
                      : Icon(
                          _pieceJustificativeId != null ? Icons.check_circle : Icons.attach_file,
                          color: _pieceJustificativeId != null ? AppColors.success : null,
                        ),
                  label: Text(
                    _pieceJustificativeId != null
                        ? 'Pièce justificative uploadée'
                        : 'Joindre une pièce justificative *',
                  ),
                  style: OutlinedButton.styleFrom(
                    minimumSize: const Size(double.infinity, 48),
                    side: _pieceJustificativeId != null
                        ? const BorderSide(color: AppColors.success)
                        : null,
                  ),
                ),
                if (_pieceJustificative != null)
                  Padding(
                    padding: const EdgeInsets.only(top: 4.0),
                    child: Text(
                      _pieceJustificative!.path.split('/').last,
                      style: Theme.of(context).textTheme.bodySmall,
                      overflow: TextOverflow.ellipsis,
                    ),
                  ),
                Padding(
                  padding: const EdgeInsets.only(top: 4.0),
                  child: Text(
                    'Photo ou PDF (max 5 MB)',
                    style: Theme.of(context).textTheme.bodySmall?.copyWith(
                          color: AppColors.textTertiary,
                        ),
                  ),
                ),
              ],
            ],
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: _loading ? null : () => Navigator.of(context).pop(),
          child: const Text('Annuler'),
        ),
        FilledButton(
          onPressed: _loading ? null : _submit,
          child: _loading
              ? const SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2))
              : const Text('Transférer'),
        ),
      ],
    );
  }
}
