import 'dart:async';

import 'package:flutter/material.dart';

import '../main.dart' show supabase;
import '../widgets/app_gradients.dart';
import '../widgets/entrance.dart';
import '../widgets/liquid_waves_background.dart';
import '../widgets/tap_bounce.dart';
import 'quiz_prefs.dart';
import 'quiz_question_screen.dart' show QuizScore;
import 'quiz_video_guide.dart';

const String _resultGuideYoutubeId = '3q7C7txH1dE';

// Fase 3 tem 29 perguntas no total: 6 são sinais de má oclusão já
// instalados (queixo, boca/dentição, apinhamento, boca/dentição 2,
// boca/dentição 3, céu da boca) — as restantes 23 são fatores de risco
// associados. Ver o diagrama de planeamento partilhado com o utilizador
// para o racional completo.
const int kSignsMax = 6;
const int kFactorsMax = 23;

/// A partir de quantos sinais/fatores presentes se recomenda avaliação.
/// Proposta: qualquer sinal já instalado, ou ao menos ~30% dos fatores de
/// risco — ajustável depois de validar com dados reais.
bool _recommendsEvaluation(QuizScore score) {
  return score.signs >= 1 || score.factors >= (kFactorsMax * 0.3).ceil();
}

class QuizResultScreen extends StatefulWidget {
  const QuizResultScreen({super.key, required this.finalScore, this.scopeId});

  final QuizScore finalScore;
  final String? scopeId;

  @override
  State<QuizResultScreen> createState() => _QuizResultScreenState();
}

class _QuizResultScreenState extends State<QuizResultScreen> {
  late final Future<void> _saveResultFuture;

  @override
  void initState() {
    super.initState();
    _saveResultFuture = _saveResult();
  }

  Future<void> _saveResult() async {
    QuizPrefs.markQuizSeen();
    final result = QuizResultData(
      signs: widget.finalScore.signs,
      signsMax: kSignsMax,
      factors: widget.finalScore.factors,
      factorsMax: kFactorsMax,
    );
    final scope = (widget.scopeId ?? '').trim();
    if (scope.isNotEmpty) {
      await QuizPrefs.saveLastResultForScope(scopeId: scope, result: result);
    } else {
      final uid = supabase.auth.currentUser?.id;
      if (uid != null && uid.trim().isNotEmpty) {
        await QuizPrefs.saveLastResultForUser(userId: uid, result: result);
      } else {
        await QuizPrefs.saveLastResult(result);
      }
    }

    final uid = supabase.auth.currentUser?.id;
    final userId = (uid ?? '').trim();
    if (userId.isNotEmpty &&
        scope.isNotEmpty &&
        scope.startsWith('${userId}_')) {
      final childId = scope.substring(userId.length + 1).trim();
      if (childId.isNotEmpty) {
        // Aguarda a gravação (em vez de fire-and-forget) para que, ao voltar
        // à Home logo a seguir, _loadQuizResult já encontre o valor novo na
        // base de dados — caso contrário havia uma corrida em que a Home
        // consultava a tabela antes desta escrita terminar, mostrando o
        // resultado antigo até trocar de aba ou reabrir a app. Requer as
        // colunas last_signs/last_signs_max/last_factors/last_factors_max
        // na tabela children — se ainda não existirem, falha silenciosamente
        // e o resultado fica só local (SharedPreferences, acima).
        try {
          await supabase
              .from('children')
              .update({
                'last_signs': widget.finalScore.signs,
                'last_signs_max': kSignsMax,
                'last_factors': widget.finalScore.factors,
                'last_factors_max': kFactorsMax,
              })
              .eq('id', childId);
        } catch (e) {
          debugPrint(
            '[QuizResult] Falha ao gravar score na base de dados: $e',
          );
        }
      }
    }
  }

