// auth_screen.dart — 登录 / 注册页(居中卡片 + 暖光晕重设计)
//
// 视觉:暖色径向光晕背景 + 居中卡片;hero 用 clay 渐变 app-icon + 品牌;胶囊分段
// tab;输入框聚焦态(accent 边 + 光环);主按钮微光;进入错落淡入。全部走 token。
// 逻辑零回归:登录/注册两段式、发码、邮箱预填、密码显隐、错误提示均保留。
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../l10n/app_text.dart';
import '../pangolin_theme.dart';
import '../services/api_config.dart';
import '../services/auth_api.dart';
import '../state/auth_provider.dart';
import 'pangolin_button.dart';
import 'pangolin_icons.dart';
import 'pangolin_logo.dart';

// API base URL 统一用 api_config.dart 的 kApiBaseUrl(单一来源,勿再重复声明)。

const _easeOut = Cubic(0.22, 1, 0.36, 1);

enum _AuthMode { login, register }

class AuthScreen extends ConsumerStatefulWidget {
  const AuthScreen({super.key, required this.onDone, required this.t});
  final VoidCallback onDone;
  final AppText t;

  @override
  ConsumerState<AuthScreen> createState() => _AuthScreenState();
}

class _AuthScreenState extends ConsumerState<AuthScreen>
    with SingleTickerProviderStateMixin {
  _AuthMode _mode = _AuthMode.login;
  int _step = 0;
  bool _sent = false;
  bool _loading = false;
  bool _pwVisible = false;
  String? _errorZh;

  final _email = TextEditingController();
  final _code = TextEditingController();
  final _pw = TextEditingController();

  final _emailFocus = FocusNode();
  final _pwFocus = FocusNode();
  final _codeFocus = FocusNode();

  late final AnimationController _intro = AnimationController(
    vsync: this,
    duration: const Duration(milliseconds: 620),
  );

  late final AuthApi _api = AuthApi(baseUrl: kApiBaseUrl);

  bool get _emailValid => RegExp(r'\S+@\S+\.\S+').hasMatch(_email.text);

  @override
  void initState() {
    super.initState();
    // 聚焦态驱动输入框边框变化。
    for (final f in [_emailFocus, _pwFocus, _codeFocus]) {
      f.addListener(() => setState(() {}));
    }
    // 预填上次登录邮箱。
    ref.read(tokenStoreProvider).loadLastEmail().then((email) {
      if (email != null && email.isNotEmpty && mounted) {
        setState(() => _email.text = email);
      }
    });
    _intro.forward();
  }

  @override
  void dispose() {
    _email.dispose();
    _code.dispose();
    _pw.dispose();
    _emailFocus.dispose();
    _pwFocus.dispose();
    _codeFocus.dispose();
    _intro.dispose();
    _api.dispose();
    super.dispose();
  }

  // ── 认证操作（逻辑不变）──────────────────────────────────────────

  Future<void> _sendCode() async {
    setState(() { _loading = true; _errorZh = null; });
    try {
      await _api.sendCode(_email.text.trim());
      if (mounted) setState(() { _sent = true; _loading = false; });
    } on AuthApiException catch (e) {
      if (mounted) setState(() { _errorZh = e.messageZh; _loading = false; });
    }
  }

  Future<void> _doRegister() async {
    setState(() { _loading = true; _errorZh = null; });
    try {
      final tokens = await _api.register(
        email: _email.text.trim(),
        code: _code.text.trim(),
        password: _pw.text,
      );
      await ref.read(tokenStoreProvider).saveLastEmail(_email.text.trim());
      await ref.read(authProvider.notifier).saveTokens(tokens);
      if (mounted) widget.onDone();
    } on AuthApiException catch (e) {
      if (mounted) setState(() { _errorZh = e.messageZh; _loading = false; });
    }
  }

  Future<void> _doLogin() async {
    setState(() { _loading = true; _errorZh = null; });
    try {
      final tokens = await _api.login(
        email: _email.text.trim(),
        password: _pw.text,
      );
      await ref.read(tokenStoreProvider).saveLastEmail(_email.text.trim());
      await ref.read(authProvider.notifier).saveTokens(tokens);
      if (mounted) widget.onDone();
    } on AuthApiException catch (e) {
      if (mounted) setState(() { _errorZh = e.messageZh; _loading = false; });
    }
  }

  void _setMode(_AuthMode m) => setState(() {
        _mode = m;
        _step = 0;
        _sent = false;
        _errorZh = null;
      });

  // ── UI ──────────────────────────────────────────────────────

  @override
  Widget build(BuildContext context) {
    final c = context.pangolin;
    final t = widget.t;
    final dark = Theme.of(context).brightness == Brightness.dark;
    final glow = c.accent.withValues(alpha: dark ? 0.16 : 0.13);

    return Scaffold(
      backgroundColor: c.bg,
      body: Stack(children: [
        _atmosphere(glow),
        SafeArea(
          child: Center(
            child: SingleChildScrollView(
              // 无弹性回弹:内容放得下就不滚(大窗口不出现上下拖动/滚动条),
              // 仅窗口太矮放不下时才滚动。
              physics: const ClampingScrollPhysics(),
              padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32),
              child: ConstrainedBox(
                constraints: const BoxConstraints(maxWidth: 420),
                child: Column(mainAxisSize: MainAxisSize.min, children: [
                  _reveal(0.0, 0.55, _hero(c, t)),
                  const SizedBox(height: 26),
                  _reveal(0.22, 1.0, _card(c, t)),
                  const SizedBox(height: 18),
                  _reveal(0.42, 1.0, Text(t.tos,
                      textAlign: TextAlign.center,
                      style: PangolinText.caption.copyWith(color: c.fg3, fontWeight: FontWeight.w400))),
                ]),
              ),
            ),
          ),
        ),
      ]),
    );
  }

  // 暖色径向光晕(顶部 + 右下两团)。
  Widget _atmosphere(Color glow) => Positioned.fill(
        child: IgnorePointer(
          child: Stack(children: [
            DecoratedBox(
              decoration: BoxDecoration(
                gradient: RadialGradient(
                  center: const Alignment(0, -1.15),
                  radius: 1.0,
                  colors: [glow, Colors.transparent],
                  stops: const [0, 0.72],
                ),
              ),
            ),
            DecoratedBox(
              decoration: BoxDecoration(
                gradient: RadialGradient(
                  center: const Alignment(0.85, 1.05),
                  radius: 0.7,
                  colors: [glow, Colors.transparent],
                  stops: const [0, 0.72],
                ),
              ),
            ),
          ]),
        ),
      );

  // 进入错落淡入 + 上移。
  Widget _reveal(double start, double end, Widget child) {
    final anim = CurvedAnimation(parent: _intro, curve: Interval(start, end, curve: _easeOut));
    return AnimatedBuilder(
      animation: anim,
      builder: (_, c) => Opacity(
        opacity: anim.value.clamp(0.0, 1.0),
        child: Transform.translate(offset: Offset(0, 14 * (1 - anim.value)), child: c),
      ),
      child: child,
    );
  }

  Widget _hero(PangolinScheme c, AppText t) => Column(children: [
        Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(PangolinRadius.xl),
            boxShadow: [
              BoxShadow(color: c.accent.withValues(alpha: 0.30), blurRadius: 44, spreadRadius: 2),
              ...PangolinShadow.lg,
            ],
          ),
          child: const PangolinAppIcon(size: 64),
        ),
        const SizedBox(height: 16),
        Text(t.brand, style: PangolinText.h1.copyWith(color: c.fg1)),
        const SizedBox(height: 6),
        Text(t.authTagline, style: PangolinText.sm.copyWith(color: c.accent, fontWeight: FontWeight.w600)),
      ]);

  Widget _card(PangolinScheme c, AppText t) => Container(
        padding: const EdgeInsets.fromLTRB(24, 26, 24, 24),
        decoration: BoxDecoration(
          color: c.surface,
          borderRadius: BorderRadius.circular(PangolinRadius.xxl),
          border: Border.all(color: c.border),
          boxShadow: [...PangolinShadow.md, ...PangolinShadow.lg],
        ),
        child: Column(children: [
          _segTabs(c, t),
          const SizedBox(height: 22),
          if (_errorZh != null) ...[
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
              decoration: BoxDecoration(
                color: c.dangerSubtle,
                borderRadius: BorderRadius.circular(PangolinRadius.md),
                border: Border.all(color: c.danger),
              ),
              child: Row(children: [
                Icon(PangolinIcons.x, size: 16, color: c.danger),
                const SizedBox(width: 8),
                Expanded(child: Text(_errorZh!, style: PangolinText.sm.copyWith(color: c.danger))),
              ]),
            ),
            const SizedBox(height: 14),
          ],
          _mode == _AuthMode.login ? _login(c, t) : _register(c, t),
        ]),
      );

  // 胶囊分段 tab(滑块滑动)。
  Widget _segTabs(PangolinScheme c, AppText t) {
    final reg = _mode == _AuthMode.register;
    return Container(
      padding: const EdgeInsets.all(4),
      decoration: BoxDecoration(color: c.bgSubtle, borderRadius: BorderRadius.circular(PangolinRadius.full)),
      child: Stack(children: [
        Positioned.fill(
          child: AnimatedAlign(
            duration: const Duration(milliseconds: 260),
            curve: _easeOut,
            alignment: reg ? Alignment.centerRight : Alignment.centerLeft,
            child: FractionallySizedBox(
              widthFactor: 0.5,
              heightFactor: 1.0,
              child: DecoratedBox(
                decoration: BoxDecoration(
                  color: c.accent,
                  borderRadius: BorderRadius.circular(PangolinRadius.full),
                  boxShadow: PangolinShadow.md,
                ),
              ),
            ),
          ),
        ),
        Row(children: [
          _seg(c, t.tabLogin, !reg, () => _setMode(_AuthMode.login)),
          _seg(c, t.tabRegister, reg, () => _setMode(_AuthMode.register)),
        ]),
      ]),
    );
  }

  Widget _seg(PangolinScheme c, String label, bool active, VoidCallback onTap) => Expanded(
        child: GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTap: onTap,
          child: Container(
            padding: const EdgeInsets.symmetric(vertical: 9),
            alignment: Alignment.center,
            child: Text(label,
                style: PangolinText.body.copyWith(
                    color: active ? c.fgOnAccent : c.fg3, fontWeight: FontWeight.w600, fontSize: 15)),
          ),
        ),
      );

  // 输入字段:标签 + 图标 + 聚焦态(accent 边 + 光环)。
  Widget _field(PangolinScheme c, {required IconData icon, required String label, required bool focused, required Widget child}) {
    return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
      Text(label, style: PangolinText.caption.copyWith(color: c.fg2, fontWeight: FontWeight.w600)),
      const SizedBox(height: 7),
      AnimatedContainer(
        duration: const Duration(milliseconds: 160),
        padding: const EdgeInsets.symmetric(horizontal: 14),
        decoration: BoxDecoration(
          color: c.surface,
          borderRadius: BorderRadius.circular(PangolinRadius.md),
          border: Border.all(color: focused ? c.accent : c.borderStrong, width: 1.5),
          boxShadow: focused ? [BoxShadow(color: c.ring, spreadRadius: 3)] : null,
        ),
        child: Row(children: [Icon(icon, size: 18, color: c.fg3), const SizedBox(width: 10), Expanded(child: child)]),
      ),
    ]);
  }

  InputDecoration get _bare =>
      const InputDecoration(border: InputBorder.none, isCollapsed: true, contentPadding: EdgeInsets.symmetric(vertical: 13));

  // 密码输入 + 显示/隐藏切换(眼睛按钮)。
  Widget _pwInput(PangolinScheme c, String hint) => Row(children: [
        Expanded(
          child: TextField(
            controller: _pw,
            focusNode: _pwFocus,
            obscureText: !_pwVisible,
            decoration: _bare.copyWith(hintText: hint),
            onChanged: (_) => setState(() {}),
          ),
        ),
        GestureDetector(
          onTap: () => setState(() => _pwVisible = !_pwVisible),
          child: Padding(
            padding: const EdgeInsets.only(left: 6),
            child: Icon(_pwVisible ? PangolinIcons.eyeOff : PangolinIcons.eye, size: 18, color: c.fg3),
          ),
        ),
      ]);

  Widget _primaryBtn(PangolinScheme c, {required String label, required VoidCallback? onPressed}) {
    final enabled = onPressed != null;
    return Container(
      decoration: enabled
          ? BoxDecoration(
              borderRadius: BorderRadius.circular(PangolinRadius.full),
              boxShadow: [BoxShadow(color: c.accent.withValues(alpha: 0.30), blurRadius: 20, offset: const Offset(0, 6))],
            )
          : null,
      child: PangolinButton(label: label, expand: true, onPressed: onPressed),
    );
  }

  Widget _login(PangolinScheme c, AppText t) {
    return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
      _field(c, icon: PangolinIcons.mail, label: t.emailLabel, focused: _emailFocus.hasFocus,
          child: TextField(controller: _email, focusNode: _emailFocus, decoration: _bare.copyWith(hintText: t.emailPh), onChanged: (_) => setState(() {}))),
      const SizedBox(height: 16),
      _field(c, icon: PangolinIcons.lock, label: t.pwLabel, focused: _pwFocus.hasFocus, child: _pwInput(c, t.pwPh)),
      Align(
        alignment: Alignment.centerRight,
        child: Padding(
          padding: const EdgeInsets.only(top: 10),
          child: Text(t.forgotPw, style: PangolinText.sm.copyWith(color: c.accent, fontWeight: FontWeight.w600)),
        ),
      ),
      const SizedBox(height: 18),
      _primaryBtn(c, label: _loading ? '...' : t.doLogin,
          onPressed: (!_loading && _emailValid && _pw.text.isNotEmpty) ? _doLogin : null),
    ]);
  }

  Widget _register(PangolinScheme c, AppText t) {
    if (_step == 0) {
      return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
        _field(c, icon: PangolinIcons.mail, label: t.emailLabel, focused: _emailFocus.hasFocus,
            child: Row(children: [
              Expanded(child: TextField(controller: _email, focusNode: _emailFocus, decoration: _bare.copyWith(hintText: t.emailPh), onChanged: (_) => setState(() {}))),
              GestureDetector(
                onTap: (!_loading && _emailValid) ? _sendCode : null,
                child: Text(_sent ? t.resend : t.sendCode,
                    style: PangolinText.caption.copyWith(color: (!_loading && _emailValid) ? c.accent : c.fg3, fontWeight: FontWeight.w700)),
              ),
            ])),
        if (_sent)
          Padding(
            padding: const EdgeInsets.only(top: 8),
            child: Row(children: [
              Icon(PangolinIcons.checkCircle, size: 14, color: c.success),
              const SizedBox(width: 6),
              Expanded(child: Text(t.codeSentTo(_email.text), style: PangolinText.caption.copyWith(color: c.success, fontWeight: FontWeight.w400))),
            ]),
          ),
        const SizedBox(height: 16),
        _field(c, icon: PangolinIcons.shieldCheck, label: t.codeLabel, focused: _codeFocus.hasFocus,
            child: TextField(controller: _code, focusNode: _codeFocus, keyboardType: TextInputType.number, maxLength: 6,
                style: PangolinText.mono.copyWith(letterSpacing: 6, color: c.fg1),
                decoration: _bare.copyWith(counterText: '', hintText: ''), onChanged: (_) => setState(() {}))),
        const SizedBox(height: 16),
        _primaryBtn(c, label: t.doNext, onPressed: (_sent && _code.text.length == 6) ? () => setState(() => _step = 1) : null),
      ]);
    }
    // Step 1: 已验证邮箱(可返回改邮箱)+ 设密码
    return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
      Container(
        padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 11),
        decoration: BoxDecoration(color: c.bgSubtle, borderRadius: BorderRadius.circular(PangolinRadius.md)),
        child: Row(children: [
          Icon(PangolinIcons.shieldCheck, size: 16, color: c.success),
          const SizedBox(width: 8),
          Expanded(child: Text(_email.text, overflow: TextOverflow.ellipsis,
              style: PangolinText.sm.copyWith(color: c.fg1, fontWeight: FontWeight.w600))),
          GestureDetector(
            onTap: () => setState(() => _step = 0),
            child: Text(t.lang == AppLang.zh ? '改邮箱' : 'Change',
                style: PangolinText.caption.copyWith(color: c.accent, fontWeight: FontWeight.w600, fontSize: 13)),
          ),
        ]),
      ),
      const SizedBox(height: 16),
      _field(c, icon: PangolinIcons.lock, label: t.pwLabel, focused: _pwFocus.hasFocus, child: _pwInput(c, t.setPwPh)),
      const SizedBox(height: 18),
      _primaryBtn(c, label: _loading ? '...' : t.doCreate,
          onPressed: (!_loading && _pw.text.length >= 6) ? _doRegister : null),
    ]);
  }
}
