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

import '../../../authentication/data/models/user_role.dart';
import '../../../authentication/presentation/bloc/auth_bloc.dart';
import '../../data/models/compte_epargne_model.dart';
import '../../data/repositories/transaction_epargne_repository.dart';
import '../../../../shared/design_system/unionflow_design_system.dart';
import '../../../../shared/widgets/core_card.dart';
import '../../../../shared/widgets/info_badge.dart';
import '../widgets/creer_compte_epargne_dialog.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';
import 'epargne_detail_page.dart';

/// Page listant les comptes épargne — rendu bank-grade : récap, cartes avec actions (Dépôt, Retrait, Transfert, Détail, Historique).
class EpargnePage extends StatefulWidget {
  const EpargnePage({super.key});

  @override
  State<EpargnePage> createState() => _EpargnePageState();
}

class _EpargnePageState extends State<EpargnePage> {
  List<CompteEpargneModel> _comptes = [];
  bool _loading = true;
  String? _error;

  @override
  void initState() {
    super.initState();
    _loadComptes();
  }

  Future<void> _loadComptes() async {
    final authState = context.read<AuthBloc>().state;
    if (authState is! AuthAuthenticated) {
      if (!mounted) return;
      setState(() {
        _loading = false;
        _error = 'Non connecté';
      });
      return;
    }

    if (!mounted) return;
    setState(() {
      _loading = true;
      _error = null;
    });

    try {
      final compteRepo = GetIt.I<CompteEpargneRepository>();
      final list = await compteRepo.getMesComptes();
      if (!mounted) return;
      setState(() {
        _comptes = list;
        _loading = false;
        _error = null;
      });
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _comptes = [];
        _loading = false;
        _error = 'Erreur: ${e.toString().replaceFirst('Exception: ', '')}';
      });
    }
  }

  void _openDepot(CompteEpargneModel compte) {
    if (compte.id == null) return;
    showDialog<bool>(
      context: context,
      builder: (ctx) => DepotEpargneDialog(
        compteId: compte.id!,
        onSuccess: _loadComptes,
      ),
    ).then((_) => _loadComptes());
  }

  void _openRetrait(CompteEpargneModel compte) {
    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: _loadComptes,
      ),
    ).then((_) => _loadComptes());
  }

  void _openTransfert(CompteEpargneModel compte) {
    if (compte.id == null) return;
    showDialog<bool>(
      context: context,
      builder: (ctx) => TransfertEpargneDialog(
        compteSource: compte,
        tousLesComptes: _comptes,
        onSuccess: _loadComptes,
      ),
    ).then((_) => _loadComptes());
  }

  void _openDetail(CompteEpargneModel compte) {
    Navigator.of(context).push(
      MaterialPageRoute<void>(
        builder: (ctx) => EpargneDetailPage(
          compte: compte,
          tousLesComptes: _comptes,
          onDataChanged: _loadComptes,
        ),
      ),
    ).then((_) => _loadComptes());
  }

  void _openHistorique(CompteEpargneModel compte) {
    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;
  }

  bool _canCreateCompte(BuildContext context) {
    final state = context.read<AuthBloc>().state;
    if (state is! AuthAuthenticated) return false;
    final role = state.effectiveRole;
    return role == UserRole.superAdmin || role == UserRole.orgAdmin;
  }

  void _openCreerCompte() {
    showDialog<bool>(
      context: context,
      builder: (ctx) => CreerCompteEpargneDialog(onCreated: _loadComptes),
    ).then((_) => _loadComptes());
  }

  Widget _buildRecapCard() {
    double total = 0;
    for (final c in _comptes) {
      total += (c.soldeActuel - c.soldeBloque).clamp(0.0, double.infinity);
    }
    return CoreCard(
      padding: const EdgeInsets.all(SpacingTokens.lg),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(
                'VUE D\'ENSEMBLE',
                style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold),
              ),
              const Icon(Icons.account_balance_wallet, color: AppColors.primaryGreen, size: 24),
            ],
          ),
          const SizedBox(height: SpacingTokens.md),
          Text(
            '${total.toStringAsFixed(0)} XOF',
            style: AppTypography.headerSmall.copyWith(fontSize: 24, color: AppColors.primaryGreen),
          ),
          const SizedBox(height: SpacingTokens.xs),
          Text(
            'Solde disponible total • ${_comptes.length} compte${_comptes.length > 1 ? 's' : ''}',
            style: AppTypography.bodyTextSmall.copyWith(color: AppColors.textSecondaryLight),
          ),
        ],
      ),
    );
  }

  Widget _buildCompteCard(CompteEpargneModel c) {
    final typeLibelle = _typeCompteLibelle(c.typeCompte);
    final dateStr = c.dateOuverture != null
        ? 'Ouvert le ${c.dateOuverture!.day.toString().padLeft(2, '0')}/${c.dateOuverture!.month.toString().padLeft(2, '0')}/${c.dateOuverture!.year}'
        : null;
    final soldeDispo = (c.soldeActuel - c.soldeBloque).clamp(0.0, double.infinity);
    final actif = c.statut == 'ACTIF';
    final canTransfert = _comptes.length > 1;

    return CoreCard(
      margin: const EdgeInsets.only(bottom: SpacingTokens.md),
      padding: const EdgeInsets.all(SpacingTokens.md),
      onTap: () => _openDetail(c),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      c.numeroCompte ?? 'Compte ${c.id ?? ""}',
                      style: AppTypography.actionText,
                    ),
                    if (typeLibelle != null)
                      Text(
                        typeLibelle,
                        style: AppTypography.subtitleSmall.copyWith(color: AppColors.textSecondaryLight),
                      ),
                    if (dateStr != null)
                      Text(
                        dateStr,
                        style: AppTypography.bodyTextSmall.copyWith(fontSize: 10, color: AppColors.textSecondaryLight),
                      ),
                  ],
                ),
              ),
              if (c.statut != null)
                 InfoBadge(
                   text: c.statut!,
                   backgroundColor: c.statut == 'ACTIF' ? AppColors.success : AppColors.textSecondaryLight,
                 ),
            ],
          ),
          const SizedBox(height: SpacingTokens.md),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text('SOLDE ACTUEL', style: AppTypography.subtitleSmall.copyWith(fontSize: 8, fontWeight: FontWeight.bold)),
                  Text(
                    '${c.soldeActuel.toStringAsFixed(0)} XOF',
                    style: AppTypography.headerSmall.copyWith(fontSize: 14, color: AppColors.primaryGreen),
                  ),
                ],
              ),
              if (c.soldeBloque > 0)
                Column(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [
                    Text('BLOQUÉ', style: AppTypography.subtitleSmall.copyWith(fontSize: 8, fontWeight: FontWeight.bold)),
                    Text(
                      '${c.soldeBloque.toStringAsFixed(0)} XOF',
                      style: AppTypography.bodyTextSmall.copyWith(fontSize: 12, color: AppColors.error),
                    ),
                  ],
                ),
            ],
          ),
          if (c.description != null && c.description!.isNotEmpty) ...[
            const SizedBox(height: SpacingTokens.sm),
            Text(
              c.description!,
              style: AppTypography.bodyTextSmall.copyWith(fontSize: 11, color: AppColors.textSecondaryLight),
              maxLines: 2,
              overflow: TextOverflow.ellipsis,
            ),
          ],
          if (actif) ...[
            const SizedBox(height: SpacingTokens.md),
            const Divider(height: 1),
            const SizedBox(height: SpacingTokens.sm),
            Row(
              children: [
                Expanded(
                  child: FilledButton.tonal(
                    onPressed: () => _openDepot(c),
                    style: FilledButton.styleFrom(
                      padding: const EdgeInsets.symmetric(vertical: SpacingTokens.sm),
                      backgroundColor: AppColors.primaryGreen.withOpacity(0.1),
                      foregroundColor: AppColors.primaryGreen,
                    ),
                    child: const Text('Dépôt', style: TextStyle(fontSize: 12)),
                  ),
                ),
                const SizedBox(width: SpacingTokens.xs),
                Expanded(
                  child: FilledButton.tonal(
                    onPressed: soldeDispo > 0 ? () => _openRetrait(c) : null,
                    style: FilledButton.styleFrom(
                      padding: const EdgeInsets.symmetric(vertical: SpacingTokens.sm),
                      backgroundColor: AppColors.primaryGreen.withOpacity(0.1),
                      foregroundColor: AppColors.primaryGreen,
                    ),
                    child: const Text('Retrait', style: TextStyle(fontSize: 12)),
                  ),
                ),
                if (canTransfert) ...[
                  const SizedBox(width: SpacingTokens.xs),
                  Expanded(
                    child: FilledButton.tonal(
                      onPressed: soldeDispo > 0 ? () => _openTransfert(c) : null,
                      style: FilledButton.styleFrom(
                        padding: const EdgeInsets.symmetric(vertical: SpacingTokens.sm),
                        backgroundColor: AppColors.primaryGreen.withOpacity(0.1),
                        foregroundColor: AppColors.primaryGreen,
                      ),
                      child: const Text('Transférer', style: TextStyle(fontSize: 12)),
                    ),
                  ),
                ],
              ],
            ),
            const SizedBox(height: SpacingTokens.xs),
            Row(
              children: [
                Expanded(
                  child: OutlinedButton.icon(
                    onPressed: () => _openDetail(c),
                    icon: const Icon(Icons.info_outline, size: 16),
                    label: const Text('Détail', style: TextStyle(fontSize: 12)),
                    style: OutlinedButton.styleFrom(
                      padding: const EdgeInsets.symmetric(vertical: SpacingTokens.sm),
                      foregroundColor: AppColors.textPrimaryLight,
                    ),
                  ),
                ),
                const SizedBox(width: SpacingTokens.xs),
                Expanded(
                  child: OutlinedButton.icon(
                    onPressed: () => _openHistorique(c),
                    icon: const Icon(Icons.history, size: 16),
                    label: const Text('Historique', style: TextStyle(fontSize: 12)),
                    style: OutlinedButton.styleFrom(
                      padding: const EdgeInsets.symmetric(vertical: SpacingTokens.sm),
                      foregroundColor: AppColors.textPrimaryLight,
                    ),
                  ),
                ),
              ],
            ),
          ],
        ],
      ),
    );
  }

  Widget _buildBodyContent() {
    if (_loading) {
      return const Center(child: CircularProgressIndicator());
    }
    if (_error != null) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.all(SpacingTokens.lg),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Icon(Icons.error_outline, size: 48, color: AppColors.error),
              const SizedBox(height: SpacingTokens.md),
              Text(
                _error!,
                style: AppTypography.bodyTextSmall.copyWith(color: AppColors.error),
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: SpacingTokens.lg),
              FilledButton(
                onPressed: _loadComptes,
                child: const Text('Réessayer'),
              ),
            ],
          ),
        ),
      );
    }
    if (_comptes.isEmpty) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: SpacingTokens.xl),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Icon(Icons.savings_outlined, size: 64, color: AppColors.textSecondaryLight),
              const SizedBox(height: SpacingTokens.lg),
              Text(
                'Aucun compte épargne',
                style: AppTypography.actionText.copyWith(color: AppColors.textSecondaryLight),
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: SpacingTokens.sm),
              Text(
                'Votre organisation peut ouvrir un compte épargne pour vous. Contactez-la pour en bénéficier.',
                style: AppTypography.bodyTextSmall.copyWith(color: AppColors.textSecondaryLight),
                textAlign: TextAlign.center,
              ),
            ],
          ),
        ),
      );
    }
    return RefreshIndicator(
      onRefresh: _loadComptes,
      child: ListView(
        padding: const EdgeInsets.all(SpacingTokens.lg),
        children: [
          _buildRecapCard(),
          const SizedBox(height: SpacingTokens.lg),
          ..._comptes.map(_buildCompteCard),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final showFab = _canCreateCompte(context);
    return Scaffold(
      backgroundColor: AppColors.background,
      appBar: const UFAppBar(
        title: 'COMPTES ÉPARGNE',
        backgroundColor: AppColors.surface,
        foregroundColor: AppColors.textPrimaryLight,
      ),
      body: _buildBodyContent(),
      floatingActionButton: showFab
          ? FloatingActionButton(
              onPressed: _openCreerCompte,
              tooltip: 'Créer un compte épargne pour un membre',
              backgroundColor: AppColors.primaryGreen,
              foregroundColor: Colors.white,
              child: const Icon(Icons.add),
            )
          : null,
    );
  }
}
