import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'dart:async';
import 'dart:math' as math;
import 'dart:io';
import 'package:shared_preferences/shared_preferences.dart';

import 'brushing_prefs.dart';
import 'main.dart' show supabase;
import 'quiz/quiz1.dart';
import 'quiz/quiz_prefs.dart';
import 'quiz/quiz_result.dart' show kSignsMax, kFactorsMax;
import 'screens/settings_screen.dart';
import 'screens/video_screen.dart';
import 'watched_videos_prefs.dart';
import 'widgets/animated_nav_icon.dart';
import 'widgets/app_dialogs.dart';
import 'widgets/app_gradients.dart';
import 'widgets/entrance.dart';
import 'widgets/liquid_waves_background.dart';
import 'widgets/name_input_formatter.dart';
import 'widgets/pill_snackbar.dart';
import 'widgets/tap_bounce.dart';

/// Nomes só podem ter letras (incluindo acentuadas) e espaços — sem números.
final RegExp _namePattern = RegExp(r"^[a-zA-ZÀ-ÖØ-öø-ÿ' -]+$");

/// Calcula a idade a partir de `birth_date` (novo campo). Para crianças
/// cadastradas antes desta mudança, que só têm a coluna legada `age`, usa
/// esse valor como fallback.
int? _childAge(Map<String, dynamic> child) {
  final birthDateRaw = (child['birth_date'] ?? '').toString().trim();
  if (birthDateRaw.isNotEmpty) {
    final birthDate = DateTime.tryParse(birthDateRaw);
    if (birthDate != null) {
      final now = DateTime.now();
      int age = now.year - birthDate.year;
      if (now.month < birthDate.month ||
          (now.month == birthDate.month && now.day < birthDate.day)) {
        age--;
      }
      return age;
    }
  }
  final legacyAge = child['age'];
  if (legacyAge is int) return legacyAge;
  return int.tryParse((legacyAge ?? '').toString());
}

class LoggedHomeScreen extends StatefulWidget {
  const LoggedHomeScreen({super.key});

  @override
  State<LoggedHomeScreen> createState() => _LoggedHomeScreenState();
}

