import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import '../../constants/app_constants.dart'; import '../../models/colors/theme_colors.dart'; import '../../services/get/history_controller.dart'; import '../../services/get/theme_controller.dart'; class HistoryPage extends StatelessWidget { const HistoryPage({super.key}); @override Widget build(BuildContext context) { final controller = Get.put(HistoryController()); final themeController = Get.find(); return Obx(() { final isDark = themeController.isDarkMode; final primaryColor = themeController.currentThemeColor; return Scaffold( backgroundColor: isDark ? const Color(0xFF1A1A1A) : const Color(0xFFF2F2F7), appBar: _buildAppBar(controller, isDark, primaryColor), body: Column( children: [ _buildSearchBar(controller, isDark), _buildSortOptions(controller, isDark), _buildCountInfo(controller, isDark), Expanded( child: Obx( () => controller.isLoading.value ? _buildLoadingWidget(isDark) : controller.filteredHistoryList.isEmpty ? _buildEmptyWidget(isDark) : _buildHistoryList(controller, isDark, primaryColor), ), ), _buildPagination(controller, isDark, primaryColor), ], ), ); }); } PreferredSizeWidget _buildAppBar( HistoryController controller, bool isDark, Color primaryColor, ) { return AppBar( title: Text( '历史记录', style: TextStyle( color: primaryColor, fontWeight: FontWeight.w600, fontSize: 17, ), ), backgroundColor: isDark ? const Color(0xFF2A2A2A) : const Color(0xFFF2F2F7), elevation: 0, centerTitle: true, actions: [ Obx( () => CupertinoButton( padding: const EdgeInsets.symmetric(horizontal: 8), onPressed: controller.historyList.isEmpty ? null : () async { final confirmed = await Get.dialog( CupertinoAlertDialog( title: const Text('确认清空'), content: const Text('确定要清空所有历史记录吗?'), actions: [ CupertinoDialogAction( child: const Text('取消'), onPressed: () => Get.back(result: false), ), CupertinoDialogAction( isDestructiveAction: true, child: const Text('清空'), onPressed: () => Get.back(result: true), ), ], ), ); if (confirmed == true) { controller.clearHistory(); } }, child: Icon( CupertinoIcons.delete, color: controller.historyList.isEmpty ? CupertinoColors.systemGrey : CupertinoColors.systemRed, ), ), ), CupertinoButton( padding: const EdgeInsets.symmetric(horizontal: 8), onPressed: controller.showStatsDialog, child: Icon(CupertinoIcons.chart_bar, color: primaryColor), ), CupertinoButton( padding: const EdgeInsets.symmetric(horizontal: 8), onPressed: controller.exportHistory, child: Icon(CupertinoIcons.share, color: primaryColor), ), ], ); } Widget _buildSearchBar(HistoryController controller, bool isDark) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Container( decoration: BoxDecoration( color: isDark ? const Color(0xFF3A3A3A) : CupertinoColors.white, borderRadius: BorderRadius.circular(10), ), child: TextField( onChanged: controller.searchHistory, decoration: InputDecoration( hintText: '搜索历史记录...', hintStyle: TextStyle( color: isDark ? Colors.grey[500] : CupertinoColors.placeholderText, ), prefixIcon: Icon( CupertinoIcons.search, color: isDark ? Colors.grey[400] : CupertinoColors.systemGrey, ), suffixIcon: Obx( () => controller.searchKeyword.value.isNotEmpty ? CupertinoButton( padding: EdgeInsets.zero, minimumSize: Size.zero, onPressed: () => controller.searchHistory(''), child: Icon( CupertinoIcons.clear_circled_solid, color: isDark ? Colors.grey[400] : CupertinoColors.systemGrey, size: 20, ), ) : const SizedBox.shrink(), ), border: InputBorder.none, contentPadding: const EdgeInsets.symmetric( horizontal: 12, vertical: 12, ), ), style: TextStyle( color: isDark ? Colors.white : CupertinoColors.label, fontSize: 16, ), ), ), ); } Widget _buildSortOptions(HistoryController controller, bool isDark) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Row( children: [ Text( '排序', style: TextStyle( fontSize: 13, color: isDark ? Colors.grey[400] : CupertinoColors.secondaryLabel, ), ), const SizedBox(width: 12), Expanded( child: GestureDetector( onTap: () => _showSortActionSheet(controller), child: Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 8, ), decoration: BoxDecoration( color: isDark ? const Color(0xFF3A3A3A) : CupertinoColors.white, borderRadius: BorderRadius.circular(8), ), child: Obx( () => Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( controller.sortTypes[controller.selectedSortType.value], style: TextStyle( fontSize: 15, color: isDark ? Colors.white : CupertinoColors.label, ), ), Icon( CupertinoIcons.chevron_down, size: 16, color: isDark ? Colors.grey[400] : CupertinoColors.systemGrey, ), ], ), ), ), ), ), ], ), ); } // === 显示排序选项 === void _showSortActionSheet(HistoryController controller) { showCupertinoModalPopup( context: Get.context!, builder: (BuildContext context) => CupertinoActionSheet( title: const Text('选择排序方式'), actions: [ CupertinoActionSheetAction( onPressed: () { Get.back(); controller.sortHistory(0); }, child: const Text('时间倒序'), ), CupertinoActionSheetAction( onPressed: () { Get.back(); controller.sortHistory(1); }, child: const Text('时间正序'), ), CupertinoActionSheetAction( onPressed: () { Get.back(); controller.sortHistory(2); }, child: const Text('按名称排序'), ), ], cancelButton: CupertinoActionSheetAction( onPressed: () => Get.back(), child: const Text('取消'), ), ), ); } Widget _buildCountInfo(HistoryController controller, bool isDark) { return Obx( () => Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '${controller.totalCount.value} 条记录', style: TextStyle( fontSize: 13, color: isDark ? Colors.grey[400] : CupertinoColors.secondaryLabel, ), ), Text( '第 ${controller.currentPage.value} / ${controller.totalPages.value} 页', style: TextStyle( fontSize: 13, color: isDark ? Colors.grey[400] : CupertinoColors.secondaryLabel, ), ), ], ), ), ); } Widget _buildLoadingWidget(bool isDark) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CupertinoActivityIndicator( radius: 20, color: isDark ? Colors.white : null, ), const SizedBox(height: 16), Text( '加载历史记录...', style: TextStyle( fontSize: 15, color: isDark ? Colors.grey[400] : CupertinoColors.secondaryLabel.resolveFrom(Get.context!), ), ), ], ), ); } Widget _buildEmptyWidget(bool isDark) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( CupertinoIcons.time, size: 64, color: isDark ? Colors.grey[600] : CupertinoColors.systemGrey3.resolveFrom(Get.context!), ), const SizedBox(height: 16), Text( '暂无历史记录', style: TextStyle( fontSize: 17, fontWeight: FontWeight.w600, color: isDark ? Colors.white : CupertinoColors.label.resolveFrom(Get.context!), ), ), const SizedBox(height: 8), Text( '浏览诗词后会自动记录在这里', style: TextStyle( fontSize: 14, color: isDark ? Colors.grey[400] : CupertinoColors.secondaryLabel.resolveFrom(Get.context!), ), ), const SizedBox(height: 24), CupertinoButton.filled( onPressed: () => Get.back(), borderRadius: BorderRadius.circular(8), padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 12), child: const Text( '返回', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), ), ], ), ); } Widget _buildHistoryList( HistoryController controller, bool isDark, Color primaryColor, ) { final currentPageData = controller.getCurrentPageData(); return ListView.separated( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), itemCount: currentPageData.length, separatorBuilder: (context, index) => const SizedBox(height: 8), itemBuilder: (context, index) { final item = currentPageData[index]; final startIndex = (controller.currentPage.value - 1) * controller.pageSize; final actualIndex = startIndex + index; return _buildHistoryItem( context, controller, item, actualIndex, isDark, primaryColor, ); }, ); } Widget _buildHistoryItem( BuildContext context, HistoryController controller, Map item, int actualIndex, bool isDark, Color primaryColor, ) { return Container( decoration: BoxDecoration( color: isDark ? const Color(0xFF2A2A2A) : CupertinoColors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: isDark ? Colors.black.withValues(alpha: 0.3) : CupertinoColors.systemGrey4.withValues(alpha: 0.3), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: CupertinoListTile( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), leading: Container( width: 44, height: 44, decoration: BoxDecoration( color: primaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(22), ), child: Center( child: Text( '${actualIndex + 1}', style: TextStyle( fontSize: 16, color: primaryColor, fontWeight: FontWeight.w600, ), ), ), ), title: Text( item['name'] ?? '未知诗词', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: isDark ? Colors.white : CupertinoColors.label, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 4), Text( '${item['alias'] ?? '未知朝代'} • ${item['date'] ?? ''}', style: TextStyle( fontSize: 13, color: isDark ? Colors.grey[400] : CupertinoColors.secondaryLabel, ), ), if (item['introduce']?.toString().isNotEmpty == true) Padding( padding: const EdgeInsets.only(top: 4), child: Text( item['introduce']?.toString() ?? '', style: TextStyle( fontSize: 12, color: isDark ? Colors.grey[500] : CupertinoColors.tertiaryLabel, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), ), ], ), trailing: CupertinoButton( padding: EdgeInsets.zero, minimumSize: Size.zero, onPressed: () => _showActionSheet(context, controller, actualIndex, item), child: Icon( CupertinoIcons.ellipsis, color: isDark ? Colors.grey[400] : CupertinoColors.systemGrey, ), ), onTap: () { HapticFeedback.lightImpact(); }, ), ); } // === 操作菜单 === void _showActionSheet( BuildContext context, HistoryController controller, int index, Map item, ) { final themeController = Get.find(); final primaryColor = themeController.currentThemeColor; showCupertinoModalPopup( context: context, builder: (BuildContext context) => CupertinoActionSheet( title: const Text('操作'), actions: [ CupertinoActionSheetAction( onPressed: () { Get.back(); controller.deleteHistoryItem(index, item); }, isDestructiveAction: true, child: const Text('删除'), ), CupertinoActionSheetAction( onPressed: () { Get.back(); Get.snackbar('提示', '分享功能开发中...', colorText: primaryColor); }, child: const Text('分享'), ), CupertinoActionSheetAction( onPressed: () { Get.back(); Get.snackbar('提示', '查看详情功能开发中...', colorText: primaryColor); }, child: const Text('查看详情'), ), ], cancelButton: CupertinoActionSheetAction( onPressed: () => Get.back(), child: const Text('取消'), ), ), ); } Widget _buildPagination( HistoryController controller, bool isDark, Color primaryColor, ) { return Obx( () => Visibility( visible: controller.totalPages.value > 1, child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: isDark ? const Color(0xFF2A2A2A) : CupertinoColors.white, border: Border( top: BorderSide( color: isDark ? Colors.grey[800]! : CupertinoColors.separator.resolveFrom(Get.context!), width: 0.5, ), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ CupertinoButton( onPressed: controller.currentPage.value > 1 ? controller.previousPage : null, padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 8, ), color: controller.currentPage.value > 1 ? primaryColor : (isDark ? Colors.grey[800] : CupertinoColors.systemGrey5), borderRadius: BorderRadius.circular(8), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Icon( CupertinoIcons.chevron_left, size: 16, color: CupertinoColors.white, ), const SizedBox(width: 4), Text( '上一页', style: TextStyle( fontSize: 14, color: controller.currentPage.value > 1 ? CupertinoColors.white : (isDark ? Colors.grey[500] : CupertinoColors.systemGrey), ), ), ], ), ), Obx( () => Text( '${controller.currentPage.value} / ${controller.totalPages.value}', style: TextStyle( fontSize: 15, fontWeight: FontWeight.w500, color: isDark ? Colors.white : CupertinoColors.label, ), ), ), CupertinoButton( onPressed: controller.currentPage.value < controller.totalPages.value ? controller.nextPage : null, padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 8, ), color: controller.currentPage.value < controller.totalPages.value ? primaryColor : (isDark ? Colors.grey[800] : CupertinoColors.systemGrey5), borderRadius: BorderRadius.circular(8), child: Row( mainAxisSize: MainAxisSize.min, children: [ Text( '下一页', style: TextStyle( fontSize: 14, color: controller.currentPage.value < controller.totalPages.value ? CupertinoColors.white : (isDark ? Colors.grey[500] : CupertinoColors.systemGrey), ), ), const SizedBox(width: 4), const Icon( CupertinoIcons.chevron_right, size: 16, color: CupertinoColors.white, ), ], ), ), ], ), ), ), ); } }