  void _goToVideo() {
    Navigator.of(context).pushReplacement(
      MaterialPageRoute<void>(
        builder: (_) => QuizVideoGuideScreen(
          youtubeId: _resultGuideYoutubeId,
          heading: 'Visualize o seguinte vídeo',
          caption:
              'Assista para compreender a importância de um diagnóstico '
              'precoce e de realizar tratamento ortodôntico intercetivo, '
              'ou seja, uma intervenção realizada na infância, tipicamente '
              'durante a fase de dentição mista (presença tanto de dentes '
              'de leite como de permanentes).\n\nO seu propósito é '
              'identificar, prevenir ou reduzir a gravidade de maloclusões '
              'e problemas no desenvolvimento dos maxilares enquanto os '
              'ossos e dentes ainda estão em crescimento.\n\nEsta '
              'intervenção aproveita a fase de desenvolvimento craniofacial '
              'para influenciar o crescimento ósseo, redirecionar a '
              'mandíbula, corrigir o alinhamento dos maxilares ou criar '
              'espaço para a erupção correta dos dentes permanentes.',
          onAdvance: (context) =>
              Navigator.of(context).popUntil((r) => r.isFirst),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final recommend = _recommendsEvaluation(widget.finalScore);
    final signs = widget.finalScore.signs;
    final factors = widget.finalScore.factors;

    return Scaffold(
      body: Stack(
        clipBehavior: Clip.none,
        children: [
          Positioned.fill(child: Container(color: const Color(0xFFFAFAF7))),
          const LiquidWavesBackground(),
          SafeArea(
            child: Center(
              child: ConstrainedBox(
                constraints: const BoxConstraints(maxWidth: 520),
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(22, 12, 22, 18),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      Expanded(
                        child: Center(
                          child: SingleChildScrollView(
                            child: Column(
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                const SizedBox(height: 10),
                                FadeSlideIn(
                                  child: const Text(
                                    'O resultado avaliado é de:',
                                    textAlign: TextAlign.center,
                                    style: TextStyle(
                                      fontSize: 18,
                                      fontWeight: FontWeight.w900,
                                      color: Color(0xFFFF55A7),
                                      height: 1.2,
                                    ),
                                  ),
                                ),
                                const SizedBox(height: 18),
                                FadeSlideIn(
                                  delay: const Duration(milliseconds: 60),
                                  child: Row(
                                    mainAxisAlignment:
                                        MainAxisAlignment.spaceEvenly,
                                    children: [
                                      _ResultRing(
                                        value: signs,
                                        max: kSignsMax,
                                        color: const Color(0xFF2F9E94),
                                        label:
                                            'Sinais de má\noclusão instalados',
                                      ),
                                      _ResultRing(
                                        value: factors,
                                        max: kFactorsMax,
                                        color: const Color(0xFFFF55A7),
                                        label: 'Fatores de\nrisco associados',
                                      ),
                                    ],
                                  ),
                                ),
                                const SizedBox(height: 22),
                                FadeSlideIn(
                                  delay: const Duration(milliseconds: 100),
                                  child: _ResultSection(
                                    heading: 'Conclusões:',
                                    body:
                                        'Foram identificados $signs de $kSignsMax '
                                        'sinais de má oclusão já instalada e '
                                        '$factors de $kFactorsMax fatores de '
                                        'risco frequentemente associados a '
                                        'má oclusão.',
                                    bodyColor: const Color(0xFFFF55A7),
                                    bodyWeight: FontWeight.w800,
                                  ),
                                ),
                                const SizedBox(height: 16),
                                FadeSlideIn(
                                  delay: const Duration(milliseconds: 140),
                                  child: _ResultSection(
                                    heading: 'O que deve fazer agora',
                                    body: recommend
                                        ? 'Com base neste resultado, recomendamos a marcação de uma consulta com Odontopediatra ou Ortodontista para uma avaliação presencial.'
                                        : 'Não foram encontrados sinais ou fatores de risco relevantes. Continue a acompanhar a saúde oral do seu filho/a com as consultas de rotina habituais.',
                                  ),
                                ),
                                const SizedBox(height: 16),
                                FadeSlideIn(
                                  delay: const Duration(milliseconds: 180),
                                  child: _ResultSection(
                                    heading: 'Importante saber',
                                    body:
                                        'Este resultado não substitui uma avaliação presencial, nem tem função de diagnóstico. O objetivo é ajudá-lo a estar mais atento aos sinais identificados e a não adiar uma consulta que pode fazer a diferença no desenvolvimento oral do seu filho/a.',
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ),
                      Center(
                        child: TapBounce(
                          child: ClipRRect(
                            borderRadius: BorderRadius.circular(999),
                            child: DecoratedBox(
                              decoration: const BoxDecoration(
                                gradient: kGreenButtonGradient,
                              ),
                              child: SizedBox(
                                width: 260,
                                height: 46,
                                child: FilledButton(
                                  style: FilledButton.styleFrom(
                                    backgroundColor: Colors.transparent,
                                    foregroundColor: Colors.white,
                                    shape: const StadiumBorder(),
                                    textStyle: const TextStyle(
                                      fontWeight: FontWeight.w900,
                                    ),
                                  ),
                                  onPressed: () async {
                                    await _saveResultFuture;
                                    if (!context.mounted) return;
                                    _goToVideo();
                                  },
                                  child: const Text('Avançar'),
                                ),
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

/// Bloco de texto "título + parágrafo" reutilizado nas secções de
/// conclusão do resultado ("Conclusões:", "O que deve fazer agora",
/// "Importante saber").
class _ResultSection extends StatelessWidget {
  const _ResultSection({
    required this.heading,
    required this.body,
    this.bodyColor,
    this.bodyWeight = FontWeight.w600,
  });

  final String heading;
  final String body;
  final Color? bodyColor;
  final FontWeight bodyWeight;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(
          heading,
          textAlign: TextAlign.center,
          style: TextStyle(
            color: Colors.black.withValues(alpha: 0.75),
            fontWeight: FontWeight.w900,
          ),
        ),
        const SizedBox(height: 8),
        Text(
          body,
          textAlign: TextAlign.center,
          style: TextStyle(
            color: bodyColor ?? Colors.black.withValues(alpha: 0.70),
            fontWeight: bodyWeight,
            height: 1.35,
          ),
        ),
      ],
    );
  }
}

/// Anel de progresso — usado para os dois indicadores do resultado
/// (sinais / fatores de risco), com o valor no centro e a legenda por
/// baixo.
class _ResultRing extends StatelessWidget {
  const _ResultRing({
    required this.value,
    required this.max,
    required this.color,
    required this.label,
  });

  final int value;
  final int max;
  final Color color;
  final String label;

  @override
  Widget build(BuildContext context) {
    final progress = max > 0 ? (value / max).clamp(0.0, 1.0) : 0.0;
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        TweenAnimationBuilder<double>(
          duration: const Duration(milliseconds: 1100),
          curve: Curves.easeOutCubic,
          tween: Tween<double>(begin: 0, end: progress),
          builder: (context, animatedProgress, _) {
            return SizedBox(
              width: 130,
              height: 130,
              child: Stack(
                alignment: Alignment.center,
                children: [
                  SizedBox(
                    width: 130,
                    height: 130,
                    child: CircularProgressIndicator(
                      value: animatedProgress,
                      strokeWidth: 12,
                      backgroundColor: Colors.black.withValues(alpha: 0.10),
                      valueColor: AlwaysStoppedAnimation(color),
                    ),
                  ),
                  Text(
                    '$value/$max',
                    style: const TextStyle(
                      fontSize: 22,
                      fontWeight: FontWeight.w900,
                      color: Colors.black,
                    ),
                  ),
                ],
              ),
            );
          },
        ),
        const SizedBox(height: 10),
        Text(
          label,
          textAlign: TextAlign.center,
          style: TextStyle(
            fontSize: 12.5,
            fontWeight: FontWeight.w800,
            color: Colors.black.withValues(alpha: 0.65),
            height: 1.25,
          ),
        ),
      ],
    );
  }
}
