import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

import 'auth_gate.dart' show pendingPrivacyUserId, pendingTermsUserId;
import 'main.dart' show supabase;
import 'privacy_gate_prefs.dart';
import 'terms_gate_prefs.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';

const Color _teal = Color(0xFF2F9E94);
const Color _pink = Color(0xFFFF55A7);

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

/// A conta existe no Supabase Auth mas os dados (perfil) já não existem na
/// base de dados — tratada como conta inexistente para efeitos de login.
class _AccountNotFoundException implements Exception {
  const _AccountNotFoundException();
}

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

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final _formKey = GlobalKey<FormState>();
  final _nameController = TextEditingController();
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();

  bool _isLogin = true;
  bool _loading = false;

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

  void _switchTab(bool isLogin) {
    if (_isLogin == isLogin || _loading) return;
    setState(() => _isLogin = isLogin);
    _formKey.currentState?.reset();
  }

  Future<void> _persistRegistrationData({
    required String uid,
    required String name,
    required String email,
  }) async {
    await supabase
        .from('profiles')
        .upsert({'id': uid, 'name': name, 'email': email})
        .timeout(const Duration(seconds: 20));
  }

  Future<void> _submit() async {
    if (!(_formKey.currentState?.validate() ?? false)) return;

    setState(() => _loading = true);
    try {
      final email = _emailController.text.trim();
      final password = _passwordController.text;

      if (_isLogin) {
        final result = await supabase.auth.signInWithPassword(
          email: email,
          password: password,
        );

        final user = result.user;
        if (user != null) {
          final profile = await supabase
              .from('profiles')
              .select('id')
              .eq('id', user.id)
              .maybeSingle();

          if (profile == null) {
            // A conta existe no Auth mas os dados foram apagados (ex.: via
            // "Apagar dados da conta" ou diretamente na base de dados).
            // Trata como inexistente: limpa qualquer resquício e bloqueia.
            unawaited(
              supabase
                  .from('children')
                  .delete()
                  .eq('owner_id', user.id)
                  .catchError((_) => <Map<String, dynamic>>[]),
            );
            await supabase.auth.signOut();
            throw const _AccountNotFoundException();
          }
        }
      } else {
        final name = _nameController.text.trim();
        final response = await supabase.auth
            .signUp(email: email, password: password, data: {'name': name})
            .timeout(const Duration(seconds: 20));

        final user = response.user;
        if (user == null) {
          throw StateError('Utilizador não encontrado após criar a conta.');
        }

        // Antes de persistir o perfil (o que já faz o AuthGate considerar a
        // sessão válida), marca esta conta como pendente de aceitação dos
        // Termos e de consentimento de privacidade — o AuthGate mostra
        // primeiro o TermsGateScreen e, só depois de aceite, o
        // PrivacyGateScreen, em vez do LoggedHome, enquanto estes uids
        // estiverem marcados. Grava também em disco (não só em memória)
        // para os gates sobreviverem caso o processo seja morto antes de o
        // utilizador responder.
        pendingPrivacyUserId.value = user.id;
        unawaited(PrivacyGatePrefs.setPendingUid(user.id));
        pendingTermsUserId.value = user.id;
        unawaited(TermsGatePrefs.setPendingUid(user.id));

        // Precisa de terminar antes de navegar: o AuthGate só mostra a app
        // depois de confirmar que existe um perfil na base de dados.
        await _persistRegistrationData(uid: user.id, name: name, email: email);
      }
    } on _AccountNotFoundException {
      if (!mounted) return;
      showPillSnackBar(
        context,
        'Esta conta já não existe. Verifique o email ou crie uma nova conta.',
      );
    } on AuthException catch (e) {
      if (!mounted) return;
      showPillSnackBar(context, _friendlyAuthError(e));
    } on TimeoutException {
      if (!mounted) return;
      showPillSnackBar(
        context,
        'Tempo esgotado. Verifique a sua ligação e tente novamente.',
      );
    } catch (e) {
      if (!mounted) return;
      showPillSnackBar(context, 'Erro: $e');
    } finally {
      if (mounted) setState(() => _loading = false);
    }
  }

  String _friendlyAuthError(AuthException e) {
    switch (e.code) {
      case 'invalid_credentials':
        return 'Email ou palavra-passe incorretos.';
      case 'user_not_found':
        return 'Utilizador não encontrado.';
      case 'email_exists':
      case 'user_already_exists':
        return 'Este email já está em uso.';
      case 'weak_password':
        return 'Palavra-passe fraca. Utilize pelo menos 6 caracteres.';
      default:
        return e.message;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        clipBehavior: Clip.none,
        children: [
          Positioned.fill(child: Container(color: const Color(0xFFFAFAF7))),
          const LiquidWavesBackground(),
          SafeArea(
            child: LayoutBuilder(
              builder: (context, constraints) {
                return SingleChildScrollView(
                  padding: const EdgeInsets.fromLTRB(24, 28, 24, 20),
                  child: ConstrainedBox(
                    constraints: BoxConstraints(
                      minHeight: constraints.maxHeight,
                    ),
                    child: IntrinsicHeight(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          const FadeSlideIn(
                            child: Text(
                              'Check-Teeth Kids',
                              textAlign: TextAlign.center,
                              style: TextStyle(
                                fontSize: 26,
                                fontWeight: FontWeight.w900,
                                color: _pink,
                                height: 1.0,
                                letterSpacing: -0.5,
                              ),
                            ),
                          ),
                          const SizedBox(height: 8),
                          FadeSlideIn(
                            delay: const Duration(milliseconds: 80),
                            child: Text(
                              'Deteção e Prevenção da Má Oclusão Infantil',
                              textAlign: TextAlign.center,
                              style: TextStyle(
                                fontSize: 13.5,
                                fontWeight: FontWeight.w700,
                                color: Colors.black.withValues(alpha: 0.55),
                              ),
                            ),
                          ),
                          const SizedBox(height: 26),
                          FadeSlideIn(
                            delay: const Duration(milliseconds: 140),
                            child: _AuthTabSwitch(
                              isLogin: _isLogin,
                              onChanged: _switchTab,
                            ),
                          ),
                          const SizedBox(height: 18),
                          FadeSlideIn(
                            delay: const Duration(milliseconds: 190),
                            child: _AuthForm(
                              formKey: _formKey,
                              isLogin: _isLogin,
                              loading: _loading,
                              nameController: _nameController,
                              emailController: _emailController,
                              passwordController: _passwordController,
                              onSubmit: _submit,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

class _AuthTabSwitch extends StatelessWidget {
  const _AuthTabSwitch({required this.isLogin, required this.onChanged});

  final bool isLogin;
  final ValueChanged<bool> onChanged;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(4),
      decoration: BoxDecoration(
        color: Colors.white.withValues(alpha: 0.6),
        borderRadius: BorderRadius.circular(999),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withValues(alpha: 0.06),
            blurRadius: 14,
            offset: const Offset(0, 6),
          ),
        ],
      ),
      child: Row(
        children: [
          Expanded(
            child: _AuthTab(
              label: 'Entrar',
              selected: isLogin,
              onTap: () => onChanged(true),
            ),
          ),
          Expanded(
            child: _AuthTab(
              label: 'Criar Conta',
              selected: !isLogin,
              onTap: () => onChanged(false),
            ),
          ),
        ],
      ),
    );
  }
}

class _AuthTab extends StatelessWidget {
  const _AuthTab({
    required this.label,
    required this.selected,
    required this.onTap,
  });

  final String label;
  final bool selected;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return TapBounce(
      scale: 0.97,
      child: Material(
        color: Colors.transparent,
        child: InkWell(
          borderRadius: BorderRadius.circular(999),
          onTap: onTap,
          child: AnimatedContainer(
            duration: const Duration(milliseconds: 220),
            curve: Curves.easeOutCubic,
            height: 42,
            alignment: Alignment.center,
            decoration: BoxDecoration(
              color: selected ? _teal : Colors.transparent,
              borderRadius: BorderRadius.circular(999),
            ),
            child: Text(
              label,
              style: TextStyle(
                fontWeight: FontWeight.w800,
                fontSize: 14,
                color: selected ? Colors.white : _teal,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class _AuthForm extends StatelessWidget {
  const _AuthForm({
    required this.formKey,
    required this.isLogin,
    required this.loading,
    required this.nameController,
    required this.emailController,
    required this.passwordController,
    required this.onSubmit,
  });

  final GlobalKey<FormState> formKey;
  final bool isLogin;
  final bool loading;
  final TextEditingController nameController;
  final TextEditingController emailController;
  final TextEditingController passwordController;
  final VoidCallback onSubmit;

  @override
  Widget build(BuildContext context) {
    return Form(
      key: formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          AnimatedSize(
            duration: const Duration(milliseconds: 220),
            curve: Curves.easeOutCubic,
            alignment: Alignment.topCenter,
            child: !isLogin
                ? Column(
                    children: [
                      _AuthTextField(
                        controller: nameController,
                        hintText: 'Introduza o seu nome',
                        icon: Icons.person_outline_rounded,
                        textInputAction: TextInputAction.next,
                        textCapitalization: TextCapitalization.sentences,
                        inputFormatters: [CapitalizeFirstLetterFormatter()],
                        validator: (v) {
                          final value = (v ?? '').trim();
                          if (value.isEmpty) return 'Indique o seu nome';
                          if (value.length < 2) return 'Nome muito curto';
                          if (!_namePattern.hasMatch(value)) {
                            return 'O nome não pode conter números';
                          }
                          return null;
                        },
                      ),
                      const SizedBox(height: 12),
                    ],
                  )
                : const SizedBox.shrink(),
          ),
          _AuthTextField(
            controller: emailController,
            hintText: 'Introduza o seu email',
            icon: Icons.mail_outline_rounded,
            keyboardType: TextInputType.emailAddress,
            textInputAction: TextInputAction.next,
            validator: (v) {
              final value = (v ?? '').trim();
              if (value.isEmpty) return 'Indique o seu email';
              if (!value.contains('@')) return 'Email inválido';
              return null;
            },
          ),
          const SizedBox(height: 12),
          _AuthTextField(
            controller: passwordController,
            hintText: 'Introduza a sua palavra-passe',
            icon: Icons.lock_outline_rounded,
            obscureText: true,
            textInputAction: TextInputAction.done,
            validator: (v) {
              final value = v ?? '';
              if (value.isEmpty) return 'Indique a sua palavra-passe';
              if (value.length < 6) return 'Mínimo de 6 caracteres';
              return null;
            },
          ),
          const SizedBox(height: 20),
          TapBounce(
            child: ClipRRect(
              borderRadius: BorderRadius.circular(999),
              child: DecoratedBox(
                decoration: const BoxDecoration(gradient: kGreenButtonGradient),
                child: SizedBox(
                  height: 50,
                  child: FilledButton(
                    style:
                        FilledButton.styleFrom(
                          backgroundColor: Colors.transparent,
                          foregroundColor: Colors.white,
                          shape: const StadiumBorder(),
                          textStyle: const TextStyle(
                            fontWeight: FontWeight.w800,
                            fontSize: 15,
                          ),
                        ).copyWith(
                          animationDuration: const Duration(milliseconds: 180),
                          splashFactory: InkSparkle.splashFactory,
                          overlayColor: WidgetStateProperty.resolveWith<Color?>(
                            (states) {
                              if (states.contains(WidgetState.pressed)) {
                                return Colors.white.withValues(alpha: 0.14);
                              }
                              if (states.contains(WidgetState.hovered) ||
                                  states.contains(WidgetState.focused)) {
                                return Colors.white.withValues(alpha: 0.08);
                              }
                              return null;
                            },
                          ),
                        ),
                    onPressed: loading ? null : onSubmit,
                    child: loading
                        ? const SizedBox(
                            width: 20,
                            height: 20,
                            child: CircularProgressIndicator(
                              strokeWidth: 2.2,
                              color: Colors.white,
                            ),
                          )
                        : Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Text(isLogin ? 'Entrar' : 'Criar Conta'),
                              const SizedBox(width: 8),
                              const Icon(Icons.arrow_forward_rounded, size: 18),
                            ],
                          ),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class _AuthTextField extends StatelessWidget {
  const _AuthTextField({
    required this.controller,
    required this.hintText,
    required this.icon,
    required this.validator,
    this.obscureText = false,
    this.keyboardType,
    this.textInputAction,
    this.textCapitalization = TextCapitalization.none,
    this.inputFormatters,
  });

  final TextEditingController controller;
  final String hintText;
  final IconData icon;
  final FormFieldValidator<String> validator;
  final bool obscureText;
  final TextInputType? keyboardType;
  final TextInputAction? textInputAction;
  final TextCapitalization textCapitalization;
  final List<TextInputFormatter>? inputFormatters;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white.withValues(alpha: 0.92),
        borderRadius: BorderRadius.circular(14),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withValues(alpha: 0.05),
            blurRadius: 10,
            offset: const Offset(0, 4),
          ),
        ],
      ),
      child: TextFormField(
        controller: controller,
        obscureText: obscureText,
        keyboardType: keyboardType,
        textInputAction: textInputAction,
        textCapitalization: textCapitalization,
        inputFormatters: inputFormatters,
        validator: validator,
        style: const TextStyle(fontWeight: FontWeight.w700),
        decoration: InputDecoration(
          hintText: hintText,
          hintStyle: TextStyle(
            fontWeight: FontWeight.w600,
            color: Colors.black.withValues(alpha: 0.35),
          ),
          prefixIcon: Icon(icon, color: _teal, size: 20),
          border: InputBorder.none,
          errorBorder: InputBorder.none,
          focusedBorder: InputBorder.none,
          enabledBorder: InputBorder.none,
          focusedErrorBorder: InputBorder.none,
          contentPadding: const EdgeInsets.symmetric(vertical: 16),
        ),
      ),
    );
  }
}
