import 'package:flutter/material.dart'; import '../../app/theme/app_colors.dart'; import '../../app/theme/app_typography.dart'; import '../../app/theme/app_spacing.dart'; import '../../app/i18n/app_localizations.dart'; import 'genex_button.dart'; /// AI操作确认弹窗组件 /// /// AI Agent 执行操作前的二次确认弹窗 /// 场景:AI帮你出售、AI帮你购买、AI帮你转赠 等需要确认的代理操作 /// /// 展示内容: /// - AI建议的操作描述 /// - 操作详情(金额/数量/对象等) /// - 风险提示 /// - 确认/取消按钮 class AiConfirmDialog extends StatelessWidget { final String actionTitle; final String actionDescription; final List details; final String? riskWarning; final String? confirmText; final String? cancelText; final VoidCallback onConfirm; final VoidCallback? onCancel; final AiConfirmLevel level; const AiConfirmDialog({ super.key, required this.actionTitle, required this.actionDescription, required this.details, this.riskWarning, this.confirmText, this.cancelText, required this.onConfirm, this.onCancel, this.level = AiConfirmLevel.normal, }); @override Widget build(BuildContext context) { return Dialog( backgroundColor: Colors.transparent, insetPadding: const EdgeInsets.symmetric(horizontal: 24), child: Container( decoration: BoxDecoration( color: AppColors.surface, borderRadius: AppSpacing.borderRadiusLg, boxShadow: const [ BoxShadow( color: Color(0x1A000000), blurRadius: 24, offset: Offset(0, 8), ), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Header with AI icon _buildHeader(context), // Body Padding( padding: const EdgeInsets.fromLTRB(20, 0, 20, 20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Action Description Text( actionDescription, style: AppTypography.bodyMedium.copyWith( color: AppColors.textSecondary, height: 1.5, ), ), const SizedBox(height: 16), // Detail Items Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: AppColors.gray50, borderRadius: AppSpacing.borderRadiusMd, ), child: Column( children: details.asMap().entries.map((entry) { final isLast = entry.key == details.length - 1; final detail = entry.value; return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( detail.label, style: AppTypography.bodySmall.copyWith( color: AppColors.textSecondary, ), ), Text( detail.value, style: detail.isHighlight ? AppTypography.labelMedium.copyWith( color: AppColors.primary, ) : AppTypography.labelMedium, ), ], ), if (!isLast) ...[ const SizedBox(height: 10), Divider(color: AppColors.gray200, height: 1), const SizedBox(height: 10), ], ], ); }).toList(), ), ), // Risk Warning if (riskWarning != null) ...[ const SizedBox(height: 12), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: level == AiConfirmLevel.high ? AppColors.errorLight : AppColors.warningLight, borderRadius: AppSpacing.borderRadiusSm, ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon( level == AiConfirmLevel.high ? Icons.warning_amber_rounded : Icons.info_outline_rounded, size: 16, color: level == AiConfirmLevel.high ? AppColors.error : AppColors.warning, ), const SizedBox(width: 8), Expanded( child: Text( riskWarning!, style: AppTypography.bodySmall.copyWith( color: AppColors.gray700, height: 1.4, ), ), ), ], ), ), ], const SizedBox(height: 20), // Buttons GenexButton( label: confirmText ?? context.t('aiChat.confirmAction'), onPressed: () { Navigator.of(context).pop(true); onConfirm(); }, ), const SizedBox(height: 8), GenexButton( label: cancelText ?? context.t('common.cancel'), variant: GenexButtonVariant.text, onPressed: () { Navigator.of(context).pop(false); onCancel?.call(); }, ), ], ), ), ], ), ), ); } Widget _buildHeader(BuildContext context) { return Container( padding: const EdgeInsets.fromLTRB(20, 20, 20, 16), child: Row( children: [ // AI Avatar Container( width: 40, height: 40, decoration: BoxDecoration( gradient: AppColors.primaryGradient, borderRadius: AppSpacing.borderRadiusSm, ), child: const Center( child: Text( '✨', style: TextStyle(fontSize: 20), ), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(context.t('aiChat.title'), style: AppTypography.labelMedium), const SizedBox(height: 2), Text( actionTitle, style: AppTypography.h3.copyWith(color: AppColors.primary), ), ], ), ), // Level indicator Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: _levelColor.withValues(alpha: 0.1), borderRadius: AppSpacing.borderRadiusFull, ), child: Text( _getLevelText(context), style: TextStyle( fontSize: 10, fontWeight: FontWeight.w600, color: _levelColor, ), ), ), ], ), ); } Color get _levelColor { switch (level) { case AiConfirmLevel.low: return AppColors.success; case AiConfirmLevel.normal: return AppColors.warning; case AiConfirmLevel.high: return AppColors.error; } } String _getLevelText(BuildContext context) { switch (level) { case AiConfirmLevel.low: return context.t('aiChat.riskLow'); case AiConfirmLevel.normal: return context.t('aiChat.riskNormal'); case AiConfirmLevel.high: return context.t('aiChat.riskHigh'); } } /// 显示AI确认弹窗的便捷方法 static Future show( BuildContext context, { required String actionTitle, required String actionDescription, required List details, String? riskWarning, String? confirmText, String? cancelText, AiConfirmLevel level = AiConfirmLevel.normal, }) { return showDialog( context: context, barrierDismissible: false, builder: (ctx) => AiConfirmDialog( actionTitle: actionTitle, actionDescription: actionDescription, details: details, riskWarning: riskWarning, confirmText: confirmText, cancelText: cancelText, level: level, onConfirm: () {}, ), ); } } /// AI确认弹窗的详情项 class AiConfirmDetail { final String label; final String value; final bool isHighlight; const AiConfirmDetail({ required this.label, required this.value, this.isHighlight = false, }); } /// AI操作风险等级 enum AiConfirmLevel { /// 低风险:查看信息、获取建议等 low, /// 需确认:购买、出售、转赠等涉及资产操作 normal, /// 高风险:大额操作、提现到外部钱包等 high, }