import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';

import '../../../core/l10n/app_localizations.dart';
import '../../../core/theme/app_colors.dart';
import '../../../core/utils/top_toast.dart';
import '../../../providers/auth_provider.dart';

/// 验证码场景
enum VerifyCodeMode { login, register }

/// 验证码输入页面参数
class VerifyCodeArgs {
  final String email;
  final String password;
  final String maskedEmail;
  final VerifyCodeMode mode;
  final bool showAuthenticator;
  final bool codeSent;

  const VerifyCodeArgs({
    required this.email,
    required this.password,
    required this.maskedEmail,
    this.mode = VerifyCodeMode.login,
    this.showAuthenticator = true,
    this.codeSent = false,
  });
}

class VerifyCodeScreen extends ConsumerStatefulWidget {
  const VerifyCodeScreen({super.key, required this.args});

  final VerifyCodeArgs args;

  @override
  ConsumerState<VerifyCodeScreen> createState() => _VerifyCodeScreenState();
}

class _VerifyCodeScreenState extends ConsumerState<VerifyCodeScreen> {
  /// 0 = 邮箱验证码, 1 = 身份验证器
  int _tabIndex = 0;

  final List<TextEditingController> _otpControllers =
      List.generate(6, (_) => TextEditingController());
  final List<FocusNode> _otpFocusNodes = List.generate(6, (_) => FocusNode());

  @override
  void initState() {
    super.initState();
    for (int i = 1; i < 6; i++) {
      final index = i;
      _otpFocusNodes[i].onKeyEvent = (node, event) {
        if (event is KeyDownEvent &&
            event.logicalKey == LogicalKeyboardKey.backspace &&
            _otpControllers[index].text.isEmpty) {
          _otpControllers[index - 1].clear();
          _otpFocusNodes[index - 1].requestFocus();
          setState(() {});
          return KeyEventResult.handled;
        }
        return KeyEventResult.ignored;
      };
    }
    Future.microtask(() {
      if (widget.args.codeSent) {
        ref.read(authProvider.notifier).startCountdown();
      } else {
        _sendCode();
      }
      _otpFocusNodes[0].requestFocus();
    });
  }

  @override
  void dispose() {
    for (final c in _otpControllers) {
      c.dispose();
    }
    for (final f in _otpFocusNodes) {
      f.dispose();
    }
    super.dispose();
  }

  String get _otpCode => _otpControllers.map((c) => c.text).join();
  bool get _otpFilled => _otpCode.length == 6;

  void _onDigitChanged(int index, String value) {
    // Handle paste: value contains multiple characters
    if (value.length > 1) {
      final digits = value.replaceAll(RegExp(r'[^0-9]'), '');
      for (int i = 0; i < 6 && i < digits.length; i++) {
        _otpControllers[i].text = digits[i];
      }
      for (int i = digits.length; i < 6; i++) {
        _otpControllers[i].clear();
      }
      final focusIdx = digits.length < 6 ? digits.length : 5;
      _otpFocusNodes[focusIdx].requestFocus();
      setState(() {});
      return;
    }

    // Advance focus when digit entered
    if (value.isNotEmpty && index < 5) {
      _otpFocusNodes[index + 1].requestFocus();
    }

    // iOS soft keyboard: when a non-empty field is cleared by backspace,
    // onChanged fires with "". Move focus to previous field so the next
    // backspace press lands on a non-empty field and triggers onChanged again.
    // (On iOS, backspace on an already-empty field fires no event at all.)
    if (value.isEmpty && index > 0) {
      _otpFocusNodes[index - 1].requestFocus();
    }

    setState(() {});
  }

  void _clearOtp() {
    for (final c in _otpControllers) {
      c.clear();
    }
  }

  void _switchTab(int index) {
    if (index == _tabIndex) return;
    _clearOtp();
    setState(() => _tabIndex = index);
    Future.microtask(() => _otpFocusNodes[0].requestFocus());
  }

  Future<void> _handlePaste() async {
    final data = await Clipboard.getData(Clipboard.kTextPlain);
    final text = data?.text ?? '';
    final digits = text.replaceAll(RegExp(r'[^0-9]'), '');
    if (digits.isEmpty) return;
    for (int i = 0; i < 6 && i < digits.length; i++) {
      _otpControllers[i].text = digits[i];
    }
    final focusIdx = digits.length < 6 ? digits.length : 5;
    _otpFocusNodes[focusIdx].requestFocus();
    if (!mounted) return;
    setState(() {});
  }

  void _sendCode() {
    final notifier = ref.read(authProvider.notifier);
    if (widget.args.mode == VerifyCodeMode.register) {
      notifier.sendRegisterCode(email: widget.args.email);
    } else {
      notifier.sendLoginCode(
        email: widget.args.email,
        password: widget.args.password,
      );
    }
  }

