import 'dart:math' as math;

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:local_auth/local_auth.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';

import '../bloc/auth_bloc.dart';
import '../../../../core/config/environment.dart';

/// UnionFlow — Écran de connexion premium
/// Gradient forêt + glassmorphism + animations + biométrie + remember me
class LoginPage extends StatefulWidget {
  const LoginPage({super.key});

  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> with TickerProviderStateMixin {
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();

  late final AnimationController _fadeController;
  late final AnimationController _slideController;
  late final Animation<double> _fadeAnim;
  late final Animation<Offset> _slideAnim;

  bool _obscurePassword = true;
  bool _rememberMe = false;
  bool _biometricAvailable = false;

  final _localAuth = LocalAuthentication();

  static const _gradTop = Color(0xFF1B5E20);
  static const _gradMid = Color(0xFF2E7D32);
  static const _gradBot = Color(0xFF388E3C);
  static const _primaryGreen = Color(0xFF2E7D32);

  @override
  void initState() {
    super.initState();
    _fadeController = AnimationController(vsync: this, duration: const Duration(milliseconds: 900));
    _slideController = AnimationController(vsync: this, duration: const Duration(milliseconds: 750));
    _fadeAnim = CurvedAnimation(parent: _fadeController, curve: Curves.easeOut);
    _slideAnim = Tween<Offset>(begin: const Offset(0, 0.12), end: Offset.zero)
        .animate(CurvedAnimation(parent: _slideController, curve: Curves.easeOutCubic));
    _fadeController.forward();
    _slideController.forward();
    _checkBiometrics();
    _loadSavedCredentials();
  }

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

  Future<void> _checkBiometrics() async {
    try {
      final canCheck = await _localAuth.canCheckBiometrics;
      final supported = await _localAuth.isDeviceSupported();
      if (mounted) setState(() => _biometricAvailable = canCheck && supported);
    } catch (_) {}
  }

  Future<void> _loadSavedCredentials() async {
    final prefs = await SharedPreferences.getInstance();
    final remember = prefs.getBool('uf_remember_me') ?? false;
    if (remember && mounted) {
      setState(() {
        _rememberMe = true;
        _emailController.text = prefs.getString('uf_saved_email') ?? '';
      });
    }
  }

  Future<void> _authenticateBiometric() async {
    try {
      final ok = await _localAuth.authenticate(
        localizedReason: 'Authentifiez-vous pour accéder à UnionFlow',
        options: const AuthenticationOptions(stickyAuth: true, biometricOnly: false),
      );
      if (ok && mounted) {
        final prefs = await SharedPreferences.getInstance();
        final email = prefs.getString('uf_saved_email') ?? '';
        final pass = prefs.getString('uf_saved_pass') ?? '';
        if (email.isNotEmpty && pass.isNotEmpty) {
          context.read<AuthBloc>().add(AuthLoginRequested(email, pass));
        }
      }
    } catch (_) {}
  }

  Future<void> _openForgotPassword() async {
    final url = Uri.parse(
      '${AppConfig.keycloakRealmUrl}/protocol/openid-connect/auth'
      '?client_id=unionflow-mobile'
      '&redirect_uri=${Uri.encodeComponent('http://localhost')}'
      '&response_type=code&scope=openid&kc_action=reset_credentials',
    );
    try {
      if (await canLaunchUrl(url)) await launchUrl(url, mode: LaunchMode.externalApplication);
    } catch (_) {}
  }

  Future<void> _onLogin() async {
    final email = _emailController.text.trim();
    final password = _passwordController.text;
    if (email.isEmpty || password.isEmpty) return;

    if (_rememberMe) {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setBool('uf_remember_me', true);
      await prefs.setString('uf_saved_email', email);
      await prefs.setString('uf_saved_pass', password);
    } else {
      final prefs = await SharedPreferences.getInstance();
      await prefs.remove('uf_remember_me');
      await prefs.remove('uf_saved_email');
      await prefs.remove('uf_saved_pass');
    }

    if (mounted) context.read<AuthBloc>().add(AuthLoginRequested(email, password));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: BlocConsumer<AuthBloc, AuthState>(
        listener: (context, state) {
          if (state is AuthError) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text(state.message),
                backgroundColor: const Color(0xFFB71C1C),
                behavior: SnackBarBehavior.floating,
                shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
              ),
            );
          }
        },
        builder: (context, state) {
          final isLoading = state is AuthLoading;
          return Stack(
            children: [
              // Gradient background
              Container(
                decoration: const BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                    colors: [_gradTop, _gradMid, _gradBot],
                    stops: [0.0, 0.55, 1.0],
                  ),
                ),
              ),

              // Subtle hexagon pattern overlay
              const Positioned.fill(child: _HexPatternOverlay()),

              // Content
              SafeArea(
                child: Center(
                  child: SingleChildScrollView(
                    padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 24),
                    child: FadeTransition(
                      opacity: _fadeAnim,
                      child: SlideTransition(
                        position: _slideAnim,
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            _buildLogoSection(),
                            const SizedBox(height: 16),
                            _buildGlassCard(isLoading),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ],
          );
        },
      ),
    );
  }

  Widget _buildLogoSection() {
    return Column(
      children: [
        CustomPaint(
          size: const Size(48, 48),
          painter: _HexLogoMark(),
        ),
        const SizedBox(height: 10),
        Text(
          'UnionFlow',
          style: GoogleFonts.roboto(
            fontSize: 34,
            fontWeight: FontWeight.w700,
            color: Colors.white,
            letterSpacing: 0.3,
          ),
        ),
        const SizedBox(height: 6),
        Text(
          'Gérez votre organisation avec sérénité',
          style: GoogleFonts.roboto(
            fontSize: 13,
            fontWeight: FontWeight.w400,
            color: Colors.white.withOpacity(0.78),
            letterSpacing: 0.2,
          ),
          textAlign: TextAlign.center,
        ),
      ],
    );
  }

  Widget _buildGlassCard(bool isLoading) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white.withOpacity(0.11),
        borderRadius: BorderRadius.circular(16),
        border: Border.all(
          color: Colors.white.withOpacity(0.22),
          width: 1.5,
        ),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.18),
            blurRadius: 40,
            offset: const Offset(0, 10),
          ),
        ],
      ),
      padding: const EdgeInsets.fromLTRB(20, 20, 20, 16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Text(
            'Connexion',
            style: GoogleFonts.roboto(
              fontSize: 22,
              fontWeight: FontWeight.w600,
              color: Colors.white,
              letterSpacing: 0.1,
            ),
          ),
          const SizedBox(height: 4),
          Text(
            'Accédez à votre espace de travail',
            style: GoogleFonts.roboto(
              fontSize: 12.5,
              color: Colors.white.withOpacity(0.68),
              letterSpacing: 0.1,
            ),
          ),
          const SizedBox(height: 12),

          _GlassTextField(
            controller: _emailController,
            hint: 'Email ou identifiant',
            icon: Icons.person_outline_rounded,
            keyboardType: TextInputType.emailAddress,
          ),
          const SizedBox(height: 8),

          _GlassTextField(
            controller: _passwordController,
            hint: 'Mot de passe',
            icon: Icons.lock_outline_rounded,
            isPassword: true,
            obscure: _obscurePassword,
            onToggleObscure: () => setState(() => _obscurePassword = !_obscurePassword),
          ),
          const SizedBox(height: 8),

          // Remember me + Forgot password
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              _RememberMeToggle(
                value: _rememberMe,
                onChanged: (v) => setState(() => _rememberMe = v),
              ),
              TextButton(
                onPressed: _openForgotPassword,
                style: TextButton.styleFrom(
                  padding: EdgeInsets.zero,
                  minimumSize: Size.zero,
                  tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                ),
                child: Text(
                  'Mot de passe oublié ?',
                  style: GoogleFonts.roboto(
                    fontSize: 12,
                    color: Colors.white,
                    fontWeight: FontWeight.w600,
                    decoration: TextDecoration.underline,
                    decorationColor: Colors.white.withOpacity(0.7),
                  ),
                ),
              ),
            ],
          ),
          const SizedBox(height: 16),

          // Login button
          isLoading
              ? const Center(child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2.5))
              : ElevatedButton(
                  onPressed: _onLogin,
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.white,
                    foregroundColor: _primaryGreen,
                    padding: const EdgeInsets.symmetric(vertical: 10),
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
                    elevation: 0,
                  ),
                  child: Text(
                    'Se connecter',
                    style: GoogleFonts.roboto(
                      fontSize: 15.5,
                      fontWeight: FontWeight.w700,
                      color: _primaryGreen,
                      letterSpacing: 0.2,
                    ),
                  ),
                ),

          // Biometric
          if (_biometricAvailable) ...[
            const SizedBox(height: 14),
            Center(
              child: TextButton.icon(
                onPressed: _authenticateBiometric,
                icon: const Icon(Icons.fingerprint_rounded, color: Colors.white60, size: 22),
                label: Text(
                  'Connexion biométrique',
                  style: GoogleFonts.roboto(fontSize: 12.5, color: Colors.white60),
                ),
                style: TextButton.styleFrom(
                  padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
                ),
              ),
            ),
          ],
        ],
      ),
    );
  }
}