class _LoggedHomeScreenState extends State<LoggedHomeScreen>
    with SingleTickerProviderStateMixin {
  static const Color _teal = Color(0xFF2F9E94);
  static const String _kPendingQuizScopeKey = 'pending_quiz_scope_v1';

  static const double _collapsedAppBarHeight = kToolbarHeight;
  static const double _expandedAppBarHeight = 256;

  int _index = 0;

  int _selectedChildIndex = 0;
  String? _selectedChildName;
  String? _selectedChildScopeId;

  QuizResultData? _lastResult;

  int? _brushingWeekCount;
  int _weeklyGoal = BrushingPrefs.defaultWeeklyGoal;
  bool _brushingDailyLimitReached = false;
  int? _watchedVideoCount;

  String _cachedUserName = 'Sem nome';
  String? _cachedPhotoUrl;

  @override
  void initState() {
    super.initState();
    _loadQuizResult();
    _loadInitialProfile();
    refreshStats();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (mounted) _maybeStartPendingQuiz();
    });
  }

  /// Recarrega os dados locais de escovagem e vídeos assistidos da criança
  /// atualmente selecionada. Chamado ao trocar de criança, ao editar a meta
  /// semanal e depois de registar uma escovagem ou um vídeo completo.
  Future<void> refreshStats() async {
    final scope = (_selectedChildScopeId ?? '').trim();
    if (scope.isEmpty) {
      if (!mounted) return;
      setState(() {
        _brushingWeekCount = null;
        _weeklyGoal = BrushingPrefs.defaultWeeklyGoal;
        _brushingDailyLimitReached = false;
        _watchedVideoCount = null;
      });
      return;
    }

    final weekCount = await BrushingPrefs.getWeekCount(scope);
    final goal = await BrushingPrefs.getWeeklyGoal(scope);
    final dailyLimitReached = await BrushingPrefs.hasReachedDailyLimit(scope);
    final watchedCount = await WatchedVideosPrefs.getWatchedCount(scope);

    if (!mounted) return;
    setState(() {
      _brushingWeekCount = weekCount;
      _weeklyGoal = goal;
      _brushingDailyLimitReached = dailyLimitReached;
      _watchedVideoCount = watchedCount;
    });
  }

  Future<void> _maybeStartPendingQuiz() async {
    try {
      final prefs = await SharedPreferences.getInstance();

      String scopeId = (prefs.getString(_kPendingQuizScopeKey) ?? '').trim();

      // O AuthGate pode trocar para o LoggedHome ANTES do register sheet terminar
      // de gravar a key. Então tentamos por um curto período.
      int tries = 0;
      while (scopeId.isEmpty && tries < 12) {
        await Future<void>.delayed(const Duration(milliseconds: 250));
        scopeId = (prefs.getString(_kPendingQuizScopeKey) ?? '').trim();
        tries++;
      }

      if (scopeId.isEmpty) return;

      // Limpa antes de navegar para evitar loop se o usuário voltar.
      await prefs.remove(_kPendingQuizScopeKey);
      if (!mounted) return;

      await Navigator.of(context).push(quizStartRoute(scopeId: scopeId));
      if (!mounted) return;
      await _loadQuizResult();
    } catch (_) {
      // no-op
    }
  }

  Future<void> _loadInitialProfile() async {
    final uid = (supabase.auth.currentUser?.id ?? '').trim();
    if (uid.isEmpty) return;
    try {
      final userDoc = await supabase
          .from('profiles')
          .select()
          .eq('id', uid)
          .maybeSingle();
      final storedName = (userDoc?['name'] ?? '').toString().trim();
      final storedPhotoUrl = (userDoc?['photo_url'] ?? '').toString().trim();

      final childrenSnap = await supabase
          .from('children')
          .select()
          .eq('owner_id', uid)
          .order('created_at')
          .limit(1);

      String? childName;
      String? scopeId;
      if (childrenSnap.isNotEmpty) {
        final c = childrenSnap.first;
        final childId = (c['id'] ?? '').toString().trim();
        childName = (c['name'] ?? '').toString().trim();
        scopeId = '${uid}_$childId';
      }

      if (!mounted) return;
      setState(() {
        _cachedUserName = storedName.isNotEmpty ? storedName : _cachedUserName;
        if (storedPhotoUrl.isNotEmpty) _cachedPhotoUrl = storedPhotoUrl;
        if ((_selectedChildName ?? '').trim().isEmpty &&
            (childName ?? '').trim().isNotEmpty) {
          _selectedChildName = childName;
        }
        if ((_selectedChildScopeId ?? '').trim().isEmpty &&
            (scopeId ?? '').trim().isNotEmpty) {
          _selectedChildScopeId = scopeId;
        }
      });
      await _loadQuizResult();
      await refreshStats();
    } catch (_) {
      // no-op
    }
  }

  Future<void> _loadQuizResult() async {
    final scope = (_selectedChildScopeId ?? '').trim();
    final uid = supabase.auth.currentUser?.id;
    final String? userId = (uid ?? '').trim().isEmpty ? null : uid;

    QuizResultData? result;

    if (scope.isNotEmpty && userId != null) {
      final String childId = scope.startsWith('${userId}_')
          ? scope.substring(userId.length + 1)
          : '';
      if (childId.trim().isNotEmpty) {
        try {
          final childDoc = await supabase
              .from('children')
              .select()
              .eq('id', childId)
              .maybeSingle();
          final signs = childDoc?['last_signs'];
          final signsMax = childDoc?['last_signs_max'];
          final factors = childDoc?['last_factors'];
          final factorsMax = childDoc?['last_factors_max'];
          if (signs is int &&
              signsMax is int &&
              factors is int &&
              factorsMax is int) {
            result = QuizResultData(
              signs: signs,
              signsMax: signsMax,
              factors: factors,
              factorsMax: factorsMax,
            );
          }
        } catch (_) {
          // no-op
        }
      }
    }

    if (result != null) {
      if (!mounted) return;
      setState(() => _lastResult = result);
      return;
    }
    if (scope.isNotEmpty) {
      result = await QuizPrefs.getLastResultForScope(scope);
    } else if (userId != null) {
      result = await QuizPrefs.getLastResultForUser(userId);
    } else {
      result = await QuizPrefs.getLastResult();
    }
    if (!mounted) return;
    setState(() => _lastResult = result);
  }

  void selectChild(String? name, String? scopeId) {
    setState(() {
      _selectedChildName = name;
      _selectedChildScopeId = scopeId;
    });
    _loadQuizResult();
    refreshStats();
  }

  void updateCachedPhoto(String url) {
    setState(() => _cachedPhotoUrl = url);
  }

  String _greeting() {
    final hour = DateTime.now().hour;
    if (hour < 12) return 'Bom dia';
    if (hour < 18) return 'Boa tarde';
    return 'Boa noite';
  }

  /// Fundo comum (cor sólida + ondas decorativas) atrás de qualquer aba, com
  /// o conteúdo real posicionado por cima via [SafeArea]/[Padding].
  Widget _decoratedBody(Size size, Widget child, double topPadding) {
    return Stack(
      clipBehavior: Clip.none,
      children: [
        Positioned.fill(child: Container(color: const Color(0xFFFAFAF7))),
        const LiquidWavesBackground(),
        SafeArea(
          top: false,
          child: Align(
            alignment: Alignment.center,
            child: Padding(
              padding: EdgeInsets.fromLTRB(16, topPadding, 16, 16),
              child: child,
            ),
          ),
        ),
      ],
    );
  }

  Widget _bottomNav() {
    return BottomNavigationBar(
      currentIndex: _index,
      onTap: (i) {
        if (i == _index) return;
        HapticFeedback.selectionClick();
        setState(() => _index = i);
      },
      backgroundColor: const Color(0xFFFAFAF7),
      selectedItemColor: _teal,
      unselectedItemColor: Colors.black54,
      type: BottomNavigationBarType.fixed,
      items: [
        BottomNavigationBarItem(
          icon: AnimatedNavIcon(
            icon: Icons.home_rounded,
            selected: _index == 0,
          ),
          label: 'Início',
        ),
        BottomNavigationBarItem(
          icon: AnimatedNavIcon(
            icon: Icons.person_rounded,
            selected: _index == 1,
          ),
          label: 'Perfil',
        ),
        BottomNavigationBarItem(
          icon: AnimatedNavIcon(
            icon: Icons.settings_rounded,
            selected: _index == 2,
          ),
          label: 'Ajustes',
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.sizeOf(context);

    final QuizResultData? result = _lastResult;
    final bool hasScore = result != null;
    final shownName = _cachedUserName;

    if (_index == 0) {
      // Home: a app bar é retrátil — encolhe (escondendo o nome da criança e
      // o gauge) à medida que o utilizador scrolla a lista, mantendo só a
      // linha do avatar/saudação fixa no topo. É um SliverAppBar dentro de
      // um NestedScrollView em vez do AppBar fixo usado nas outras abas,
      // para que a altura acompanhe o scroll em vez de ficar sempre cheia
      // (o que cortava o conteúdo do card do quiz contra a barra ao rolar).
      // A app bar mantém sempre a mesma altura e mostra sempre os dois
      // gauges — vazios (sem número, sem rótulo) quando ainda não há
      // resultado, para o utilizador já perceber que aquele espaço é para
      // o resultado do quiz mesmo antes de o fazer.
      const double expandedHeight = _expandedAppBarHeight;

      return Scaffold(
        body: NestedScrollView(
          headerSliverBuilder: (context, innerBoxIsScrolled) => [
            SliverAppBar(
              expandedHeight: expandedHeight,
              toolbarHeight: kToolbarHeight,
              pinned: true,
              elevation: 0,
              scrolledUnderElevation: 0,
              backgroundColor: _teal,
              foregroundColor: Colors.white,
              surfaceTintColor: Colors.transparent,
              shape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.vertical(
                  bottom: Radius.circular(40),
                ),
              ),
              flexibleSpace: FlexibleSpaceBar(
                titlePadding: EdgeInsets.zero,
                background: ClipRRect(
                  borderRadius: const BorderRadius.vertical(
                    bottom: Radius.circular(40),
                  ),
                  child: Container(
                    decoration: const BoxDecoration(gradient: kAppBarGradient),
                    child: Stack(
                      fit: StackFit.expand,
                      children: [
                        if (hasScore)
                          Positioned(
                            left: 0,
                            right: 0,
                            top: kToolbarHeight + 50,
                            child: Center(
                              child: Text(
                                (_selectedChildName ?? '').trim(),
                                textAlign: TextAlign.center,
                                style: TextStyle(
                                  fontWeight: FontWeight.w800,
                                  color: Colors.white.withValues(alpha: 0.92),
                                  fontSize: 14,
                                ),
                              ),
                            ),
                          ),
                        //posição da app bar relativamente ao nome
                        Positioned(
                          left: 0,
                          right: 0,
                          top: kToolbarHeight + 96,
                          child: Center(
                            child: Row(
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                _RiskArcGauge(
                                  // Usa sempre o máximo atual do quiz (não
                                  // o que foi gravado na última avaliação)
                                  // para não mostrar um denominador antigo
                                  // quando o número de perguntas muda.
                                  value: hasScore ? result.signs : null,
                                  max: hasScore ? kSignsMax : null,
                                  label: 'Sinais de má\noclusão',
                                ),
                                const SizedBox(width: 18),
                                _RiskArcGauge(
                                  value: hasScore ? result.factors : null,
                                  max: hasScore ? kFactorsMax : null,
                                  label: 'Fatores de risco',
                                ),
                              ],
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
              title: Padding(
                padding: const EdgeInsets.only(left: 16, right: 10),
                child: TapBounce(
                  scale: 0.96,
                  child: Material(
                    color: Colors.transparent,
                    child: InkWell(
                      borderRadius: BorderRadius.circular(30),
                      onTap: () => setState(() => _index = 1),
                      child: Padding(
                        padding: const EdgeInsets.symmetric(
                          vertical: 4,
                          horizontal: 4,
                        ),
                        child: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            CircleAvatar(
                              radius: 20,
                              backgroundColor: Colors.white.withValues(
                                alpha: 0.25,
                              ),
                              backgroundImage:
                                  (_cachedPhotoUrl ?? '').isNotEmpty
                                  ? NetworkImage(_cachedPhotoUrl!)
                                  : null,
                              child: (_cachedPhotoUrl ?? '').isEmpty
                                  ? const Icon(
                                      Icons.person_rounded,
                                      color: Colors.white,
                                    )
                                  : null,
                            ),
                            const SizedBox(width: 10),
                            Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                Text(
                                  _greeting(),
                                  style: TextStyle(
                                    fontWeight: FontWeight.w600,
                                    color: Colors.white.withValues(alpha: 0.85),
                                    fontSize: 12,
                                  ),
                                ),
                                Text(
                                  shownName,
                                  textAlign: TextAlign.left,
                                  style: const TextStyle(
                                    fontWeight: FontWeight.w900,
                                    color: Colors.white,
                                    fontSize: 19,
                                  ),
                                ),
                              ],
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),
              ),
              centerTitle: false,
              titleSpacing: 0,
            ),
          ],
          body: _decoratedBody(
            size,
            _InicioTab(onQuizClosed: _loadQuizResult),
            0,
          ),
        ),
        bottomNavigationBar: _bottomNav(),
      );
    }

    final String title = _index == 1 ? 'Perfil' : 'Configurações';

    return Scaffold(
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(_collapsedAppBarHeight),
        // O gradiente é pintado por este Container de tamanho fixo (a
        // própria altura da app bar), em vez de confiar no `flexibleSpace`
        // do AppBar — em alguns aparelhos, o `flexibleSpace` de um AppBar
        // comum (não Sliver) não recebia o tamanho esperado e a gradiente
        // aparecia como cor sólida. Com o Container por baixo e o AppBar
        // totalmente transparente por cima, o gradiente é garantido.
        child: Container(
          decoration: const BoxDecoration(gradient: kAppBarGradient),
          child: AppBar(
            toolbarHeight: _collapsedAppBarHeight,
            backgroundColor: Colors.transparent,
            foregroundColor: Colors.white,
            surfaceTintColor: Colors.transparent,
            elevation: 0,
            scrolledUnderElevation: 0,
            centerTitle: true,
            title: Text(
              title,
              textAlign: TextAlign.center,
              style: const TextStyle(
                fontWeight: FontWeight.w900,
                color: Colors.white,
              ),
            ),
            shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.zero,
            ),
          ),
        ),
      ),
      body: _decoratedBody(
        size,
        _index == 1
            ? _PerfilTab(
                selectedChildIndex: _selectedChildIndex,
                onChildSelected: (index, name, scopeId) {
                  setState(() {
                    _selectedChildIndex = index;
                    _selectedChildName = name;
                    _selectedChildScopeId = scopeId;
                  });
                  _loadQuizResult();
                  refreshStats();
                },
              )
            : const SettingsBody(),
        10,
      ),
      bottomNavigationBar: _bottomNav(),
    );
  }
}

class _RiskArcGauge extends StatelessWidget {
  const _RiskArcGauge({required this.value, required this.max, this.label});

  /// Quando [value]/[max] são nulos (sem criança selecionada, ou criança
  /// ainda sem quiz feito), o gauge mostra-se vazio — só o anel em branco,
  /// sem número nem rótulo — em vez de desaparecer, para o espaço já
  /// indicar onde o resultado vai aparecer assim que existir.
  final int? value;
  final int? max;
  final String? label;

  bool get _isEmpty => value == null || max == null;

  @override
  Widget build(BuildContext context) {
    final progress = _isEmpty || max! <= 0
        ? 0.0
        : (value! / max!).clamp(0, 1).toDouble();

    return TweenAnimationBuilder<double>(
      duration: const Duration(milliseconds: 700),
      curve: Curves.easeOutCubic,
      tween: Tween<double>(begin: 0, end: progress),
      builder: (context, animatedProgress, _) {
        return SizedBox(
          width: 108,
          height: 92,
          child: Stack(
            clipBehavior: Clip.none,
            children: [
              Positioned(
                top: 0,
                left: 0,
                right: 0,
                height: 60,
                child: CustomPaint(
                  painter: _RiskArcGaugePainter(progress: animatedProgress),
                ),
              ),
              if (!_isEmpty) ...[
                Positioned(
                  top: 38,
                  left: 0,
                  right: 0,
                  child: Center(
                    child: Text(
                      '$value/$max',
                      style: const TextStyle(
                        color: Colors.white,
                        fontSize: 17,
                        fontWeight: FontWeight.w900,
                        height: 1,
                      ),
                    ),
                  ),
                ),
                Positioned(
                  top: 68,
                  left: 0,
                  right: 0,
                  child: Text(
                    label ?? '',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      color: Colors.white.withValues(alpha: 0.85),
                      fontSize: 10.5,
                      fontWeight: FontWeight.w700,
                      height: 1.15,
                      letterSpacing: 0.1,
                    ),
                  ),
                ),
              ],
            ],
          ),
        );
      },
    );
  }
}

class _RiskArcGaugePainter extends CustomPainter {
  const _RiskArcGaugePainter({required this.progress});

  final double progress;

  @override
  void paint(Canvas canvas, Size size) {
    final rect = Rect.fromLTWH(10, 8, size.width - 20, size.height * 1.7);
    const startAngle = math.pi;
    const sweepAngle = math.pi;
    final strokeWidth = size.width * 0.12;

    final backgroundPaint = Paint()
      ..color = Colors.white.withValues(alpha: 0.72)
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round;

    final progressPaint = Paint()
      ..color = const Color(0xFFFF9AD0)
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round;

    canvas.drawArc(rect, startAngle, sweepAngle, false, backgroundPaint);
    canvas.drawArc(
      rect,
      startAngle,
      sweepAngle * progress.clamp(0, 1),
      false,
      progressPaint,
    );
  }

  @override
  bool shouldRepaint(covariant _RiskArcGaugePainter oldDelegate) {
    return oldDelegate.progress != progress;
  }
}

class _InicioTab extends StatelessWidget {
  const _InicioTab({required this.onQuizClosed});

  final VoidCallback onQuizClosed;

  Future<void> _startQuiz(BuildContext context) async {
    final uid = (supabase.auth.currentUser?.id ?? '').trim();
    if (uid.isEmpty) return;

    List<Map<String, dynamic>> children = const [];
    try {
      children = await supabase
          .from('children')
          .select()
          .eq('owner_id', uid)
          .order('created_at');
    } catch (_) {
      // segue com lista vazia; tratado abaixo
    }

    if (!context.mounted) return;

    Map<String, dynamic>? chosen;
    if (children.isEmpty) {
      chosen = await _requireFirstChild(context, uid);
      if (chosen == null) return;
    } else if (children.length == 1) {
      chosen = children.first;
    } else {
      if (!context.mounted) return;
      chosen = await _pickChildSheet(context, children);
      if (chosen == null) return;
    }

    final childId = (chosen['id'] ?? '').toString().trim();
    final childName = (chosen['name'] ?? '').toString().trim();
    final scopeId = childId.isEmpty ? uid : '${uid}_$childId';

    if (!context.mounted) return;
    final state = context.findAncestorStateOfType<_LoggedHomeScreenState>();
    state?.selectChild(childName, scopeId);

    await Navigator.of(context).push(quizStartRoute(scopeId: scopeId));
    onQuizClosed();
  }

  @override
  Widget build(BuildContext context) {
    final state = context.findAncestorStateOfType<_LoggedHomeScreenState>();
    final selectedChildName = (state?._selectedChildName ?? '').trim();
    final scopeId = state?._selectedChildScopeId;

    return Align(
      alignment: Alignment.topCenter,
      child: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 560),
        child: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.only(top: 18, bottom: 16),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                if (selectedChildName.isNotEmpty) ...[
                  FadeSlideIn(
                    child: _HomeSectionLabel('Para $selectedChildName'),
                  ),
                  const SizedBox(height: 8),
                ],
                FadeSlideIn(
                  child: TapBounce(
                    scale: 0.97,
                    child: _HeroQuizCard(
                      onStartQuiz: () => _startQuiz(context),
                    ),
                  ),
                ),
                const SizedBox(height: 16),
                FadeSlideIn(
                  delay: const Duration(milliseconds: 70),
                  child: _StatsRow(
                    brushingCount: state?._brushingWeekCount,
                    weeklyGoal:
                        state?._weeklyGoal ?? BrushingPrefs.defaultWeeklyGoal,
                    brushedToday: state?._brushingDailyLimitReached ?? false,
                    watchedCount: state?._watchedVideoCount,
                    onTapBrushing: () => _logBrushing(context, state, scopeId),
                  ),
                ),
                const SizedBox(height: 20),
                FadeSlideIn(
                  delay: const Duration(milliseconds: 110),
                  child: const _HomeSectionLabel('Vídeos educativos'),
                ),
                const SizedBox(height: 8),
                FadeSlideIn(
                  delay: const Duration(milliseconds: 130),
                  child: TapBounce(
                    scale: 0.97,
                    child: _VideoLibraryCard(
                      watchedCount: state?._watchedVideoCount ?? 0,
                      onTap: () async {
                        await Navigator.of(context).push(
                          MaterialPageRoute<void>(
                            builder: (_) => VideoScreen(scopeId: scopeId),
                          ),
                        );
                        await state?.refreshStats();
                      },
                    ),
                  ),
                ),
                const SizedBox(height: 14),
                FadeSlideIn(
                  delay: const Duration(milliseconds: 150),
                  child: Center(
                    child: Text(
                      'Mais funcionalidades em breve',
                      style: TextStyle(
                        fontWeight: FontWeight.w700,
                        fontSize: 12.5,
                        color: Colors.black.withValues(alpha: 0.35),
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 16),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Future<void> _logBrushing(
    BuildContext context,
    _LoggedHomeScreenState? state,
    String? scopeId,
  ) async {
    final scope = (scopeId ?? '').trim();
    if (scope.isEmpty) {
      final uid = (supabase.auth.currentUser?.id ?? '').trim();
      if (uid.isEmpty) return;
      await _requireFirstChild(context, uid);
      return;
    }
    if (!(await BrushingPrefs.canLogMore(scope))) {
      if (context.mounted) {
        showPillSnackBar(
          context,
          'Já registou as ${BrushingPrefs.maxPerDay} escovagens de hoje!',
        );
      }
      return;
    }
    await BrushingPrefs.logToday(scope);
    await state?.refreshStats();
    if (context.mounted) {
      showPillSnackBar(context, 'Escovagem registada!');
    }
  }
}

/// Faz [child] "respirar" (escala sobe e desce suavemente, em loop) — usado
/// para chamar a atenção para os dois destaques principais da Home (o quiz
/// e o vídeo em destaque), que são o carro-chefe da app.
class _Pulse extends StatefulWidget {
  const _Pulse({
    required this.child,
    this.minScale = 0.94,
    this.maxScale = 1.0,
    this.duration = const Duration(milliseconds: 1100),
  });

  final Widget child;
  final double minScale;
  final double maxScale;
  final Duration duration;

  @override
  State<_Pulse> createState() => _PulseState();
}

class _PulseState extends State<_Pulse> with SingleTickerProviderStateMixin {
  late final AnimationController _controller = AnimationController(
    vsync: this,
    duration: widget.duration,
  )..repeat(reverse: true);
  late final Animation<double> _scale = Tween(
    begin: widget.minScale,
    end: widget.maxScale,
  ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut));

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ScaleTransition(scale: _scale, child: widget.child);
  }
}

/// Pequeno rótulo maiúsculo discreto usado para separar as secções da Home
/// ("Para {nome}", "Novo episódio", "Continuar a aprender").
class _HomeSectionLabel extends StatelessWidget {
  const _HomeSectionLabel(this.text);

  final String text;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(left: 4),
      child: Text(
        text.toUpperCase(),
        style: TextStyle(
          fontSize: 12,
          fontWeight: FontWeight.w800,
          letterSpacing: 0.6,
          color: Colors.black.withValues(alpha: 0.45),
        ),
      ),
    );
  }
}

class _StatsRow extends StatelessWidget {
  const _StatsRow({
    required this.brushingCount,
    required this.weeklyGoal,
    required this.brushedToday,
    required this.watchedCount,
    required this.onTapBrushing,
  });

  final int? brushingCount;
  final int weeklyGoal;
  final bool brushedToday;
  final int? watchedCount;
  final VoidCallback onTapBrushing;

  @override
  Widget build(BuildContext context) {
    return IntrinsicHeight(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(
            child: TapBounce(
              scale: 0.97,
              child: _StatCard(
                icon: Icons.brush_rounded,
                iconColor: const Color(0xFFFF55A7),
                value: brushingCount == null
                    ? '--'
                    : '$brushingCount/$weeklyGoal',
                label: 'Escovagens esta semana',
                done: brushedToday,
                onTap: onTapBrushing,
              ),
            ),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: _StatCard(
              icon: Icons.movie_filter_rounded,
              iconColor: const Color(0xFF8E7CC3),
              value: watchedCount == null ? '--' : '$watchedCount',
              label: 'Episódios completos',
            ),
          ),
        ],
      ),
    );
  }
}

class _StatCard extends StatelessWidget {
  const _StatCard({
    required this.icon,
    required this.iconColor,
    required this.value,
    required this.label,
    this.onTap,
    this.done = false,
  });

  final IconData icon;
  final Color iconColor;
  final String value;
  final String label;
  final VoidCallback? onTap;
  final bool done;

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.white,
      borderRadius: BorderRadius.circular(20),
      elevation: 8,
      shadowColor: Colors.black.withValues(alpha: 0.10),
      child: InkWell(
        borderRadius: BorderRadius.circular(20),
        onTap: onTap,
        child: Padding(
          padding: const EdgeInsets.all(14),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Stack(
                clipBehavior: Clip.none,
                children: [
                  Container(
                    width: 38,
                    height: 38,
                    decoration: BoxDecoration(
                      color: iconColor.withValues(alpha: 0.14),
                      borderRadius: BorderRadius.circular(12),
                    ),
                    child: Icon(icon, color: iconColor, size: 20),
                  ),
                  if (done)
                    Positioned(
                      top: -4,
                      right: -4,
                      child: Container(
                        width: 16,
                        height: 16,
                        decoration: const BoxDecoration(
                          color: Color(0xFF2F9E94),
                          shape: BoxShape.circle,
                        ),
                        child: const Icon(
                          Icons.check_rounded,
                          size: 11,
                          color: Colors.white,
                        ),
                      ),
                    ),
                ],
              ),
              const SizedBox(height: 10),
              Text(
                value,
                style: const TextStyle(
                  fontWeight: FontWeight.w900,
                  fontSize: 20,
                ),
              ),
              const SizedBox(height: 2),
              Text(
                label,
                style: TextStyle(
                  fontSize: 11.5,
                  fontWeight: FontWeight.w600,
                  color: Colors.black.withValues(alpha: 0.6),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Future<Map<String, dynamic>?> _createChildViaSheet(
  BuildContext context,
  String uid,
) async {
  final result = await showModalBottomSheet<Map<String, dynamic>?>(
    context: context,
    isScrollControlled: true,
    showDragHandle: true,
    backgroundColor: const Color(0xFFFFE6F1),
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
    ),
    builder: (ctx) => const _AddChildSheet(),
  );

  if (result == null) return null;
  if (!context.mounted) return null;

  try {
    final inserted = await supabase
        .from('children')
        .insert({...result, 'owner_id': uid})
        .select()
        .single();
    return inserted;
  } catch (e) {
    if (!context.mounted) return null;
    showPillSnackBar(context, 'Erro ao adicionar criança: $e');
    return null;
  }
}

Future<Map<String, dynamic>?> _requireFirstChild(
  BuildContext context,
  String uid,
) async {
  final proceed = await showConfirmDialog(
    context,
    title: 'Registe uma criança',
    message: 'Antes de iniciar o quiz, adicione uma criança ao seu perfil.',
    confirmLabel: 'Adicionar criança',
  );

  if (proceed != true) return null;
  if (!context.mounted) return null;
  return _createChildViaSheet(context, uid);
}

Future<Map<String, dynamic>?> _pickChildSheet(
  BuildContext context,
  List<Map<String, dynamic>> children,
) {
  const Color teal = Color(0xFF2F9E94);
  return showModalBottomSheet<Map<String, dynamic>?>(
    context: context,
    isScrollControlled: true,
    showDragHandle: true,
    backgroundColor: const Color(0xFFFFE6F1),
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
    ),
    builder: (ctx) {
      final maxHeight = MediaQuery.sizeOf(ctx).height * 0.8;
      return SafeArea(
        child: ConstrainedBox(
          constraints: BoxConstraints(maxHeight: maxHeight),
          child: Padding(
            padding: const EdgeInsets.fromLTRB(18, 6, 18, 18),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                const Text(
                  'Para qual criança é o quiz?',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.w900,
                    color: Color(0xFFFF55A7),
                  ),
                ),
                const SizedBox(height: 14),
                Flexible(
                  child: SingleChildScrollView(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: children.map((c) {
                        final name = (c['name'] ?? '').toString();
                        final age = _childAge(c);
                        final label = age != null
                            ? '$name  •  $age anos'
                            : name;
                        return Padding(
                          padding: const EdgeInsets.only(bottom: 10),
                          child: TapBounce(
                            scale: 0.97,
                            child: Material(
                              color: Colors.white.withValues(alpha: 0.85),
                              borderRadius: BorderRadius.circular(16),
                              child: InkWell(
                                borderRadius: BorderRadius.circular(16),
                                onTap: () => Navigator.of(ctx).pop(c),
                                child: Padding(
                                  padding: const EdgeInsets.symmetric(
                                    horizontal: 16,
                                    vertical: 14,
                                  ),
                                  child: Row(
                                    children: [
                                      Expanded(
                                        child: Text(
                                          label,
                                          style: const TextStyle(
                                            fontWeight: FontWeight.w800,
                                          ),
                                        ),
                                      ),
                                      const Icon(
                                        Icons.chevron_right_rounded,
                                        color: teal,
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                          ),
                        );
                      }).toList(),
                    ),
                  ),
                ),
                const SizedBox(height: 4),
                TextButton(
                  onPressed: () => Navigator.of(ctx).pop(null),
                  child: const Text('Cancelar'),
                ),
              ],
            ),
          ),
        ),
      );
    },
  );
}

class _HeroQuizCard extends StatelessWidget {
  const _HeroQuizCard({required this.onStartQuiz});

  final VoidCallback onStartQuiz;

  @override
  Widget build(BuildContext context) {
    return Material(
      elevation: 18,
      shadowColor: const Color(0xFFFF55A7).withValues(alpha: 0.45),
      borderRadius: BorderRadius.circular(28),
      clipBehavior: Clip.antiAlias,
      color: Colors.transparent,
      child: Ink(
        decoration: const BoxDecoration(gradient: kPinkHeroGradient),
        child: Stack(
          clipBehavior: Clip.none,
          children: [
            Positioned(
              right: -34,
              bottom: -34,
              child: IgnorePointer(
                child: Opacity(
                  opacity: 0.14,
                  child: Container(
                    width: 160,
                    height: 160,
                    decoration: const BoxDecoration(
                      color: Colors.white,
                      shape: BoxShape.circle,
                    ),
                  ),
                ),
              ),
            ),
            Positioned(
              right: 4,
              bottom: 10,
              child: IgnorePointer(
                child: Opacity(
                  opacity: 0.16,
                  child: Transform.rotate(
                    angle: -0.22,
                    child: const Icon(
                      Icons.health_and_safety_rounded,
                      size: 92,
                      color: Colors.white,
                    ),
                  ),
                ),
              ),
            ),
            Positioned(
              left: -18,
              top: -18,
              child: IgnorePointer(
                child: Opacity(
                  opacity: 0.10,
                  child: Container(
                    width: 70,
                    height: 70,
                    decoration: const BoxDecoration(
                      color: Colors.white,
                      shape: BoxShape.circle,
                    ),
                  ),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Container(
                        padding: const EdgeInsets.symmetric(
                          horizontal: 10,
                          vertical: 5,
                        ),
                        decoration: BoxDecoration(
                          color: Colors.white.withValues(alpha: 0.22),
                          borderRadius: BorderRadius.circular(999),
                        ),
                        child: const Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            Icon(
                              Icons.bolt_rounded,
                              color: Colors.white,
                              size: 14,
                            ),
                            SizedBox(width: 4),
                            Text(
                              'Avaliação gratuita',
                              style: TextStyle(
                                color: Colors.white,
                                fontWeight: FontWeight.w800,
                                fontSize: 12,
                              ),
                            ),
                          ],
                        ),
                      ),
                      const SizedBox(width: 8),
                      _Pulse(
                        minScale: 0.85,
                        maxScale: 1.15,
                        duration: const Duration(milliseconds: 900),
                        child: Container(
                          width: 8,
                          height: 8,
                          decoration: const BoxDecoration(
                            color: Colors.white,
                            shape: BoxShape.circle,
                          ),
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 14),
                  const Text(
                    'Avaliação de má oclusão dentária',
                    style: TextStyle(
                      fontWeight: FontWeight.w900,
                      fontSize: 22,
                      height: 1.1,
                      color: Colors.white,
                    ),
                  ),
                  const SizedBox(height: 5),
                  Text(
                    '29 perguntas rápidas · menos de 3 minutos',
                    style: TextStyle(
                      color: Colors.white.withValues(alpha: 0.92),
                      fontWeight: FontWeight.w600,
                      fontSize: 13,
                    ),
                  ),
                  const SizedBox(height: 18),
                  _Pulse(
                    minScale: 0.985,
                    maxScale: 1.0,
                    duration: const Duration(milliseconds: 1400),
                    child: SizedBox(
                      height: 50,
                      width: double.infinity,
                      child: FilledButton.icon(
                        style: FilledButton.styleFrom(
                          backgroundColor: Colors.white,
                          foregroundColor: const Color(0xFFFF55A7),
                          shape: const StadiumBorder(),
                          elevation: 6,
                          shadowColor: Colors.black.withValues(alpha: 0.25),
                          textStyle: const TextStyle(
                            fontWeight: FontWeight.w800,
                            fontSize: 15.5,
                          ),
                        ),
                        onPressed: onStartQuiz,
                        icon: const Icon(Icons.play_arrow_rounded),
                        label: const Text('Iniciar Quiz'),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

/// Card de destaque (mesma linguagem visual do card do quiz: gradiente,
/// badge, título, botão branco) que convida a criança/pai a ir ver a
/// biblioteca de vídeos — sem nenhuma miniatura/imagem de vídeo específica,
/// só ícone e texto. Um único toque (no card ou no botão) leva direto à
/// grelha onde se escolhe qual episódio assistir.
class _VideoLibraryCard extends StatelessWidget {
  const _VideoLibraryCard({required this.watchedCount, required this.onTap});

  final int watchedCount;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return Material(
      elevation: 14,
      shadowColor: const Color(0xFF2F9E94).withValues(alpha: 0.38),
      borderRadius: BorderRadius.circular(28),
      clipBehavior: Clip.antiAlias,
      color: Colors.transparent,
      child: Ink(
        decoration: const BoxDecoration(gradient: kGreenButtonGradient),
        child: InkWell(
          onTap: onTap,
          child: Stack(
            clipBehavior: Clip.none,
            children: [
              Positioned(
                right: -30,
                bottom: -30,
                child: IgnorePointer(
                  child: Opacity(
                    opacity: 0.14,
                    child: Container(
                      width: 150,
                      height: 150,
                      decoration: const BoxDecoration(
                        color: Colors.white,
                        shape: BoxShape.circle,
                      ),
                    ),
                  ),
                ),
              ),
              Positioned(
                right: 6,
                bottom: 6,
                child: IgnorePointer(
                  child: Opacity(
                    opacity: 0.16,
                    child: Transform.rotate(
                      angle: 0.2,
                      child: const Icon(
                        Icons.smart_display_rounded,
                        size: 88,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ),
              ),
              Padding(
                padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Container(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 10,
                        vertical: 5,
                      ),
                      decoration: BoxDecoration(
                        color: Colors.white.withValues(alpha: 0.22),
                        borderRadius: BorderRadius.circular(999),
                      ),
                      child: const Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Icon(
                            Icons.play_circle_fill_rounded,
                            color: Colors.white,
                            size: 14,
                          ),
                          SizedBox(width: 4),
                          Text(
                            'Biblioteca de vídeos',
                            style: TextStyle(
                              color: Colors.white,
                              fontWeight: FontWeight.w800,
                              fontSize: 12,
                            ),
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(height: 14),
                    const Text(
                      'Vídeos educativos',
                      style: TextStyle(
                        fontWeight: FontWeight.w900,
                        fontSize: 22,
                        height: 1.1,
                        color: Colors.white,
                      ),
                    ),
                    const SizedBox(height: 5),
                    Text(
                      watchedCount > 0
                          ? '$watchedCount episódio${watchedCount == 1 ? '' : 's'} completo${watchedCount == 1 ? '' : 's'} · ${videoList.length} no total'
                          : '${videoList.length} episódios sobre saúde oral para toda a família',
                      style: TextStyle(
                        color: Colors.white.withValues(alpha: 0.92),
                        fontWeight: FontWeight.w600,
                        fontSize: 13,
                      ),
                    ),
                    const SizedBox(height: 18),
                    SizedBox(
                      height: 48,
                      width: double.infinity,
                      child: FilledButton.icon(
                        style: FilledButton.styleFrom(
                          backgroundColor: Colors.white,
                          foregroundColor: const Color(0xFF2F9E94),
                          shape: const StadiumBorder(),
                          textStyle: const TextStyle(
                            fontWeight: FontWeight.w800,
                            fontSize: 15,
                          ),
                        ),
                        onPressed: onTap,
                        icon: const Icon(Icons.video_library_rounded),
                        label: const Text('Ver vídeos'),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _PerfilTab extends StatefulWidget {
  const _PerfilTab({
    required this.selectedChildIndex,
    required this.onChildSelected,
  });

  final int selectedChildIndex;
  final void Function(int index, String? name, String? scopeId) onChildSelected;

  @override
  State<_PerfilTab> createState() => _PerfilTabState();
}

class _PerfilTabState extends State<_PerfilTab> {
  bool _addingChild = false;
  bool _updatingPhoto = false;

  bool _initialLoading = true;
  Map<String, dynamic>? _profileData;
  List<Map<String, dynamic>> _children = const [];

  @override
  void initState() {
    super.initState();
    _loadPerfilData().whenComplete(() {
      if (mounted) setState(() => _initialLoading = false);
    });
  }

  // Busca simples (sem Realtime): o Realtime do Supabase pode travar depois de
  // várias trocas de aba/reconexões, deixando a lista de filhos e a foto sem
  // atualizar. Como só o próprio usuário edita esses dados, buscamos uma vez
  // e recarregamos manualmente após cada ação (adicionar/remover filho, trocar
  // foto), o que é bem mais confiável.
  Future<void> _loadPerfilData() async {
    final uid = (supabase.auth.currentUser?.id ?? '').trim();
    if (uid.isEmpty) return;
    try {
      final profile = await supabase
          .from('profiles')
          .select()
          .eq('id', uid)
          .maybeSingle();
      final children = await supabase
          .from('children')
          .select()
          .eq('owner_id', uid)
          .order('created_at');
      if (!mounted) return;
      setState(() {
        _profileData = profile;
        _children = children;
      });
    } catch (_) {
      // mantém os dados já carregados; usuário pode tentar de novo
    }
  }

  Future<QuizResultData?> _loadScoreForScope(String scopeId) {
    return QuizPrefs.getLastResultForScope(scopeId);
  }

  Future<void> _pickAndUploadProfilePhoto(
    BuildContext context,
    String uid,
  ) async {
    if (_updatingPhoto) return;

    final source = await showModalBottomSheet<ImageSource>(
      context: context,
      showDragHandle: true,
      backgroundColor: const Color(0xFFFFE6F1),
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
      ),
      builder: (ctx) {
        return SafeArea(
          child: Padding(
            padding: const EdgeInsets.fromLTRB(18, 6, 18, 18),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                const Text(
                  'Foto de perfil',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.w900,
                    color: Color(0xFFFF55A7),
                  ),
                ),
                const SizedBox(height: 14),
                ClipRRect(
                  borderRadius: BorderRadius.circular(999),
                  child: DecoratedBox(
                    decoration: const BoxDecoration(
                      gradient: kGreenButtonGradient,
                    ),
                    child: SizedBox(
                      height: 46,
                      child: FilledButton(
                        style: FilledButton.styleFrom(
                          backgroundColor: Colors.transparent,
                          foregroundColor: Colors.white,
                          shape: const StadiumBorder(),
                          textStyle: const TextStyle(
                            fontWeight: FontWeight.w900,
                          ),
                        ),
                        onPressed: () =>
                            Navigator.of(ctx).pop(ImageSource.camera),
                        child: const Text('Câmara'),
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 10),
                ClipRRect(
                  borderRadius: BorderRadius.circular(999),
                  child: DecoratedBox(
                    decoration: const BoxDecoration(
                      gradient: kGreenButtonGradient,
                    ),
                    child: SizedBox(
                      height: 46,
                      child: FilledButton(
                        style: FilledButton.styleFrom(
                          backgroundColor: Colors.transparent,
                          foregroundColor: Colors.white,
                          shape: const StadiumBorder(),
                          textStyle: const TextStyle(
                            fontWeight: FontWeight.w900,
                          ),
                        ),
                        onPressed: () =>
                            Navigator.of(ctx).pop(ImageSource.gallery),
                        child: const Text('Galeria'),
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 8),
                SizedBox(
                  height: 42,
                  child: TextButton(
                    style: TextButton.styleFrom(
                      foregroundColor: const Color(0xFF2F9E94),
                    ),
                    onPressed: () => Navigator.of(ctx).pop(),
                    child: const Text('Cancelar'),
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );

    if (source == null) return;

    final picker = ImagePicker();
    final picked = await picker.pickImage(
      source: source,
      imageQuality: 82,
      maxWidth: 1024,
    );
    if (picked == null) return;

    setState(() => _updatingPhoto = true);
    try {
      final file = File(picked.path);
      final path = '$uid/profile.jpg';
      await supabase.storage
          .from('photos')
          .upload(path, file, fileOptions: const FileOptions(upsert: true));
      final publicUrl = supabase.storage.from('photos').getPublicUrl(path);
      final url = '$publicUrl?t=${DateTime.now().millisecondsSinceEpoch}';

      await supabase.from('profiles').upsert({'id': uid, 'photo_url': url});

      await _loadPerfilData();
      if (context.mounted) {
        context
            .findAncestorStateOfType<_LoggedHomeScreenState>()
            ?.updateCachedPhoto(url);
      }
    } catch (e) {
      if (!context.mounted) return;
      showPillSnackBar(context, 'Erro ao enviar foto: $e');
    } finally {
      if (mounted) setState(() => _updatingPhoto = false);
    }
  }

  Future<void> _confirmDeleteChild(
    BuildContext context, {
    required String childId,
    required String childName,
  }) async {
    final confirmed = await showConfirmDialog(
      context,
      title: 'Remover criança',
      message:
          'Tem a certeza que quer remover "$childName"? Esta ação não pode ser desfeita.',
      confirmLabel: 'Remover',
      confirmColor: const Color(0xFFFF55A7),
    );

    if (confirmed != true) return;
    if (!context.mounted) return;

    try {
      final deleted = await supabase
          .from('children')
          .delete()
          .eq('id', childId)
          .select('id');

      if (deleted.isEmpty) {
        throw StateError('Sem permissão para remover esta criança.');
      }

      widget.onChildSelected(0, null, null);
      await _loadPerfilData();
      if (context.mounted) showPillSnackBar(context, 'Criança removida');
    } catch (e) {
      if (context.mounted) {
        showPillSnackBar(context, 'Erro ao remover: $e');
      }
    }
  }

  Future<void> _editWeeklyGoal(
    BuildContext context, {
    required String scopeId,
    required String childName,
  }) async {
    final current = await BrushingPrefs.getWeeklyGoal(scopeId);
    if (!context.mounted) return;
    final controller = TextEditingController(text: current.toString());

    final saved = await showDialog<int>(
      context: context,
      builder: (ctx) {
        return AlertDialog(
          backgroundColor: const Color(0xFFFFE6F1),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20),
          ),
          title: Text(
            'Meta semanal de $childName',
            style: const TextStyle(
              fontWeight: FontWeight.w900,
              color: Color(0xFFFF55A7),
            ),
          ),
          content: TextField(
            controller: controller,
            keyboardType: TextInputType.number,
            autofocus: true,
            decoration: const InputDecoration(
              labelText: 'Escovagens por semana',
              helperText: 'Entre 1 e 21 (até 3 por dia)',
            ),
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(ctx).pop(),
              child: const Text('Cancelar'),
            ),
            ClipRRect(
              borderRadius: BorderRadius.circular(999),
              child: DecoratedBox(
                decoration: const BoxDecoration(gradient: kGreenButtonGradient),
                child: FilledButton(
                  style: FilledButton.styleFrom(
                    backgroundColor: Colors.transparent,
                    foregroundColor: Colors.white,
                    shape: const StadiumBorder(),
                  ),
                  onPressed: () {
                    final value = int.tryParse(controller.text.trim());
                    if (value == null || value < 1 || value > 21) return;
                    Navigator.of(ctx).pop(value);
                  },
                  child: const Text('Guardar'),
                ),
              ),
            ),
          ],
        );
      },
    );

    if (saved == null) return;
    await BrushingPrefs.setWeeklyGoal(scopeId, saved);
    if (!context.mounted) return;
    context.findAncestorStateOfType<_LoggedHomeScreenState>()?.refreshStats();
    setState(() {});
  }

  Future<void> _addAnotherChild(BuildContext context, String uid) async {
    if (_addingChild) return;
    final result = await showModalBottomSheet<Map<String, dynamic>?>(
      context: context,
      isScrollControlled: true,
      showDragHandle: true,
      backgroundColor: const Color(0xFFFFE6F1),
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
      ),
      builder: (ctx) => const _AddChildSheet(),
    );

    if (!mounted) return;

    if (result == null) return;

    final childMap = {...result, 'owner_id': uid};

    setState(() => _addingChild = true);
    try {
      await supabase
          .from('children')
          .insert(childMap)
          .timeout(const Duration(seconds: 20));

      if (!mounted) return;
      await _loadPerfilData();
      if (context.mounted) showPillSnackBar(context, 'Criança adicionada');

      if (mounted) {
        setState(() => _addingChild = false);
      }

      if (!mounted) return;
      if (!mounted) return;
      final addMore = await showConfirmDialog(
        // ignore: use_build_context_synchronously
        context,
        title: 'Adicionar outra criança?',
        cancelLabel: 'Agora não',
        confirmLabel: 'Adicionar outra',
      );

      if (!mounted) return;
      if (addMore == true) {
        await Future<void>.delayed(const Duration(milliseconds: 120));
        if (!mounted) return;
        if (!mounted) return;
        if (!mounted) return;
        // ignore: use_build_context_synchronously
        await _addAnotherChild(context, uid);
      }
    } on TimeoutException {
      if (!mounted || !context.mounted) return;
      showPillSnackBar(
        context,
        'Tempo esgotado ao adicionar. Tente novamente.',
      );
    } catch (e) {
      if (!mounted || !context.mounted) return;
      showPillSnackBar(context, 'Erro ao adicionar: $e');
    } finally {
      if (mounted) setState(() => _addingChild = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    final user = supabase.auth.currentUser;
    final uid = (user?.id ?? '').trim();
    final name = (user?.userMetadata?['name'] ?? '').toString().trim();
    final email = (user?.email ?? '').trim();
    final shownName = name.isNotEmpty ? name : 'Sem nome';

    if (uid.isEmpty) {
      return const SizedBox.shrink();
    }

    if (_initialLoading) {
      return const Center(
        child: Padding(
          padding: EdgeInsets.only(top: 60),
          child: CircularProgressIndicator(color: Color(0xFF2F9E94)),
        ),
      );
    }

    final data = _profileData;
    final storedName = (data?['name'] ?? '').toString().trim();
    final profileName = storedName.isNotEmpty ? storedName : shownName;
    final photoUrl = (data?['photo_url'] ?? '').toString().trim();
    final storedEmail = (data?['email'] ?? '').toString().trim();
    final profileEmail = storedEmail.isNotEmpty ? storedEmail : email;

    final children = _children;
    final int selectedIndex = children.isEmpty
        ? 0
        : widget.selectedChildIndex.clamp(
            0,
            (children.length - 1).clamp(0, 999999),
          );

    return Align(
      alignment: Alignment.topCenter,
      child: Padding(
        padding: const EdgeInsets.only(top: 10),
        child: ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 560),
          child: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                FadeSlideIn(
                  child: Material(
                    elevation: 10,
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(20),
                    shadowColor: Colors.black.withValues(alpha: 0.16),
                    child: Padding(
                      padding: const EdgeInsets.all(18),
                      child: Row(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: [
                          TapBounce(
                            scale: 0.92,
                            child: InkWell(
                              borderRadius: BorderRadius.circular(40),
                              onTap: _updatingPhoto
                                  ? null
                                  : () => _pickAndUploadProfilePhoto(
                                      context,
                                      uid,
                                    ),
                              child: Stack(
                                clipBehavior: Clip.none,
                                children: [
                                  Container(
                                    width: 76,
                                    height: 76,
                                    decoration: BoxDecoration(
                                      color: const Color(0xFFFFE6F1),
                                      shape: BoxShape.circle,
                                      border: Border.all(
                                        color: const Color(
                                          0xFF2F9E94,
                                        ).withValues(alpha: 0.35),
                                        width: 2,
                                      ),
                                    ),
                                    clipBehavior: Clip.antiAlias,
                                    child: Stack(
                                      fit: StackFit.expand,
                                      children: [
                                        if (photoUrl.isNotEmpty)
                                          Image.network(
                                            photoUrl,
                                            fit: BoxFit.cover,
                                          )
                                        else
                                          const Icon(
                                            Icons.person_rounded,
                                            size: 42,
                                            color: Color(0xFF2F9E94),
                                          ),
                                        if (_updatingPhoto)
                                          Container(
                                            color: Colors.black.withValues(
                                              alpha: 0.25,
                                            ),
                                            child: const Center(
                                              child: SizedBox(
                                                width: 22,
                                                height: 22,
                                                child:
                                                    CircularProgressIndicator(
                                                      strokeWidth: 2,
                                                    ),
                                              ),
                                            ),
                                          ),
                                      ],
                                    ),
                                  ),
                                  Positioned(
                                    right: -2,
                                    bottom: -2,
                                    child: Container(
                                      width: 26,
                                      height: 26,
                                      decoration: const BoxDecoration(
                                        color: Color(0xFFFF55A7),
                                        shape: BoxShape.circle,
                                      ),
                                      child: const Icon(
                                        Icons.camera_alt_rounded,
                                        size: 14,
                                        color: Colors.white,
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                          const SizedBox(width: 14),
                          Expanded(
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Text(
                                  profileName,
                                  maxLines: 1,
                                  overflow: TextOverflow.ellipsis,
                                  style: const TextStyle(
                                    fontSize: 20,
                                    fontWeight: FontWeight.w900,
                                    color: Color(0xFFFF55A7),
                                  ),
                                ),
                                if (profileEmail.isNotEmpty) ...[
                                  const SizedBox(height: 4),
                                  Text(
                                    profileEmail,
                                    maxLines: 1,
                                    overflow: TextOverflow.ellipsis,
                                    style: TextStyle(
                                      fontSize: 13,
                                      fontWeight: FontWeight.w600,
                                      color: Colors.black.withValues(
                                        alpha: 0.55,
                                      ),
                                    ),
                                  ),
                                ],
                              ],
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 22),
                Padding(
                  padding: const EdgeInsets.only(left: 4, bottom: 10),
                  child: Row(
                    children: [
                      const Text(
                        'Meus filhos',
                        style: TextStyle(
                          color: Color(0xFF2F9E94),
                          fontWeight: FontWeight.w900,
                          fontSize: 15,
                        ),
                      ),
                      const SizedBox(width: 8),
                      Container(
                        padding: const EdgeInsets.symmetric(
                          horizontal: 8,
                          vertical: 2,
                        ),
                        decoration: BoxDecoration(
                          color: const Color(
                            0xFF2F9E94,
                          ).withValues(alpha: 0.10),
                          borderRadius: BorderRadius.circular(999),
                        ),
                        child: Text(
                          '${children.length}',
                          style: const TextStyle(
                            color: Color(0xFF2F9E94),
                            fontWeight: FontWeight.w900,
                            fontSize: 12,
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
                if (children.isEmpty)
                  Container(
                    padding: const EdgeInsets.all(18),
                    margin: const EdgeInsets.only(bottom: 12),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(16),
                      border: Border.all(
                        color: Colors.black.withValues(alpha: 0.08),
                      ),
                    ),
                    child: Row(
                      children: [
                        Container(
                          width: 40,
                          height: 40,
                          decoration: BoxDecoration(
                            color: const Color(0xFFFFE6F1),
                            borderRadius: BorderRadius.circular(12),
                          ),
                          child: const Icon(
                            Icons.child_care_rounded,
                            color: Color(0xFFFF55A7),
                          ),
                        ),
                        const SizedBox(width: 12),
                        Expanded(
                          child: Text(
                            'Nenhuma criança adicionada ainda.',
                            style: TextStyle(
                              color: Colors.black.withValues(alpha: 0.62),
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                        ),
                      ],
                    ),
                  )
                else
                  ...children.asMap().entries.map((entry) {
                    final i = entry.key;
                    final c = entry.value;
                    final childId = (c['id'] ?? '').toString().trim();
                    final childName = (c['name'] ?? '').toString().trim();
                    final childAge = _childAge(c);
                    final childGender = (c['gender'] ?? '').toString().trim();
                    final scopeId = '${uid}_$childId';

                    final title = childName.isNotEmpty
                        ? childName
                        : 'Criança ${i + 1}';
                    final subtitle = [
                      if (childAge != null) 'Idade: $childAge',
                      if (childGender.isNotEmpty) 'Género: $childGender',
                    ].join('  •  ');
                    final bool selected = i == selectedIndex;

                    return FadeSlideIn(
                      delay: Duration(milliseconds: 60 * i.clamp(0, 6)),
                      child: Padding(
                        padding: const EdgeInsets.only(bottom: 12),
                        child: TapBounce(
                          scale: 0.97,
                          child: InkWell(
                            borderRadius: BorderRadius.circular(16),
                            onTap: () => widget.onChildSelected(
                              i,
                              childName.isEmpty ? null : childName,
                              scopeId,
                            ),
                            child: Container(
                              padding: const EdgeInsets.all(14),
                              decoration: BoxDecoration(
                                color: selected
                                    ? const Color(0xFFFFE6F1)
                                    : Colors.white,
                                borderRadius: BorderRadius.circular(16),
                                border: Border.all(
                                  color: selected
                                      ? const Color(
                                          0xFF2F9E94,
                                        ).withValues(alpha: 0.45)
                                      : Colors.black.withValues(alpha: 0.10),
                                  width: selected ? 1.6 : 1,
                                ),
                                boxShadow: [
                                  BoxShadow(
                                    color: Colors.black.withValues(alpha: 0.06),
                                    blurRadius: 14,
                                    offset: const Offset(0, 8),
                                  ),
                                ],
                              ),
                              child: Row(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Expanded(
                                    child: Column(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.start,
                                      children: [
                                        Text(
                                          title,
                                          style: const TextStyle(
                                            fontWeight: FontWeight.w900,
                                          ),
                                        ),
                                        if (subtitle.isNotEmpty) ...[
                                          const SizedBox(height: 4),
                                          Text(subtitle),
                                        ],
                                      ],
                                    ),
                                  ),
                                  const SizedBox(width: 10),
                                  FutureBuilder<QuizResultData?>(
                                    future: _loadScoreForScope(scopeId),
                                    builder: (context, snap) {
                                      final result = snap.data;
                                      final text = result == null
                                          ? '--'
                                          : '${result.signs}/$kSignsMax · ${result.factors}/$kFactorsMax';
                                      return Container(
                                        padding: const EdgeInsets.symmetric(
                                          horizontal: 10,
                                          vertical: 8,
                                        ),
                                        decoration: BoxDecoration(
                                          color: const Color(
                                            0xFF2F9E94,
                                          ).withValues(alpha: 0.10),
                                          borderRadius: BorderRadius.circular(
                                            999,
                                          ),
                                        ),
                                        child: Text(
                                          text,
                                          style: const TextStyle(
                                            fontWeight: FontWeight.w900,
                                            color: Color(0xFF2F9E94),
                                          ),
                                        ),
                                      );
                                    },
                                  ),
                                  IconButton(
                                    onPressed: () => _editWeeklyGoal(
                                      context,
                                      scopeId: scopeId,
                                      childName: title,
                                    ),
                                    icon: const Icon(
                                      Icons.edit_outlined,
                                      color: Color(0xFF2F9E94),
                                    ),
                                    tooltip: 'Meta semanal de escovagens',
                                    visualDensity: VisualDensity.compact,
                                  ),
                                  IconButton(
                                    onPressed: () => _confirmDeleteChild(
                                      context,
                                      childId: childId,
                                      childName: title,
                                    ),
                                    icon: const Icon(
                                      Icons.delete_outline_rounded,
                                      color: Color(0xFFFF55A7),
                                    ),
                                    tooltip: 'Remover',
                                    visualDensity: VisualDensity.compact,
                                  ),
                                ],
                              ),
                            ),
                          ),
                        ),
                      ),
                    );
                  }),
                TapBounce(
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(999),
                    child: DecoratedBox(
                      decoration: const BoxDecoration(
                        gradient: kGreenButtonGradient,
                      ),
                      child: SizedBox(
                        height: 48,
                        child: FilledButton.icon(
                          style: FilledButton.styleFrom(
                            backgroundColor: Colors.transparent,
                            foregroundColor: Colors.white,
                            shape: const StadiumBorder(),
                            textStyle: const TextStyle(
                              fontWeight: FontWeight.w800,
                            ),
                          ),
                          onPressed: _addingChild
                              ? null
                              : () => _addAnotherChild(context, uid),
                          icon: const Icon(Icons.add_rounded),
                          label: const Text('Adicionar criança'),
                        ),
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 22),
                TapBounce(
                  child: SizedBox(
                    height: 46,
                    child: OutlinedButton.icon(
                      style: OutlinedButton.styleFrom(
                        foregroundColor: const Color(0xFFFF55A7),
                        side: const BorderSide(
                          color: Color(0xFFFF55A7),
                          width: 1.4,
                        ),
                        shape: const StadiumBorder(),
                        textStyle: const TextStyle(fontWeight: FontWeight.w800),
                      ),
                      onPressed: () async {
                        await supabase.auth.signOut();
                      },
                      icon: const Icon(Icons.logout_rounded),
                      label: const Text('Sair'),
                    ),
                  ),
                ),
                const SizedBox(height: 12),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _AddChildSheet extends StatefulWidget {
  const _AddChildSheet();

  @override
  State<_AddChildSheet> createState() => _AddChildSheetState();
}

class _AddChildSheetState extends State<_AddChildSheet> {
  final _formKey = GlobalKey<FormState>();
  final _nameController = TextEditingController();
  DateTime? _birthDate;
  String? _gender;
  String? _birthDateError;

  @override
  void dispose() {
    _nameController.dispose();
    super.dispose();
  }

  Future<void> _pickBirthDate() async {
    final now = DateTime.now();
    final picked = await showDatePicker(
      context: context,
      initialDate: _birthDate ?? DateTime(now.year - 5, now.month, now.day),
      firstDate: DateTime(now.year - 17, now.month, now.day),
      lastDate: DateTime(now.year - 1, now.month, now.day),
      helpText: 'Data de nascimento',
      cancelText: 'Cancelar',
      confirmText: 'Confirmar',
      locale: const Locale('pt', 'PT'),
    );
    if (picked == null) return;
    setState(() {
      _birthDate = picked;
      _birthDateError = null;
    });
  }

  void _submit() {
    final formOk = _formKey.currentState?.validate() ?? false;
    setState(() {
      _birthDateError = _birthDate == null
          ? 'Indique a data de nascimento'
          : null;
    });
    if (!formOk || _birthDate == null) return;
    Navigator.of(context).pop({
      'name': _nameController.text.trim(),
      'birth_date': _birthDate!.toIso8601String().split('T').first,
      'gender': (_gender ?? '').trim(),
    });
  }

  @override
  Widget build(BuildContext context) {
    final bottomInset = MediaQuery.viewInsetsOf(context).bottom;
    return SafeArea(
      child: Padding(
        padding: EdgeInsets.fromLTRB(18, 6, 18, 18 + bottomInset),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            const Text(
              'Adicionar outra criança',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 18,
                fontWeight: FontWeight.w900,
                color: Color(0xFFFF55A7),
              ),
            ),
            const SizedBox(height: 12),
            Container(
              padding: const EdgeInsets.all(14),
              decoration: BoxDecoration(
                color: Colors.white.withValues(alpha: 0.82),
                borderRadius: BorderRadius.circular(16),
                border: Border.all(color: Colors.black.withValues(alpha: 0.08)),
              ),
              child: Form(
                key: _formKey,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    TextFormField(
                      controller: _nameController,
                      textInputAction: TextInputAction.next,
                      textCapitalization: TextCapitalization.sentences,
                      inputFormatters: [CapitalizeFirstLetterFormatter()],
                      decoration: const InputDecoration(
                        labelText: 'Nome da criança',
                      ),
                      validator: (v) {
                        final value = (v ?? '').trim();
                        if (value.isEmpty) return 'Indique o nome';
                        if (value.length < 2) return 'Nome muito curto';
                        if (!_namePattern.hasMatch(value)) {
                          return 'O nome não pode conter números';
                        }
                        return null;
                      },
                    ),
                    InkWell(
                      borderRadius: BorderRadius.circular(8),
                      onTap: _pickBirthDate,
                      child: InputDecorator(
                        decoration: InputDecoration(
                          labelText: 'Data de nascimento',
                          errorText: _birthDateError,
                          suffixIcon: const Icon(
                            Icons.calendar_today_rounded,
                            size: 18,
                          ),
                        ),
                        child: Text(
                          _birthDate == null
                              ? 'Selecione a data'
                              : '${_birthDate!.day.toString().padLeft(2, '0')}/'
                                    '${_birthDate!.month.toString().padLeft(2, '0')}/'
                                    '${_birthDate!.year}',
                          style: _birthDate == null
                              ? TextStyle(
                                  color: Colors.black.withValues(alpha: 0.4),
                                )
                              : null,
                        ),
                      ),
                    ),
                    DropdownButtonFormField<String>(
                      initialValue: _gender,
                      items: const [
                        DropdownMenuItem(
                          value: 'Masculino',
                          child: Text('Masculino'),
                        ),
                        DropdownMenuItem(
                          value: 'Feminino',
                          child: Text('Feminino'),
                        ),
                        DropdownMenuItem(value: 'Outro', child: Text('Outro')),
                      ],
                      onChanged: (v) => setState(() => _gender = v),
                      decoration: const InputDecoration(labelText: 'Género'),
                      validator: (v) {
                        if (v == null || v.trim().isEmpty) {
                          return 'Selecione o género';
                        }
                        return null;
                      },
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 14),
            Row(
              children: [
                Expanded(
                  child: SizedBox(
                    height: 44,
                    child: TextButton(
                      onPressed: () => Navigator.of(context).pop(null),
                      child: const Text('Cancelar'),
                    ),
                  ),
                ),
                const SizedBox(width: 10),
                Expanded(
                  child: TapBounce(
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(999),
                      child: DecoratedBox(
                        decoration: const BoxDecoration(
                          gradient: kGreenButtonGradient,
                        ),
                        child: SizedBox(
                          height: 44,
                          child: FilledButton(
                            style: FilledButton.styleFrom(
                              backgroundColor: Colors.transparent,
                              foregroundColor: Colors.white,
                              shape: const StadiumBorder(),
                              textStyle: const TextStyle(
                                fontWeight: FontWeight.w900,
                              ),
                            ),
                            onPressed: _submit,
                            child: const Text('Adicionar'),
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