  Future<void> _handleSubmit() async {
    final l10n = AppLocalizations.of(context)!;
    final notifier = ref.read(authProvider.notifier);
    if (widget.args.mode == VerifyCodeMode.register) {
      final success = await notifier.register(code: _otpCode);
      if (success && mounted) {
        showTopToast(context, message: l10n.registerSuccess, backgroundColor: AppColors.rise);
        context.go('/login');
      }
    } else {
      final success = await notifier.login(
        email: widget.args.email,
        password: widget.args.password,
        code: _otpCode,
        vtype: _tabIndex == 0 ? '2' : '3',
      );
      if (success && mounted) {
        context.go('/');
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context)!;
    final cs = Theme.of(context).colorScheme;
    final state = ref.watch(authProvider);

    ref.listen<AuthState>(authProvider, (prev, next) {
      if (next.errorMessage != null && next.errorMessage != prev?.errorMessage) {
        final code = next.errorMessage!;
        WidgetsBinding.instance.addPostFrameCallback((_) {
          if (!context.mounted) return;
          final loc = AppLocalizations.of(context)!;
          showTopToast(
            context,
            message: resolveProviderError(code, loc) ?? code,
          );
          ref.read(authProvider.notifier).clearError();
        });
      }
    });

    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.chevron_left, size: 28),
          onPressed: () => context.pop(),
        ),
        title: Text(
          l10n.enterVerifyCode,
          style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
        ),
        centerTitle: true,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.fromLTRB(24, 16, 24, 24),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // ── Tab 切换
            if (widget.args.showAuthenticator) ...[
              _SegmentedTab(
                selectedIndex: _tabIndex,
                onChanged: _switchTab,
                emailLabel: l10n.emailCodeTab,
                authenticatorLabel: l10n.authenticatorTab,
              ),
              const SizedBox(height: 28),
            ] else
              const SizedBox(height: 8),

            // ── 图标
            Container(
              width: 48,
              height: 48,
              decoration: BoxDecoration(
                color: _tabIndex == 0
                    ? const Color(0xFFE8F5E9)
                    : const Color(0xFFFFF8E1),
                borderRadius: BorderRadius.circular(14),
              ),
              child: Icon(
                _tabIndex == 0 ? Icons.email_outlined : Icons.smartphone,
                color: _tabIndex == 0
                    ? const Color(0xFF4CAF50)
                    : AppColors.brand,
                size: 24,
              ),
            ),
            const SizedBox(height: 20),

            // ── 标题
            Text(
              l10n.enterVerifyCode,
              style: TextStyle(
                color: cs.onSurface,
                fontSize: 22,
                fontWeight: FontWeight.w700,
              ),
            ),
            const SizedBox(height: 16),

            // ── 提示文字
            if (_tabIndex == 0)
              Text.rich(
                TextSpan(
                  text: '${l10n.email}: ',
                  children: [
                    TextSpan(
                      text: widget.args.maskedEmail,
                      style: TextStyle(
                        fontWeight: FontWeight.w600,
                        color: cs.onSurface,
                      ),
                    ),
                    TextSpan(text: '  ${l10n.emailCodeHint}'),
                  ],
                ),
                style: TextStyle(
                  color: cs.onSurface.withAlpha(153),
                  fontSize: 14,
                  height: 1.5,
                ),
              )
            else
              Text(
                l10n.authenticatorHint,
                style: TextStyle(
                  color: cs.onSurface.withAlpha(153),
                  fontSize: 14,
                  height: 1.5,
                ),
              ),
            const SizedBox(height: 28),