// ─────────────────────────────────────────────────────────────────────────────
// Sous-composants privés
// ─────────────────────────────────────────────────────────────────────────────

class _GlassTextField extends StatelessWidget {
  const _GlassTextField({
    required this.controller,
    required this.hint,
    required this.icon,
    this.keyboardType,
    this.isPassword = false,
    this.obscure = false,
    this.onToggleObscure,
  });

  final TextEditingController controller;
  final String hint;
  final IconData icon;
  final TextInputType? keyboardType;
  final bool isPassword;
  final bool obscure;
  final VoidCallback? onToggleObscure;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white.withOpacity(0.13),
        borderRadius: BorderRadius.circular(8),
        border: Border.all(color: Colors.white.withOpacity(0.28), width: 1),
      ),
      child: TextField(
        controller: controller,
        obscureText: isPassword && obscure,
        keyboardType: keyboardType,
        style: GoogleFonts.roboto(fontSize: 15, color: Colors.white),
        decoration: InputDecoration(
          hintText: hint,
          hintStyle: GoogleFonts.roboto(fontSize: 14.5, color: Colors.white.withOpacity(0.48)),
          prefixIcon: Icon(icon, color: Colors.white54, size: 20),
          suffixIcon: isPassword
              ? IconButton(
                  icon: Icon(
                    obscure ? Icons.visibility_outlined : Icons.visibility_off_outlined,
                    color: Colors.white54,
                    size: 20,
                  ),
                  onPressed: onToggleObscure,
                )
              : null,
          border: InputBorder.none,
          contentPadding: const EdgeInsets.symmetric(vertical: 10, horizontal: 4),
        ),
      ),
    );
  }
}

