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

import '../../../core/api/api_client.dart';
import '../../boloes/data/ciclo_vida_repository.dart';
import '../../boloes/presentation/encerramento_dialog.dart';
import '../../boloes/presentation/recriar_temporada_dialog.dart';
import '../../../core/tema/tema.dart';

/// Histórico de bolões encerrados e títulos (CV-5).
///
/// É a memória da competição: sem ela, ganhar o bolão não deixa marca nenhuma
/// depois que o campeonato acaba.
class HistoricoPage extends ConsumerStatefulWidget {
  const HistoricoPage({super.key});

  @override
  ConsumerState<HistoricoPage> createState() => _HistoricoPageState();
}

class _HistoricoPageState extends ConsumerState<HistoricoPage> {
  List<ParticipacaoEncerrada>? _lista;
  String? _erro;
  bool _carregando = true;

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

  Future<void> _carregar() async {
    setState(() => _erro = null);
    try {
      final l = await ref.read(cicloVidaRepositoryProvider).historico();
      if (!mounted) return;
      setState(() => _lista = l);
    } on ApiError catch (e) {
      if (mounted) setState(() => _erro = e.mensagem);
    } finally {
      if (mounted) setState(() => _carregando = false);
    }
  }

  Future<void> _alternarArquivo(ParticipacaoEncerrada p) async {
    final repo = ref.read(cicloVidaRepositoryProvider);
    try {
      if (p.arquivado) {
        // Arquivamento é reversível de propósito: correção de placar pode
        // precisar recalcular um bolão arquivado.
        await repo.desarquivar(p.poolId);
      } else {
        await repo.arquivar(p.poolId);
      }
      await _carregar();
    } on ApiError catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text(e.mensagem)));
      }
    }
  }

  Future<void> _recriar(ParticipacaoEncerrada p) async {
    final criou = await showDialog<bool>(
      context: context,
      builder: (_) =>
          RecriarTemporadaDialog(poolId: p.poolId, nomeAtual: p.nome),
    );
    if (criou == true) await _carregar();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Histórico e títulos')),
      body: RefreshIndicator(onRefresh: _carregar, child: _corpo()),
    );
  }

  Widget _corpo() {
    if (_carregando) return const Center(child: CircularProgressIndicator());

    if (_lista == null) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.all(32),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Icon(Icons.cloud_off, size: 48),
              const SizedBox(height: 12),
              Text(_erro ?? 'falha ao carregar', textAlign: TextAlign.center),
              const SizedBox(height: 16),
              FilledButton(
                onPressed: _carregar,
                child: const Text('Tentar de novo'),
              ),
            ],
          ),
        ),
      );
    }

    if (_lista!.isEmpty) {
      return const Center(
        child: Padding(
          padding: EdgeInsets.all(32),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(Icons.workspace_premium_outlined, size: 48),
              SizedBox(height: 12),
              Text('Nenhum bolão encerrado ainda'),
              SizedBox(height: 6),
              Text(
                'Quando um bolão que você joga terminar, ele aparece aqui com '
                'sua posição final.',
                textAlign: TextAlign.center,
              ),
            ],
          ),
        ),
      );
    }

    final titulos = _lista!
        .where((p) => p.resultado == 'CAMPEAO' || p.resultado == 'CO_CAMPEAO')
        .length;

    return ListView.separated(
      itemCount: _lista!.length + 1,
      separatorBuilder: (_, _) => const Divider(height: 1),
      itemBuilder: (_, i) {
        if (i == 0) {
          return Padding(
            padding: const EdgeInsets.all(16),
            child: Text(
              titulos == 0
                  ? '${_lista!.length} bolão(ões) encerrado(s), nenhum título ainda'
                  : '$titulos título(s) em ${_lista!.length} bolão(ões) encerrado(s)',
              style: Theme.of(context).textTheme.titleMedium,
            ),
          );
        }
        final p = _lista![i - 1];
        final campeao = p.resultado == 'CAMPEAO' || p.resultado == 'CO_CAMPEAO';

        return ListTile(
          leading: Icon(
            campeao ? Icons.emoji_events : Icons.flag_outlined,
            color: campeao ? CoresDoApp.campeao : null,
          ),
          title: Text(p.nome),
          subtitle: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                descreverResultado(p.resultado, p.posicao) +
                    (p.pontos != null ? ' · ${p.pontos} pts' : ''),
              ),
              Text(
                'encerrado em ${_data(p.encerradoEm)}'
                // Título de bolão encerrado na rodada 5 não vale o mesmo.
                '${p.antecipado ? ' (antecipadamente)' : ''}'
                '${p.arquivado ? ' · arquivado' : ''}',
                style: TextStyle(
                  fontSize: 11,
                  color: Theme.of(context).colorScheme.outline,
                ),
              ),
            ],
          ),
          // Arquivar/desarquivar e recriar são ações de admin; para os outros o
          // servidor responde 403, e botão que sempre falha é pior que ausência.
          trailing: p.souAdmin
              ? PopupMenuButton<String>(
                  onSelected: (v) =>
                      v == 'arquivo' ? _alternarArquivo(p) : _recriar(p),
                  itemBuilder: (_) => [
                    PopupMenuItem(
                      value: 'arquivo',
                      child: Text(p.arquivado ? 'Desarquivar' : 'Arquivar'),
                    ),
                    const PopupMenuItem(
                      value: 'recriar',
                      child: Text('Recriar na próxima temporada'),
                    ),
                  ],
                )
              : null,
          isThreeLine: true,
        );
      },
    );
  }

  String _data(DateTime utc) {
    final l = utc.toLocal();
    return '${l.day.toString().padLeft(2, '0')}/'
        '${l.month.toString().padLeft(2, '0')}/${l.year}';
  }
}
