import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:airhub_app/theme/design_tokens.dart'; import 'package:airhub_app/widgets/animated_gradient_background.dart'; import 'package:airhub_app/widgets/glass_dialog.dart'; import 'package:airhub_app/features/device/domain/entities/role_memory.dart'; import 'package:airhub_app/features/device/presentation/controllers/device_controller.dart'; class AgentManagePage extends ConsumerStatefulWidget { const AgentManagePage({super.key}); @override ConsumerState createState() => _AgentManagePageState(); } class _AgentManagePageState extends ConsumerState { @override Widget build(BuildContext context) { final memoriesAsync = ref.watch(roleMemoryControllerProvider); return Scaffold( backgroundColor: Colors.transparent, body: Stack( children: [ const AnimatedGradientBackground(), Column( children: [ _buildHeader(context), Expanded( child: memoriesAsync.when( loading: () => const Center( child: CircularProgressIndicator(color: Colors.white), ), error: (error, _) => Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( '加载失败', style: TextStyle( color: Colors.white.withOpacity(0.8), fontSize: 16, ), ), const SizedBox(height: 12), GestureDetector( onTap: () => ref.read(roleMemoryControllerProvider.notifier).refresh(), child: Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(20), ), child: const Text( '重试', style: TextStyle(color: Colors.white), ), ), ), ], ), ), data: (memories) { if (memories.isEmpty) { return Center( child: Text( '暂无角色记忆', style: TextStyle( color: Colors.white.withOpacity(0.6), fontSize: 16, ), ), ); } return ListView.builder( padding: EdgeInsets.only( top: 20, left: 20, right: 20, bottom: 40 + MediaQuery.of(context).padding.bottom, ), itemCount: memories.length, itemBuilder: (context, index) { return _buildMemoryCard(memories[index]); }, ); }, ), ), ], ), ], ), ); } Widget _buildHeader(BuildContext context) { return Container( padding: EdgeInsets.only( top: MediaQuery.of(context).padding.top + 20, left: AppSpacing.lg, right: AppSpacing.lg, bottom: AppSpacing.md, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () => Navigator.pop(context), child: Container( width: 40, height: 40, decoration: BoxDecoration( color: AppColors.iconBtnBg, borderRadius: BorderRadius.circular(AppRadius.button), ), child: const Icon( Icons.arrow_back_ios_new, color: AppColors.textPrimary, size: 18, ), ), ), Text('角色记忆', style: AppTextStyles.title), GestureDetector( onTap: () { showGlassDialog( context: context, title: '什么是角色记忆?', description: '角色记忆是您与 AI 互动产生的人格数据,它是独立的数字资产,可以在不同设备间迁移,或分享给好友。', confirmText: '确定', onConfirm: () => Navigator.pop(context), ); }, child: Container( width: 44, height: 44, decoration: BoxDecoration( color: AppColors.iconBtnBg, borderRadius: BorderRadius.circular(AppRadius.button), border: Border.all(color: AppColors.iconBtnBorder), ), child: const Center( child: Text( '?', style: TextStyle( fontSize: 18, color: AppColors.textSecondary, fontWeight: FontWeight.w500, ), ), ), ), ), ], ), ); } Widget _buildMemoryCard(RoleMemory memory) { final dateStr = memory.createdAt != null ? memory.createdAt!.substring(0, 10).replaceAll('-', '/') : ''; return Container( margin: const EdgeInsets.only(bottom: 16), padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: const Color(0xFFD4A373), gradient: const LinearGradient(colors: AppColors.gradientCapybara), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: const Color(0xFFC9A07A).withOpacity(0.25), blurRadius: 20, offset: const Offset(0, 8), ), ], ), child: Stack( children: [ Positioned( left: 0, right: 0, top: 0, height: 60, child: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.white.withOpacity(0.12), Colors.transparent], ), borderRadius: const BorderRadius.vertical( top: Radius.circular(20), ), ), ), ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Text( dateStr, style: TextStyle( color: Colors.white.withOpacity(0.85), fontSize: 12, ), ), ], ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 48, height: 48, decoration: BoxDecoration( color: Colors.white.withOpacity(0.25), borderRadius: BorderRadius.circular(12), ), alignment: Alignment.center, child: const Text('🧠', style: TextStyle(fontSize: 24)), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( memory.deviceTypeName.isNotEmpty ? memory.deviceTypeName : '角色记忆 #${memory.id}', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, shadows: [ Shadow( color: Color(0x1A000000), blurRadius: 2, offset: Offset(0, 1), ), ], ), ), if (memory.nickname.isNotEmpty) ...[ const SizedBox(height: 4), Text( memory.nickname, style: TextStyle( fontSize: 13, color: Colors.white.withOpacity(0.8), ), ), ], ], ), ), ], ), const SizedBox(height: 12), _buildDetailRow('状态:', memory.isBound ? '已绑定' : '空闲'), if (memory.memorySummary.isNotEmpty) ...[ const SizedBox(height: 6), _buildDetailRow('记忆:', memory.memorySummary.length > 30 ? '${memory.memorySummary.substring(0, 30)}...' : memory.memorySummary), ], const SizedBox(height: 12), Container(height: 1, color: Colors.white.withOpacity(0.2)), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ _buildStatusTag(memory.isBound), ], ), ], ), ], ), ); } Widget _buildDetailRow(String label, String value) { return RichText( text: TextSpan( style: TextStyle(fontSize: 14, color: Colors.white.withOpacity(0.85)), children: [ TextSpan(text: label), TextSpan( text: value, style: const TextStyle( color: Colors.white, fontWeight: FontWeight.w500, ), ), ], ), ); } Widget _buildStatusTag(bool isBound) { return Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 6), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(20), border: Border.all(color: Colors.white.withOpacity(0.3)), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( isBound ? Icons.link : Icons.link_off, size: 14, color: Colors.white.withOpacity(0.9), ), const SizedBox(width: 4), Text( isBound ? '使用中' : '空闲', style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w600, color: Colors.white, ), ), ], ), ); } }