class _RememberMeToggle extends StatelessWidget {
  const _RememberMeToggle({required this.value, required this.onChanged});

  final bool value;
  final ValueChanged<bool> onChanged;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => onChanged(!value),
      behavior: HitTestBehavior.opaque,
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          SizedBox(
            width: 18,
            height: 18,
            child: Checkbox(
              value: value,
              onChanged: (v) => onChanged(v ?? false),
              fillColor: WidgetStateProperty.resolveWith((s) {
                if (s.contains(WidgetState.selected)) return Colors.white;
                return Colors.transparent;
              }),
              checkColor: const Color(0xFF2E7D32),
              side: const BorderSide(color: Colors.white60, width: 1.5),
              shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)),
              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
            ),
          ),
          const SizedBox(width: 7),
          Text(
            'Se souvenir de moi',
            style: GoogleFonts.roboto(
              fontSize: 12,
              color: Colors.white.withOpacity(0.78),
            ),
          ),
        ],
      ),
    );
  }
}

// ─────────────────────────────────────────────────────────────────────────────
// Painters
// ─────────────────────────────────────────────────────────────────────────────

/// Motif hexagonal en overlay sur le dégradé (opacité 4%)
class _HexPatternOverlay extends StatelessWidget {
  const _HexPatternOverlay();

  @override
  Widget build(BuildContext context) {
    return CustomPaint(painter: _HexPatternPainter());
  }
}

class _HexPatternPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.white.withOpacity(0.045)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 0.8;

    const r = 22.0;
    const hSpace = r * 1.75;
    const vSpace = r * 1.52;

    for (double row = -1; row * vSpace < size.height + vSpace; row++) {
      final offset = (row % 2 == 0) ? 0.0 : hSpace / 2;
      for (double col = -1; col * hSpace - offset < size.width + hSpace; col++) {
        _hexagon(canvas, paint, Offset(col * hSpace + offset, row * vSpace), r);
      }
    }
  }

  void _hexagon(Canvas canvas, Paint paint, Offset center, double r) {
    final path = Path();
    for (int i = 0; i < 6; i++) {
      final a = (i * 60 - 30) * math.pi / 180;
      final p = Offset(center.dx + r * math.cos(a), center.dy + r * math.sin(a));
      if (i == 0) path.moveTo(p.dx, p.dy); else path.lineTo(p.dx, p.dy);
    }
    path.close();
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

/// Logo hexagonal avec initiales "UF"
class _HexLogoMark extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final cx = size.width / 2;
    final cy = size.height / 2;
    final r = size.width / 2 - 2;

    // Fond hexagonal blanc semi-transparent
    final bgPaint = Paint()
      ..color = Colors.white.withOpacity(0.18)
      ..style = PaintingStyle.fill;
    final borderPaint = Paint()
      ..color = Colors.white.withOpacity(0.6)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.8;

    final path = Path();
    for (int i = 0; i < 6; i++) {
      final a = (i * 60 - 30) * math.pi / 180;
      final p = Offset(cx + r * math.cos(a), cy + r * math.sin(a));
      if (i == 0) path.moveTo(p.dx, p.dy); else path.lineTo(p.dx, p.dy);
    }
    path.close();
    canvas.drawPath(path, bgPaint);
    canvas.drawPath(path, borderPaint);

    // Lignes stylisées "UF" dessinées (plus propre qu'un TextPainter dans un painter)
    final linePaint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.8
      ..strokeCap = StrokeCap.round
      ..strokeJoin = StrokeJoin.round;

    // Lettre U
    final uPath = Path()
      ..moveTo(cx - 13, cy - 10)
      ..lineTo(cx - 13, cy + 5)
      ..quadraticBezierTo(cx - 13, cy + 12, cx - 7, cy + 12)
      ..quadraticBezierTo(cx - 1, cy + 12, cx - 1, cy + 5)
      ..lineTo(cx - 1, cy - 10);
    canvas.drawPath(uPath, linePaint);

    // Lettre F
    canvas.drawLine(Offset(cx + 3, cy - 10), Offset(cx + 3, cy + 12), linePaint);
    canvas.drawLine(Offset(cx + 3, cy - 10), Offset(cx + 13, cy - 10), linePaint);
    canvas.drawLine(Offset(cx + 3, cy + 1), Offset(cx + 11, cy + 1), linePaint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
