import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:miaoji_zhang/shared/services/session_store.dart'; import 'package:miaoji_zhang/shared/services/sync_service.dart'; import 'package:miaoji_zhang/shared/theme/app_theme.dart'; import 'package:miaoji_zhang/shared/widgets/app_controls.dart'; import 'package:miaoji_zhang/shared/widgets/app_icons.dart'; enum AiAccessState { guest, reauthenticate, aiDisabled, cloudDisabled } AiAccessState? currentAiAccessState() { final session = SessionStore.instance; if (session.isGuest) return AiAccessState.guest; if (session.needsReauth) return AiAccessState.reauthenticate; if (!session.aiEnabled) return AiAccessState.aiDisabled; if (!session.cloudSyncEnabled) return AiAccessState.cloudDisabled; return null; } class AiAccessGate extends StatefulWidget { final AiAccessState state; final Future Function()? onAction; const AiAccessGate({super.key, required this.state, this.onAction}); @override State createState() => _AiAccessGateState(); } class _AiAccessGateState extends State { bool _busy = false; String get _title => switch (widget.state) { AiAccessState.guest => '登录后使用 AI 助手', AiAccessState.reauthenticate => '登录状态已过期', AiAccessState.aiDisabled => 'AI 功能已关闭', AiAccessState.cloudDisabled => 'AI 功能需要云连接', }; String get _message => switch (widget.state) { AiAccessState.guest => '游客账单会继续安全保存在本机。登录后即可使用 AI 聊天、语音解析和图片识别。', AiAccessState.reauthenticate => '本地记账不受影响。重新登录后可以继续使用 AI 和云同步。', AiAccessState.aiDisabled => '当前账号暂未开通 AI,手动记账和统计不受影响。', AiAccessState.cloudDisabled => '当前账号仅使用本地数据。开启云同步后才能发送 AI 消息。', }; String? get _actionLabel => switch (widget.state) { AiAccessState.guest => '登录后使用', AiAccessState.reauthenticate => '重新登录', AiAccessState.aiDisabled => null, AiAccessState.cloudDisabled => '开启云同步', }; Future _act() async { if (_busy) return; if (widget.state == AiAccessState.aiDisabled) return; if (widget.onAction != null) { await widget.onAction!(); return; } if (widget.state != AiAccessState.cloudDisabled) { if (mounted) { context.go( Uri(path: '/login', queryParameters: {'notice': _title}).toString(), ); } return; } setState(() => _busy = true); try { await SessionStore.instance.setCloudSyncEnabled(true); await SyncService.instance.run(); } finally { if (mounted) setState(() => _busy = false); } } @override Widget build(BuildContext context) { return Center( child: SingleChildScrollView( padding: const EdgeInsets.all(28), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 420), child: Card( child: Padding( padding: const EdgeInsets.fromLTRB(24, 28, 24, 24), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( width: 62, height: 62, decoration: BoxDecoration( color: context.jz.aiBackground, borderRadius: BorderRadius.circular(20), ), child: Center( child: AppIcons.icon( AppIcons.sparkle, size: 29, color: AppTheme.ai, ), ), ), SizedBox(height: 18), Text( _title, textAlign: TextAlign.center, style: TextStyle(fontSize: 18, fontWeight: FontWeight.w800), ), SizedBox(height: 9), Text( _message, textAlign: TextAlign.center, style: TextStyle( color: context.jz.text2, fontSize: 12.5, height: 1.6, ), ), if (_actionLabel case final label?) ...[ SizedBox(height: 22), SizedBox( width: double.infinity, child: JzActionButton( label: label, loading: _busy, onPressed: _busy ? null : _act, ), ), ], if (widget.state == AiAccessState.guest) ...[ SizedBox(height: 12), Text( '无需登录也可以继续手动记账、管理预算和查看统计', textAlign: TextAlign.center, style: TextStyle(fontSize: 10.5, color: context.jz.text3), ), ], ], ), ), ), ), ), ); } }