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

import '../../../../core/utils/logger.dart';
import '../../data/models/compte_epargne_model.dart';
import '../../data/models/transaction_epargne_model.dart';
import '../../data/repositories/transaction_epargne_repository.dart'; // CompteEpargneRepository + TransactionEpargneRepository
import '../../../../shared/design_system/unionflow_design_system.dart';
import '../widgets/depot_epargne_dialog.dart';
import '../widgets/retrait_epargne_dialog.dart';
import '../widgets/transfert_epargne_dialog.dart';
import '../widgets/historique_epargne_sheet.dart';

/// Page détail d'un compte épargne : solde, infos, actions (Dépôt, Retrait, Transfert), dernieres transactions.
class EpargneDetailPage extends StatefulWidget {
  final CompteEpargneModel compte;
  final List<CompteEpargneModel> tousLesComptes;
  final VoidCallback? onDataChanged;

  const EpargneDetailPage({
    super.key,
    required this.compte,
    required this.tousLesComptes,
    this.onDataChanged,
  });

  @override
  State<EpargneDetailPage> createState() => _EpargneDetailPageState();
}

class _EpargneDetailPageState extends State<EpargneDetailPage> {
  List<TransactionEpargneModel> _transactions = [];
  bool _loadingTx = true;
  String? _errorTx;
  CompteEpargneModel? _compte; // rafraîchi après actions

  @override
  void initState() {
    super.initState();
    _compte = widget.compte;
    _loadTransactions();
  }

