import 'package:cloudreve4_flutter/presentation/widgets/desktop_constrained.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:provider/provider.dart';
import '../../../core/exceptions/app_exception.dart';
import '../../../core/validators/string_validator.dart';
import '../../../data/models/login_config_model.dart';
import '../../providers/auth_provider.dart';
import '../../../services/api_service.dart';
import '../../../services/auth_service.dart';
import '../../../services/captcha_service.dart';
import '../../../services/server_service.dart';
import '../../../router/app_router.dart';
import 'forgot_password_page.dart';
import 'register_page.dart';
import '../../widgets/toast_helper.dart';

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

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

class _LoginPageState extends State<LoginPage> {
  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();
  final _focusNode = FocusNode();
  bool _obscurePassword = true;
  bool _rememberMe = false;
  bool _isLoading = false;
  LoginConfigModel _loginConfig = const LoginConfigModel();

  @override
  void initState() {
    super.initState();
    _loadRememberedInfo();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _loadLoginConfig();
    });
  }

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

  Future<void> _loadRememberedInfo() async {
    final server = ServerService.instance.currentServer;
    if (server != null) {
      setState(() {
        if (server.email != null) {
          _emailController.text = server.email!;
        }
        if (server.password != null && server.rememberMe) {
          _passwordController.text = server.password!;
        }
        _rememberMe = server.rememberMe;
      });
    }
  }

  Future<void> _loadLoginConfig() async {
    final server = ServerService.instance.currentServer;
    if (server == null) return;

    try {
      await ApiService.instance.setBaseUrl(server.baseUrl);
      final config = await AuthService.instance.getLoginConfig().timeout(
        const Duration(seconds: 10),
      );

      if (!mounted) return;
      setState(() => _loginConfig = config);

      if (config.loginCaptcha) {
        await CaptchaService.instance.loadCaptcha(server.baseUrl);
        if (mounted) setState(() {});
      } else {
        CaptchaService.instance.clearCaptcha();
      }
    } catch (_) {}
  }

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

    final captcha = CaptchaService.instance;
    if (_loginConfig.loginCaptcha && !captcha.isWebCaptchaVerified) {
      ToastHelper.failure('请先完成人机验证');
      return;
    }

    final navigator = Navigator.of(context);
    final authProvider = Provider.of<AuthProvider>(context, listen: false);

    setState(() => _isLoading = true);

    try {
      final captchaParams = _loginConfig.loginCaptcha
          ? captcha.getCaptchaParams()
          : <String, String>{};

      final success = await authProvider
          .passwordLogin(
            email: _emailController.text.trim(),
            password: _passwordController.text,
            rememberMe: _rememberMe,
            captcha: captchaParams['captcha'],
            ticket: captchaParams['ticket'],
          )
          .timeout(
            const Duration(seconds: 15),
            onTimeout: () => throw Exception('请求超时'),
          );

      if (mounted) setState(() => _isLoading = false);

      if (success && mounted) {
        _focusNode.unfocus();
        ToastHelper.success('登录成功');
        await Future.delayed(const Duration(seconds: 1));
        if (mounted) navigator.pushReplacementNamed(RouteNames.home);
      } else if (mounted) {
        if (_loginConfig.loginCaptcha) {
          await captcha.refreshCaptcha();
          if (mounted) setState(() {});
        }

        final errorMessage = authProvider.errorMessage;
        if (errorMessage != null && errorMessage.isNotEmpty) {
          final errorMsg = _parseErrorMessage(errorMessage);
          ToastHelper.failure(errorMsg);
        } else {
          ToastHelper.failure('登录失败');
        }
      }
    } on TwoFactorRequiredException catch (e) {
      if (mounted) {
        setState(() => _isLoading = false);
        _showTwoFactorDialog(e.sessionId);
      }
    } catch (e) {
      if (mounted) {
        setState(() => _isLoading = false);
        if (_loginConfig.loginCaptcha) {
          await captcha.refreshCaptcha();
          if (mounted) setState(() {});
        }

        final errorMsg = _parseErrorMessage(e.toString());
        ToastHelper.failure(errorMsg);
      }
    }
  }

  Future<void> _showTwoFactorDialog(String sessionId) async {
    final success = await showDialog<bool>(
      context: context,
      barrierDismissible: false,
      builder: (context) => _TwoFactorDialog(
        sessionId: sessionId,
        email: _emailController.text.trim(),
        password: _passwordController.text,
        rememberMe: _rememberMe,
      ),
    );

    if (success != true || !mounted) return;

    _focusNode.unfocus();
    ToastHelper.success('登录成功');
    await Future.delayed(const Duration(seconds: 1));
    if (mounted) Navigator.of(context).pushReplacementNamed(RouteNames.home);
  }

  String _parseErrorMessage(String error) {
    if (error.startsWith('Exception(') || error.startsWith('AppException(')) {
      final startIdx = error.indexOf('(');
      final endIdx = error.lastIndexOf(')');
      if (startIdx != -1 && endIdx != -1 && endIdx > startIdx) {
        return error.substring(startIdx + 1, endIdx).trim();
      }
    }
    if (error.contains(':')) {
      final parts = error.split(':');
      if (parts.length > 1) {
        final msg = parts.sublist(1).join(':').trim();
        if (msg.isNotEmpty) return '登录失败: $msg';
      }
    }
    if (error.contains('"') && error.split('"').length >= 2) {
      final parts = error.split('"');
      if (parts.length >= 2) {
        final msg = parts[1].trim();
        if (msg.isNotEmpty && msg != 'login') return '登录失败: $msg';
      }
    }
    return error.isEmpty ? '登录失败: 未知原因' : '登录失败: $error';
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final captcha = CaptchaService.instance;

    return Scaffold(
      body: SafeArea(
        child: Center(
          child: SingleChildScrollView(
            padding: const EdgeInsets.all(24),
            child: DesktopConstrained(
              maxContentWidth: 480,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Center(child: _buildLogo()),
                  const SizedBox(height: 32),
                  Center(
                    child: Text('公云存储', style: theme.textTheme.headlineMedium),
                  ),
                  const SizedBox(height: 32),
                  Card(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(16),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.all(24),
                      child: Form(
                        key: _formKey,
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [
                            // 邮箱
                            TextFormField(
                              controller: _emailController,
                              keyboardType: TextInputType.emailAddress,
                              textInputAction: TextInputAction.next,
                              validator: StringValidator.validateEmail,
                              decoration: const InputDecoration(
                                labelText: '邮箱',
                                hintText: '请输入邮箱地址',
                                prefixIcon: Icon(LucideIcons.mail),
                              ),
                              onFieldSubmitted: (_) =>
                                  _focusNode.requestFocus(),
                            ),

                            const SizedBox(height: 16),

                            // 密码
                            TextFormField(
                              controller: _passwordController,
                              focusNode: _focusNode,
                              obscureText: _obscurePassword,
                              validator: StringValidator.validatePassword,
                              decoration: InputDecoration(
                                labelText: '密码',
                                hintText: '请输入密码',
                                prefixIcon: const Icon(LucideIcons.lock),
                                suffixIcon: IconButton(
                                  icon: Icon(
                                    _obscurePassword
                                        ? LucideIcons.eye
                                        : LucideIcons.eyeOff,
                                    size: 20,
                                  ),
                                  onPressed: () {
                                    setState(
                                      () =>
                                          _obscurePassword = !_obscurePassword,
                                    );
                                  },
                                ),
                              ),
                              onFieldSubmitted: (_) => _login(),
                            ),

                            if (_loginConfig.loginCaptcha) ...[
                              const SizedBox(height: 16),
                              captcha.buildCaptchaInput(context),
                            ],

                            const SizedBox(height: 12),

                            // 记住我
                            InkWell(
                              onTap: () =>
                                  setState(() => _rememberMe = !_rememberMe),
                              borderRadius: BorderRadius.circular(8),
                              child: Row(
                                mainAxisSize: MainAxisSize.min,
                                children: [
                                  SizedBox(
                                    width: 24,
                                    height: 24,
                                    child: Checkbox(
                                      value: _rememberMe,
                                      onChanged: (v) => setState(
                                        () => _rememberMe = v ?? false,
                                      ),
                                    ),
                                  ),
                                  const SizedBox(width: 8),
                                  const Text('记住我'),
                                ],
                              ),
                            ),

                            const SizedBox(height: 20),

                            // 链接按钮
                            Row(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              children: [
                                TextButton(
                                  onPressed: () {
                                    Navigator.of(context).push(
                                      MaterialPageRoute(
                                        builder: (context) =>
                                            ForgotPasswordPage(
                                              loginConfig: _loginConfig,
                                            ),
                                      ),
                                    );
                                  },
                                  child: const Text('忘记密码？'),
                                ),
                                TextButton(
                                  onPressed: () {
                                    Navigator.of(context).push(
                                      MaterialPageRoute(
                                        builder: (context) => RegisterPage(
                                          loginConfig: _loginConfig,
                                        ),
                                      ),
                                    );
                                  },
                                  child: const Text('注册账号'),
                                ),
                              ],
                            ),

                            const SizedBox(height: 16),

                            // 登录按钮
                            FilledButton(
                              onPressed: _isLoading ? null : _login,
                              style: FilledButton.styleFrom(
                                minimumSize: const Size(double.infinity, 48),
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(12),
                                ),
                              ),
                              child: _isLoading
                                  ? const SizedBox(
                                      width: 24,
                                      height: 24,
                                      child: CircularProgressIndicator(
                                        strokeWidth: 2,
                                      ),
                                    )
                                  : const Text('登录'),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildLogo() {
    return ClipOval(
      child: Image.asset(
        'assets/images/app_logo.png',
        width: 96,
        height: 96,
        fit: BoxFit.cover,
      ),
    );
  }
}

/// 两步验证输入对话框
class _TwoFactorDialog extends StatefulWidget {
  final String sessionId;
  final String email;
  final String password;
  final bool rememberMe;

  const _TwoFactorDialog({
    required this.sessionId,
    required this.email,
    required this.password,
    required this.rememberMe,
  });

  @override
  State<_TwoFactorDialog> createState() => _TwoFactorDialogState();
}

class _TwoFactorDialogState extends State<_TwoFactorDialog>
    with SingleTickerProviderStateMixin {
  final _controller = TextEditingController();
  final _focusNode = FocusNode();
  bool _isSubmitting = false;
  late final AnimationController _shakeController;
  late final Animation<double> _shakeAnimation;

  @override
  void initState() {
    super.initState();
    _shakeController = AnimationController(
      duration: const Duration(milliseconds: 400),
      vsync: this,
    );
    _shakeAnimation =
        TweenSequence<double>([
          TweenSequenceItem(tween: Tween(begin: 0, end: 10), weight: 1),
          TweenSequenceItem(tween: Tween(begin: 10, end: -10), weight: 1),
          TweenSequenceItem(tween: Tween(begin: -10, end: 8), weight: 1),
          TweenSequenceItem(tween: Tween(begin: 8, end: -8), weight: 1),
          TweenSequenceItem(tween: Tween(begin: -8, end: 4), weight: 1),
          TweenSequenceItem(tween: Tween(begin: 4, end: 0), weight: 1),
        ]).animate(
          CurvedAnimation(parent: _shakeController, curve: Curves.easeInOut),
        );
    _controller.addListener(_onTextChanged);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _focusNode.requestFocus();
    });
  }

  @override
  void dispose() {
    _controller.removeListener(_onTextChanged);
    _controller.dispose();
    _focusNode.dispose();
    _shakeController.dispose();
    super.dispose();
  }

  void _onTextChanged() {
    if (_controller.text.length == 6 && !_isSubmitting) {
      _submit();
    }
  }

  Future<void> _submit() async {
    final code = _controller.text.trim();
    if (code.length != 6 || int.tryParse(code) == null) return;

    setState(() => _isSubmitting = true);

    final authProvider = Provider.of<AuthProvider>(context, listen: false);
    try {
      final success = await authProvider
          .twoFactorLogin(
            otp: code,
            sessionId: widget.sessionId,
            email: widget.email,
            password: widget.password,
            rememberMe: widget.rememberMe,
          )
          .timeout(
            const Duration(seconds: 5),
            onTimeout: () => throw Exception('请求超时'),
          );

      if (!mounted) return;

      if (success) {
        Navigator.of(context).pop(true);
      } else {
        _onVerifyFailed(authProvider.errorMessage ?? '验证码错误');
      }
    } catch (e) {
      if (mounted) _onVerifyFailed(_parse2FAError(e.toString()));
    }
  }

  void _onVerifyFailed(String message) {
    setState(() => _isSubmitting = false);
    _controller.clear();
    _focusNode.requestFocus();
    _shakeController.forward(from: 0);
    ToastHelper.failure(message);
  }

  String _parse2FAError(String error) {
    if (error.startsWith('Exception(') || error.startsWith('AppException(')) {
      final startIdx = error.indexOf('(');
      final endIdx = error.lastIndexOf(')');
      if (startIdx != -1 && endIdx != -1 && endIdx > startIdx) {
        return error.substring(startIdx + 1, endIdx).trim();
      }
    }
    return error.isEmpty ? '验证码错误' : error;
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return AlertDialog(
      title: Row(
        children: [
          Icon(LucideIcons.shieldCheck, color: theme.colorScheme.primary),
          const SizedBox(width: 8),
          const Text('两步验证'),
        ],
      ),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Text(
            '请输入身份验证器中的6位数字验证码',
            style: theme.textTheme.bodyMedium?.copyWith(
              color: theme.colorScheme.onSurfaceVariant,
            ),
          ),
          const SizedBox(height: 20),
          AnimatedBuilder(
            animation: _shakeAnimation,
            builder: (context, child) {
              return Transform.translate(
                offset: Offset(_shakeAnimation.value, 0),
                child: child,
              );
            },
            child: TextField(
              controller: _controller,
              focusNode: _focusNode,
              keyboardType: TextInputType.number,
              maxLength: 6,
              textAlign: TextAlign.center,
              enabled: !_isSubmitting,
              style: const TextStyle(
                fontSize: 24,
                fontWeight: FontWeight.bold,
                letterSpacing: 8,
              ),
              decoration: InputDecoration(
                counterText: '',
                hintText: '------',
                hintStyle: TextStyle(
                  fontSize: 24,
                  fontWeight: FontWeight.bold,
                  letterSpacing: 8,
                  color: theme.colorScheme.outline.withValues(alpha: 0.4),
                ),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(12),
                ),
              ),
              inputFormatters: [FilteringTextInputFormatter.digitsOnly],
              onSubmitted: (_) => _submit(),
            ),
          ),
        ],
      ),
      actions: [
        TextButton(
          onPressed: _isSubmitting
              ? null
              : () => Navigator.of(context).pop(false),
          child: const Text('取消'),
        ),
        FilledButton(
          onPressed: _isSubmitting ? null : _submit,
          child: _isSubmitting
              ? const SizedBox(
                  width: 20,
                  height: 20,
                  child: CircularProgressIndicator(strokeWidth: 2),
                )
              : const Text('验证'),
        ),
      ],
    );
  }
}