            // ── 6 位验证码输入
            AutofillGroup(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: List.generate(6, (i) {
                  return SizedBox(
                    width: 48,
                    height: 52,
                    child: Semantics(
                      label: 'verify_input_code_$i',
                      textField: true,
                      child: TextField(
                        controller: _otpControllers[i],
                        focusNode: _otpFocusNodes[i],
                        textAlign: TextAlign.center,
                        keyboardType: TextInputType.number,
                        maxLength: 1,
                        autofillHints: const [AutofillHints.oneTimeCode],
                        inputFormatters: [
                          FilteringTextInputFormatter.digitsOnly,
                        ],
                        onChanged: (v) => _onDigitChanged(i, v),
                        style: TextStyle(
                          color: cs.onSurface,
                          fontSize: 20,
                          fontWeight: FontWeight.w600,
                        ),
                        decoration: InputDecoration(
                          counterText: '',
                          contentPadding: const EdgeInsets.symmetric(vertical: 14),
                          isDense: true,
                          filled: true,
                          fillColor: cs.surface,
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(10),
                            borderSide: BorderSide(color: cs.outline.withAlpha(60)),
                          ),
                          enabledBorder: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(10),
                            borderSide: BorderSide(color: cs.outline.withAlpha(60)),
                          ),
                          focusedBorder: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(10),
                            borderSide: const BorderSide(
                                color: AppColors.brand, width: 1.5),
                          ),
                        ),
                      ),
                    ),
                  );
                }),
              ),
            ),
            const SizedBox(height: 16),

            // ── 倒计时 / 粘贴
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                if (_tabIndex == 0)
                  Semantics(
                    label: 'verify_link_resend',
                    onTap: state.codeCooldown > 0 ? null : _sendCode,
                    child: GestureDetector(
                      onTap: state.codeCooldown > 0 ? null : _sendCode,
                      child: Text(
                        state.codeCooldown > 0
                            ? l10n.resendCountdown(state.codeCooldown)
                            : l10n.resendCode,
                        style: TextStyle(
                          color: state.codeCooldown > 0
                              ? cs.onSurface.withAlpha(153)
                              : AppColors.brand,
                          fontSize: 13,
                        ),
                      ),
                    ),
                  )
                else
                  const SizedBox.shrink(),
                GestureDetector(
                  onTap: _handlePaste,
                  child: Text(
                    l10n.paste,
                    style: TextStyle(
                      color: cs.onSurface,
                      fontSize: 13,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 32),

            // ── 提交按钮
            Semantics(
              label: 'verify_btn_confirm',
              button: true,
              enabled: _otpFilled && !state.isLoading,
              onTap: (_otpFilled && !state.isLoading) ? _handleSubmit : null,
              child: SizedBox(
                width: double.infinity,
                height: 50,
                child: ElevatedButton(
                  onPressed:
                      (_otpFilled && !state.isLoading) ? _handleSubmit : null,
                  style: ElevatedButton.styleFrom(
                    backgroundColor: AppColors.brand,
                    disabledBackgroundColor: AppColors.brand.withAlpha(80),
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10),
                    ),
                  ),
                  child: state.isLoading
                      ? SizedBox(
                          width: 20,
                          height: 20,
                          child: CircularProgressIndicator(
                              strokeWidth: 2, color: Colors.black),
                        )
                      : Text(
                          l10n.submit,
                          style: TextStyle(
                            color: _otpFilled
                                ? Colors.black
                                : Colors.black.withAlpha(153),
                            fontSize: 16,
                            fontWeight: FontWeight.w600,
                          ),
                        ),
                ),
              ),
            ),

            // ── 切换链接（仅身份验证器 Tab 显示）
            if (_tabIndex == 1) ...[
              const SizedBox(height: 20),
              Center(
                child: Semantics(
                  label: 'verify_link_switch',
                  onTap: () => _switchTab(0),
                  child: GestureDetector(
                    onTap: () => _switchTab(0),
                    child: Text(
                      l10n.switchEmailVerify,
                      style: const TextStyle(
                        color: AppColors.brand,
                        fontSize: 14,
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }
}

// ── 分段选择器 ───────────────────────────────────────────────

class _SegmentedTab extends StatelessWidget {
  const _SegmentedTab({
    required this.selectedIndex,
    required this.onChanged,
    required this.emailLabel,
    required this.authenticatorLabel,
  });

  final int selectedIndex;
  final ValueChanged<int> onChanged;
  final String emailLabel;
  final String authenticatorLabel;

  @override
  Widget build(BuildContext context) {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    return Container(
      height: 40,
      decoration: BoxDecoration(
        color: isDark ? AppColors.darkBgTertiary : AppColors.lightBgTertiary,
        borderRadius: BorderRadius.circular(20),
      ),
      child: Row(
        children: [
          _buildTab(context, 0, emailLabel),
          _buildTab(context, 1, authenticatorLabel),
        ],
      ),
    );
  }

  Widget _buildTab(BuildContext context, int index, String label) {
    final cs = Theme.of(context).colorScheme;
    final selected = index == selectedIndex;
    return Expanded(
      child: GestureDetector(
        onTap: () => onChanged(index),
        child: Container(
          margin: const EdgeInsets.all(3),
          decoration: BoxDecoration(
            color: selected ? AppColors.brand : Colors.transparent,
            borderRadius: BorderRadius.circular(18),
          ),
          child: Center(
            child: Text(
              label,
              style: TextStyle(
                color: selected ? Colors.black : cs.onSurface.withAlpha(153),
                fontSize: 13,
                fontWeight: selected ? FontWeight.w600 : FontWeight.w400,
              ),
            ),
          ),
        ),
      ),
    );
  }
}