  Future<void> _refreshCompte() async {
    try {
      final repo = GetIt.I<CompteEpargneRepository>();
      if (_compte?.id != null) {
        final c = await repo.getById(_compte!.id!);
        if (c != null && mounted) setState(() => _compte = c);
      }
    } catch (e, st) {
      AppLogger.error('EpargneDetailPage: _refreshCompte échoué', error: e, stackTrace: st);
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Impossible de rafraîchir le compte')),
        );
      }
    }
  }

  Future<void> _loadTransactions() async {
    if (_compte?.id == null) {
      setState(() {
        _loadingTx = false;
        _transactions = [];
      });
      return;
    }
    setState(() {
      _loadingTx = true;
      _errorTx = null;
    });
    try {
      final repo = GetIt.I<TransactionEpargneRepository>();
      final list = await repo.getByCompte(_compte!.id!);
      if (!mounted) return;
      setState(() {
        _transactions = list.map((e) => TransactionEpargneModel.fromJson(e)).toList();
        _loadingTx = false;
        _errorTx = null;
      });
    } catch (e, st) {
      AppLogger.error('EpargneDetailPage: _loadTransactions échoué', error: e, stackTrace: st);
      if (!mounted) return;
      setState(() {
        _transactions = [];
        _loadingTx = false;
        _errorTx = e.toString().replaceFirst('Exception: ', '');
      });
    }
  }

  void _openDepot() {
    if (_compte?.id == null) return;
    showDialog<bool>(
      context: context,
      builder: (ctx) => DepotEpargneDialog(
        compteId: _compte!.id!,
        onSuccess: () {
          _refreshCompte();
          _loadTransactions();
          widget.onDataChanged?.call();
        },
      ),
    ).then((_) => _refreshCompte());
  }

  void _openRetrait() {
    if (_compte?.id == null) return;
    final soldeDispo = (_compte!.soldeActuel - _compte!.soldeBloque).clamp(0.0, double.infinity);
    showDialog<bool>(
      context: context,
      builder: (ctx) => RetraitEpargneDialog(
        compteId: _compte!.id!,
        numeroCompte: _compte!.numeroCompte ?? _compte!.id!,
        soldeDisponible: soldeDispo,
        onSuccess: () {
          _refreshCompte();
          _loadTransactions();
          widget.onDataChanged?.call();
        },
      ),
    ).then((_) => _refreshCompte());
  }

  void _openTransfert() {
    if (_compte?.id == null) return;
    showDialog<bool>(
      context: context,
      builder: (ctx) => TransfertEpargneDialog(
        compteSource: _compte!,
        tousLesComptes: widget.tousLesComptes,
        onSuccess: () {
          _refreshCompte();
          _loadTransactions();
          widget.onDataChanged?.call();
        },
      ),
    ).then((_) => _refreshCompte());
  }

  void _openHistorique() {
    if (_compte?.id == null) return;
    showModalBottomSheet<void>(
      context: context,
      isScrollControlled: true,
      useSafeArea: true,
      builder: (ctx) => HistoriqueEpargneSheet(compte: _compte!),
    );
  }

  String? _typeCompteLibelle(String? code) {
    if (code == null) return null;
    const map = {
      'COURANT': 'Compte courant',
      'EPARGNE_LIBRE': 'Épargne libre',
      'EPARGNE_BLOQUEE': 'Épargne bloquée',
      'DEPOT_A_TERME': 'Dépôt à terme',
      'EPARGNE_PROJET': 'Épargne projet',
    };
    return map[code] ?? code;
  }

  @override
  Widget build(BuildContext context) {
    final c = _compte ?? widget.compte;
    final soldeDispo = (c.soldeActuel - c.soldeBloque).clamp(0.0, double.infinity);
    final actif = c.statut == 'ACTIF';

    return Scaffold(
      appBar: AppBar(
        title: const Text('Détail du compte'),
        backgroundColor: Colors.transparent,
        elevation: 0,
        foregroundColor: ColorTokens.onSurface,
        actions: [
          IconButton(
            icon: const Icon(Icons.history),
            onPressed: _transactions.isEmpty ? null : _openHistorique,
            tooltip: 'Historique',
          ),
        ],
      ),
      body: Container(
        width: double.infinity,
        decoration: BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            colors: [
              const Color(0xFFfafaf9),
              const Color(0xFFfafaf9).withOpacity(0.85),
            ],
          ),
        ),
        child: SafeArea(
          child: RefreshIndicator(
            onRefresh: () async {
              await _refreshCompte();
              await _loadTransactions();
            },
            child: SingleChildScrollView(
              physics: const AlwaysScrollableScrollPhysics(),
              padding: const EdgeInsets.all(SpacingTokens.lg),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Card(
                    elevation: 2,
                    shadowColor: ColorTokens.shadow,
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(RadiusTokens.lg)),
                    child: Padding(
                      padding: const EdgeInsets.all(SpacingTokens.lg),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            c.numeroCompte ?? c.id ?? '—',
                            style: TypographyTokens.titleMedium?.copyWith(
                              color: ColorTokens.onSurfaceVariant,
                              letterSpacing: 0.5,
                            ),
                          ),
                          if (_typeCompteLibelle(c.typeCompte) != null)
                            Text(
                              _typeCompteLibelle(c.typeCompte)!,
                              style: TypographyTokens.bodySmall?.copyWith(color: ColorTokens.onSurfaceVariant),
                            ),
                          const SizedBox(height: SpacingTokens.md),
                          Text(
                            '${c.soldeActuel.toStringAsFixed(0)} XOF',
                            style: TypographyTokens.headlineMedium?.copyWith(
                              fontWeight: FontWeight.bold,
                              color: ColorTokens.primary,
                            ),
                          ),
                          if (c.soldeBloque > 0)
                            Text(
                              'dont ${c.soldeBloque.toStringAsFixed(0)} XOF bloqué(s)',
                              style: TypographyTokens.bodySmall?.copyWith(color: ColorTokens.onSurfaceVariant),
                            ),
                          Text(
                            'Disponible: ${soldeDispo.toStringAsFixed(0)} XOF',
                            style: TypographyTokens.labelMedium?.copyWith(color: ColorTokens.primary),
                          ),
                          if (c.dateOuverture != null)
                            Padding(
                              padding: const EdgeInsets.only(top: SpacingTokens.sm),
                              child: Text(
                                'Ouvert le ${c.dateOuverture!.day.toString().padLeft(2, '0')}/${c.dateOuverture!.month.toString().padLeft(2, '0')}/${c.dateOuverture!.year}',
                                style: TypographyTokens.bodySmall?.copyWith(color: ColorTokens.onSurfaceVariant),
                              ),
                            ),
                          if (c.description != null && c.description!.isNotEmpty)
                            Padding(
                              padding: const EdgeInsets.only(top: SpacingTokens.xs),
                              child: Text(
                                c.description!,
                                style: TypographyTokens.bodySmall?.copyWith(color: ColorTokens.onSurfaceVariant),
                                maxLines: 2,
                                overflow: TextOverflow.ellipsis,
                              ),
                            ),
                        ],
                      ),
                    ),
                  ),
                  const SizedBox(height: SpacingTokens.lg),
                  if (actif) ...[
                    Row(
                      children: [
                        Expanded(
                          child: FilledButton.icon(
                            onPressed: _openDepot,
                            icon: const Icon(Icons.add_circle_outline, size: 20),
                            label: const Text('Dépôt'),
                          ),
                        ),
                        const SizedBox(width: SpacingTokens.sm),
                        Expanded(
                          child: FilledButton.tonalIcon(
                            onPressed: soldeDispo > 0 ? _openRetrait : null,
                            icon: const Icon(Icons.remove_circle_outline, size: 20),
                            label: const Text('Retrait'),
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(height: SpacingTokens.sm),
                    SizedBox(
                      width: double.infinity,
                      child: OutlinedButton.icon(
                        onPressed: widget.tousLesComptes.length > 1 ? _openTransfert : null,
                        icon: const Icon(Icons.swap_horiz, size: 20),
                        label: const Text('Transfert vers un autre compte'),
                      ),
                    ),
                    const SizedBox(height: SpacingTokens.lg),
                  ],
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        'Dernières opérations',
                        style: TypographyTokens.titleSmall,
                      ),
                      TextButton(
                        onPressed: _openHistorique,
                        child: const Text('Voir tout'),
                      ),
                    ],
                  ),
                  if (_loadingTx)
                    const Padding(
                      padding: EdgeInsets.all(SpacingTokens.xl),
                      child: Center(child: CircularProgressIndicator()),
                    )
                  else if (_errorTx != null)
                    Padding(
                      padding: const EdgeInsets.all(SpacingTokens.md),
                      child: Column(
                        children: [
                          Text(_errorTx!, style: TextStyle(color: ColorTokens.error)),
                          const SizedBox(height: 8),
                          FilledButton.tonal(
                            onPressed: _loadTransactions,
                            child: const Text('Réessayer'),
                          ),
                        ],
                      ),
                    )
                  else if (_transactions.isEmpty)
                    Padding(
                      padding: const EdgeInsets.all(SpacingTokens.lg),
                      child: Text(
                        'Aucune transaction',
                        style: TypographyTokens.bodySmall?.copyWith(color: ColorTokens.onSurfaceVariant),
                        textAlign: TextAlign.center,
                      ),
                    )
                  else
                    Card(
                      child: Column(
                        children: _transactions.take(10).map((t) {
                          return ListTile(
                            leading: CircleAvatar(
                              backgroundColor: t.isCredit ? ColorTokens.success.withOpacity(0.2) : ColorTokens.error.withOpacity(0.2),
                              child: Icon(
                                t.isCredit ? Icons.arrow_downward : Icons.arrow_upward,
                                color: t.isCredit ? ColorTokens.success : ColorTokens.error,
                                size: 20,
                              ),
                            ),
                            title: Text(
                              _libelleType(t.type),
                              style: TypographyTokens.bodyMedium,
                            ),
                            subtitle: t.dateTransaction != null
                                ? Text(
                                    '${t.dateTransaction!.day.toString().padLeft(2, '0')}/${t.dateTransaction!.month.toString().padLeft(2, '0')}/${t.dateTransaction!.year} ${t.dateTransaction!.hour.toString().padLeft(2, '0')}:${t.dateTransaction!.minute.toString().padLeft(2, '0')}',
                                    style: TypographyTokens.bodySmall?.copyWith(color: ColorTokens.onSurfaceVariant),
                                  )
                                : null,
                            trailing: Text(
                              '${t.isCredit ? '+' : '-'}${t.montant.toStringAsFixed(0)} XOF',
                              style: TypographyTokens.titleSmall?.copyWith(
                                color: t.isCredit ? ColorTokens.success : ColorTokens.error,
                                fontWeight: FontWeight.w600,
                              ),
                            ),
                          );
                        }).toList(),
                      ),
                    ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  String _libelleType(String? type) {
    if (type == null) return '—';
    const map = {
      'DEPOT': 'Dépôt',
      'RETRAIT': 'Retrait',
      'TRANSFERT_ENTRANT': 'Virement reçu',
      'TRANSFERT_SORTANT': 'Virement envoyé',
    };
    return map[type] ?? type;
  }
}
