import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/navigation_provider.dart';
import '../../../providers/chat_provider.dart';
import '../../../providers/data_providers.dart';

/// 对话消息列表
class ChatMessagesView extends ConsumerWidget {
  final ScrollController scrollCtrl;
  final List<ChatMessage> messages;

  const ChatMessagesView({super.key, required this.scrollCtrl, required this.messages});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final chatState = ref.watch(chatProvider);

    if (messages.isEmpty) {
      return Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              width: 80,
              height: 80,
              decoration: BoxDecoration(
                color: const Color(0xFFF0F2FF),
                borderRadius: BorderRadius.circular(40),
              ),
              child: const Icon(Icons.health_and_safety, size: 40, color: Color(0xFF8B9CF7)),
            ),
            const SizedBox(height: 16),
            Text('开始和 AI 健康管家对话吧', style: Theme.of(context).textTheme.bodyMedium),
            const SizedBox(height: 8),
            const Text('记录健康数据，获取专业建议', style: TextStyle(fontSize: 14, color: Color(0xFF9E9E9E))),
          ],
        ),
      );
    }

    return ListView.builder(
      controller: scrollCtrl,
      reverse: true,
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
      itemCount: messages.length,
      itemBuilder: (context, index) {
        final msg = messages[messages.length - 1 - index];
        return _buildMessageContent(context, ref, msg, chatState);
      },
    );
  }

  // ─── 消息分发 ─────────────────────────────────────────────

  Widget _buildMessageContent(BuildContext context, WidgetRef ref, ChatMessage msg, ChatState chatState) {
    switch (msg.type) {
      case MessageType.agentWelcome:
        final storedAgent = _parseAgentFromName(msg.metadata?['agent'] as String?);
        return _buildAgentWelcomeCard(context, ref, msg, storedAgent);
      case MessageType.taskCard:
        return _buildTaskCardInChat(context, ref);
      case MessageType.dataConfirm:
        return _buildDataConfirmCard(context, msg);
      case MessageType.medicationConfirm:
        return _buildMedicationConfirmCard(context, msg);
      case MessageType.dietAnalysis:
        return _buildDietAnalysisCard(context, msg);
      case MessageType.reportAnalysis:
        return _buildReportAnalysisCard(context, msg);
      case MessageType.onboarding:
        return _buildOnboardingCard(context, ref);
      case MessageType.quickOptions:
        return _buildQuickOptionsCard(context, msg);
      default:
        // 只有当前正在流式回复的文本消息才显示"正在分析"
        if (!msg.isUser && chatState.isStreaming && msg.content.isEmpty) {
          return _buildThinkingBubble(context, chatState.thinkingText);
        }
        return _buildTextBubble(context, msg);
    }
  }

  // ═══════════════════════════════════════════════════════════
  // 1. AgentWelcomeCard — 智能体欢迎卡片
  // ═══════════════════════════════════════════════════════════

  Widget _buildAgentWelcomeCard(BuildContext context, WidgetRef ref, ChatMessage msg, ActiveAgent agent) {
    final info = _agentInfo(agent);
    final actions = agent.actions;
    final screenWidth = MediaQuery.of(context).size.width;
    final colors = _agentColors(agent);

    return Align(
      alignment: Alignment.centerLeft,
      child: Container(
        margin: const EdgeInsets.only(bottom: 12),
        constraints: BoxConstraints(maxWidth: screenWidth * 0.92),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(20),
          boxShadow: [
            BoxShadow(color: colors.gradient[0].withAlpha(30), blurRadius: 16, offset: const Offset(0, 4)),
          ],
        ),
        clipBehavior: Clip.antiAlias,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            // ── 渐变色头部 ──
            Container(
              width: double.infinity,
              padding: const EdgeInsets.fromLTRB(20, 24, 16, 20),
              decoration: BoxDecoration(
                gradient: LinearGradient(
                  colors: colors.gradient,
                  begin: Alignment.topLeft,
                  end: Alignment.bottomRight,
                ),
              ),
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Container(
                    width: 48,
                    height: 48,
                    decoration: BoxDecoration(
                      color: Colors.white.withAlpha(30),
                      borderRadius: BorderRadius.circular(14),
                    ),
                    child: Icon(info.$1, size: 26, color: Colors.white),
                  ),
                  const SizedBox(width: 14),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(info.$2, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: Colors.white)),
                        const SizedBox(height: 4),
                        Container(
                          padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 3),
                          decoration: BoxDecoration(
                            color: Colors.white.withAlpha(25),
                            borderRadius: BorderRadius.circular(10),
                          ),
                          child: Text(info.$3, style: const TextStyle(fontSize: 12, color: Color(0xFFE8E6FF))),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),

            // ── 快捷操作按钮网格 ──
            Padding(
              padding: const EdgeInsets.fromLTRB(18, 18, 18, 4),
              child: Wrap(
                spacing: 10,
                runSpacing: 10,
                children: agent == ActiveAgent.consultation
                    ? _buildDoctorCards(screenWidth, ref)
                    : actions.map((a) => _agentActionBtn(a, screenWidth, context, ref, colors)).toList(),
              ),
            ),

            const SizedBox(height: 12),
          ],
        ),
      ),
    );
  }

  Widget _agentActionBtn(_AgentAction a, double screenWidth, BuildContext context, WidgetRef ref, _AgentColors colors) {
    return InkWell(
      onTap: () {
        if (a.label == '服药打卡') {
          _medicationCheckIn(ref, context);
        } else if (a.route != null) {
          if (a.route == 'camera' || a.route == 'gallery') {
            ref.read(cameraActionProvider.notifier).trigger(a.route!);
          } else {
            pushRoute(ref, a.route!);
          }
        }
      },
      borderRadius: BorderRadius.circular(14),
      child: Container(
        width: ((screenWidth - 72) / (a.isWide ? 2 : 3)) - 10,
        padding: const EdgeInsets.symmetric(vertical: 13, horizontal: 8),
        decoration: BoxDecoration(
          color: colors.bg,
          borderRadius: BorderRadius.circular(14),
          border: Border.all(color: colors.border, width: 1),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              width: 38,
              height: 38,
              decoration: BoxDecoration(
                color: colors.iconBg,
                borderRadius: BorderRadius.circular(11),
              ),
              child: Icon(a.icon, size: 20, color: colors.accent),
            ),
            const SizedBox(height: 7),
            Text(a.label, style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500, color: Color(0xFF333333))),
          ],
        ),
      ),
    );
  }

  List<Widget> _buildDoctorCards(double screenWidth, WidgetRef ref) {
    const doctors = [
      {'name': '张医生', 'title': '主任医师', 'dept': '心内科', 'desc': '冠心病、高血压术后管理', 'id': 'doc_1'},
      {'name': '李医生', 'title': '副主任医师', 'dept': '内分泌科', 'desc': '糖尿病、甲状腺疾病管理', 'id': 'doc_2'},
      {'name': '王医生', 'title': '主治医师', 'dept': '营养科', 'desc': '术后营养指导、饮食方案制定', 'id': 'doc_3'},
    ];
    return doctors.map((d) => _doctorCard(d, screenWidth, ref)).toList();
  }

  Widget _doctorCard(Map<String, String> doc, double screenWidth, WidgetRef ref) {
    return InkWell(
      onTap: () => pushRoute(ref, 'consultation', params: {'id': doc['id']!}),
      borderRadius: BorderRadius.circular(14),
      child: Container(
        width: screenWidth * 0.38,
        padding: const EdgeInsets.all(12),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(14),
          border: Border.all(color: const Color(0xFFF0F2FF)),
        ),
        child: Column(children: [
          CircleAvatar(
            radius: 24,
            backgroundColor: const Color(0xFFF0F2FF),
            child: Text(doc['name']![0], style: const TextStyle(fontSize: 20, color: Color(0xFF8B9CF7))),
          ),
          const SizedBox(height: 8),
          Text(doc['name']!, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600)),
          Text(doc['title']!, style: const TextStyle(fontSize: 11, color: Color(0xFF999999))),
          const SizedBox(height: 2),
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
            decoration: BoxDecoration(
              color: const Color(0xFFF0F2FF),
              borderRadius: BorderRadius.circular(4),
            ),
            child: Text(doc['dept']!, style: const TextStyle(fontSize: 10, color: Color(0xFF8B9CF7))),
          ),
          const SizedBox(height: 6),
          Text(
            doc['desc']!,
            style: const TextStyle(fontSize: 10, color: Color(0xFF888888), height: 1.3),
            maxLines: 2,
            overflow: TextOverflow.ellipsis,
          ),
        ]),
      ),
    );
  }

  // ═══════════════════════════════════════════════════════════
  // 2. DataConfirmCard — 增强版数据确认卡片
  // ═══════════════════════════════════════════════════════════

  Widget _buildDataConfirmCard(BuildContext context, ChatMessage msg) {
    final meta = msg.metadata;
    final metricType = meta?['type'] as String? ?? '';
    final value = meta?['value'] as String? ?? '';
    final abnormal = meta?['abnormal'] as bool? ?? false;
    final recordTime = meta?['recordTime'] as String? ?? '';
    final unit = meta?['unit'] as String? ?? _getMetricUnit(metricType);
    final trend = meta?['trend'] as List? ?? [0.6, 0.8, 0.5];

    return Align(
      alignment: Alignment.centerLeft,
      child: Container(
        margin: const EdgeInsets.only(bottom: 12),
        constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.88),
        decoration: BoxDecoration(
          color: const Color(0xFFFFFFFF),
          borderRadius: BorderRadius.circular(20),
          boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
        ),
        clipBehavior: Clip.antiAlias,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            // ── 绿色勾选条 ──
            Container(
              width: double.infinity,
              padding: const EdgeInsets.symmetric(vertical: 10),
              decoration: const BoxDecoration(
                gradient: LinearGradient(colors: [Color(0xFF4CAF50), Color(0xFF43A047)]),
              ),
              child: const Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Icon(Icons.check_circle, size: 18, color: Colors.white),
                  SizedBox(width: 6),
                  Text('✓ 数据已记录', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.white)),
                ],
              ),
            ),

            Padding(
              padding: const EdgeInsets.all(18),
              child: Column(
                children: [
                  // 记录时间
                  Align(
                    alignment: Alignment.centerLeft,
                    child: Text(recordTime.isNotEmpty ? recordTime : _formatTime(msg.createdAt), style: const TextStyle(fontSize: 12, color: Color(0xFF9E9E9E))),
                  ),
                  const SizedBox(height: 14),

                  // 主要指标区域
                  Container(
                    padding: const EdgeInsets.all(18),
                    decoration: BoxDecoration(
                      color: const Color(0xFFF9F8FF),
                      borderRadius: BorderRadius.circular(16),
                    ),
                    child: Row(
                      children: [
                        Container(
                          width: 52,
                          height: 52,
                          decoration: BoxDecoration(
                            color: const Color(0xFFEDEAFF),
                            borderRadius: BorderRadius.circular(14),
                          ),
                          child: Center(child: Text(_getMetricIcon(metricType), style: const TextStyle(fontSize: 26))),
                        ),
                        const SizedBox(width: 14),
                        Expanded(
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(_getMetricName(metricType), style: const TextStyle(fontSize: 13, color: Color(0xFF888888))),
                              const SizedBox(height: 4),
                              RichText(
                                text: TextSpan(
                                  children: [
                                    TextSpan(text: value, style: TextStyle(fontSize: 28, fontWeight: FontWeight.w800, color: abnormal ? const Color(0xFFE53935) : const Color(0xFF1A1A2E))),
                                    TextSpan(text: ' $unit', style: TextStyle(fontSize: 14, color: abnormal ? const Color(0xFFE53970) : const Color(0xFF999999))),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),

                  // 异常警告条
                  if (abnormal) ...[
                    const SizedBox(height: 12),
                    Container(
                      width: double.infinity,
                      padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
                      decoration: BoxDecoration(
                        color: const Color(0xFFFFF3F0),
                        borderRadius: BorderRadius.circular(10),
                        border: Border.all(color: const Color(0xFFFFDAD4), width: 1),
                      ),
                      child: const Row(
                        children: [
                          Icon(Icons.warning_amber_rounded, size: 18, color: Color(0xFFE53935)),
                          SizedBox(width: 8),
                          Expanded(child: Text('⚠️ 数值偏高，建议关注', style: TextStyle(fontSize: 13, color: Color(0xFFE53935), fontWeight: FontWeight.w500))),
                        ],
                      ),
                    ),
                  ],

                  // 迷你趋势图（最近3次）
                  const SizedBox(height: 16),
                  Row(
                    children: [
                      const Text('近期趋势', style: TextStyle(fontSize: 12, color: Color(0xFFAAAAAA))),
                      const Spacer(),
                      const Text('最近3次', style: TextStyle(fontSize: 11, color: Color(0xFFCCCCCC))),
                    ],
                  ),
                  const SizedBox(height: 8),
                  SizedBox(
                    height: 36,
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children: trend.asMap().entries.map((e) {
                        final h = (e.value * 32).clamp(6.0, 32.0);
                        return Padding(
                          padding: EdgeInsets.only(right: e.key < trend.length - 1 ? 10 : 0),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.end,
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Container(
                                width: 22,
                                height: h,
                                decoration: BoxDecoration(
                                  color: e.key == trend.length - 1 ? const Color(0xFF8B9CF7) : const Color(0xFFD5D0FF),
                                  borderRadius: BorderRadius.circular(5),
                                ),
                              ),
                              const SizedBox(height: 4),
                              Text('${e.key + 1}', style: const TextStyle(fontSize: 9, color: Color(0xFFBBBBBB))),
                            ],
                          ),
                        );
                      }).toList(),
                    ),
                  ),

                  // 底部操作按钮
                  const SizedBox(height: 18),
                  Row(children: [
                    Expanded(child: _cardOutlineBtn('编辑', Icons.edit_outlined)),
                    const SizedBox(width: 8),
                    Expanded(child: _cardFilledBtn('确认', Icons.check)),
                    const SizedBox(width: 8),
                    Expanded(child: _cardOutlineBtn('查看详情', Icons.trending_up_outlined)),
                  ]),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  // ═══════════════════════════════════════════════════════════
  // 3. MedicationConfirmCard — 增强版用药确认卡片
  // ═══════════════════════════════════════════════════════════

  Widget _buildMedicationConfirmCard(BuildContext context, ChatMessage msg) {
    final meta = msg.metadata;
    final name = meta?['name'] as String? ?? '';
    final dosage = meta?['dosage'] as String? ?? '';
    final time = meta?['time'] as String? ?? '';
    final frequency = meta?['frequency'] as String? ?? '';
    final remaining = meta?['remaining'] as double? ?? 0.65;

    return Align(
      alignment: Alignment.centerLeft,
      child: Container(
        margin: const EdgeInsets.only(bottom: 12),
        constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.88),
        decoration: BoxDecoration(
          color: const Color(0xFFFFFFFF),
          borderRadius: BorderRadius.circular(20),
          boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
        ),
        clipBehavior: Clip.antiAlias,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            // ── 药品头部 ──
            Container(
              width: double.infinity,
              padding: const EdgeInsets.fromLTRB(18, 20, 18, 16),
              decoration: const BoxDecoration(
                gradient: LinearGradient(colors: [Color(0xFFE8F0FE), Color(0xFFF0F2FF)]),
              ),
              child: Row(
                children: [
                  Container(
                    width: 46,
                    height: 46,
                    decoration: BoxDecoration(
                      color: const Color(0xFFFFF3E0),
                      borderRadius: BorderRadius.circular(13),
                    ),
                    child: const Center(child: Text('💊', style: TextStyle(fontSize: 24))),
                  ),
                  const SizedBox(width: 14),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(name, style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w700, color: Color(0xFF1A1A2E))),
                        if (dosage.isNotEmpty) ...[
                          const SizedBox(height: 3),
                          Text(dosage, style: const TextStyle(fontSize: 13, color: Color(0xFF777777))),
                        ],
                      ],
                    ),
                  ),
                ],
              ),
            ),

            Padding(
              padding: const EdgeInsets.fromLTRB(18, 16, 18, 6),
              child: Column(
                children: [
                  // 服药时间 & 频率
                  _medInfoRow(Icons.schedule_outlined, time.isNotEmpty ? '服药时间：$time' : '待设置'),
                  if (frequency.isNotEmpty) _medInfoRow(Icons.repeat, '频率：$frequency'),

                  // 剩余药量进度条
                  const SizedBox(height: 14),
                  Row(
                    children: [
                      const Text('剩余药量', style: TextStyle(fontSize: 13, color: Color(0xFF666666))),
                      const Spacer(),
                      Text('${(remaining * 100).toInt()}%', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF8B9CF7))),
                    ],
                  ),
                  const SizedBox(height: 8),
                  ClipRRect(
                    borderRadius: BorderRadius.circular(6),
                    child: LinearProgressIndicator(
                      value: remaining,
                      minHeight: 8,
                      backgroundColor: const Color(0xFFEFEDFF),
                      valueColor: const AlwaysStoppedAnimation<Color>(Color(0xFF8B9CF7)),
                    ),
                  ),

                  // 操作按钮
                  const SizedBox(height: 18),
                  Row(children: [
                    Expanded(child: _cardFilledBtn('确认服药', Icons.check_circle_outline)),
                    const SizedBox(width: 8),
                    Expanded(child: _cardOutlineBtn('跳过', Icons.skip_next)),
                    const SizedBox(width: 8),
                    Expanded(child: _cardOutlineBtn('设置提醒', Icons.notifications_none_outlined)),
                  ]),
                  const SizedBox(height: 8),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _medInfoRow(IconData icon, String text) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 10),
      child: Row(
        children: [
          Icon(icon, size: 17, color: const Color(0xFF888888)),
          const SizedBox(width: 8),
          Text(text, style: const TextStyle(fontSize: 13, color: Color(0xFF444444))),
        ],
      ),
    );
  }

  // ═══════════════════════════════════════════════════════════
  // 4. DietAnalysisCard — 增强版饮食分析卡片
  // ═══════════════════════════════════════════════════════════

  Widget _buildDietAnalysisCard(BuildContext context, ChatMessage msg) {
    final meta = msg.metadata;
    final foods = meta?['foods'] as List? ?? [];
    final totalCalories = meta?['totalCalories'] as int? ?? 0;
    final advice = meta?['advice'] as String? ?? '饮食均衡，多吃蔬菜水果，减少高油高糖食物摄入。';

    return Align(
      alignment: Alignment.centerLeft,
      child: Container(
        margin: const EdgeInsets.only(bottom: 12),
        constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.88),
        decoration: BoxDecoration(
          color: const Color(0xFFFFFFFF),
          borderRadius: BorderRadius.circular(20),
          boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
        ),
        clipBehavior: Clip.antiAlias,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            // ── 头部 ──
            Container(
              width: double.infinity,
              padding: const EdgeInsets.symmetric(vertical: 12),
              decoration: const BoxDecoration(gradient: LinearGradient(colors: [Color(0xFFFFF8E1), Color(0xFFFFF3E0)])),
              child: const Row(mainAxisAlignment: MainAxisAlignment.center, children: [
                Text('🍽️ ', style: TextStyle(fontSize: 18)),
                Text('饮食分析结果', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700, color: Color(0xFF1A1A2E))),
              ]),
            ),
            Padding(
              padding: const EdgeInsets.all(16),
              child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                // ── 总热量（仅 >0 时显示） ──
                if (totalCalories > 0) ...[
                  Center(child: Column(children: [
                    Text('$totalCalories', style: const TextStyle(fontSize: 36, fontWeight: FontWeight.w800, color: Color(0xFFFF8F00))),
                    const Text('千卡 (kcal)', style: TextStyle(fontSize: 12, color: Color(0xFFAAAAAA))),
                  ])),
                  const SizedBox(height: 16),
                ],

                // ── 识别食物列表 ──
                if (foods.isNotEmpty) ...[
                  const Text('识别结果', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))),
                  const SizedBox(height: 10),
                  ...foods.map((food) {
                    final f = food is Map ? food : <String, dynamic>{};
                    final name = f['name'] as String? ?? '';
                    final calories = f['calories'] as num? ?? 0;
                    final portion = f['portion'] as String?;
                    final nutrients = f['nutrients'] as String?;

                    return Container(
                      margin: const EdgeInsets.only(bottom: 8),
                      padding: const EdgeInsets.all(10),
                      decoration: BoxDecoration(color: const Color(0xFFFAFAFA), borderRadius: BorderRadius.circular(10), border: Border.all(color: const Color(0xFFF0F0F0))),
                      child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                        Row(children: [
                          Expanded(child: Text(name, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Color(0xFF1A1A1A)))),
                          if (calories > 0) Text('${calories is int ? calories : calories.toInt()} kcal', style: const TextStyle(fontSize: 13, color: Color(0xFF888888))),
                        ]),
                        if (portion != null && portion.isNotEmpty) Padding(padding: const EdgeInsets.only(top: 4), child: Text(portion, style: TextStyle(fontSize: 12, color: Colors.grey[500]))),
                        if (nutrients != null && nutrients.isNotEmpty) Padding(padding: const EdgeInsets.only(top: 2), child: Text(nutrients, style: TextStyle(fontSize: 11, color: Colors.grey[500]))),
                      ]),
                    );
                  }),
                  const SizedBox(height: 6),
                ],

                // ── AI 建议 ──
                const SizedBox(height: 14),
                const Text('AI 建议', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))),
                const SizedBox(height: 6),
                Container(
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(color: const Color(0xFFF0F2FF), borderRadius: BorderRadius.circular(10)),
                  child: Text(advice, style: const TextStyle(fontSize: 13, height: 1.6, color: Color(0xFF555555))),
                ),
              ]),
            ),
          ],
        ),
      ),
    );
  }

  // ═══════════════════════════════════════════════════════════
  // 5. ReportAnalysisCard — 增强版报告分析卡片
  // ═══════════════════════════════════════════════════════════

  Widget _buildReportAnalysisCard(BuildContext context, ChatMessage msg) {
    final meta = msg.metadata;
    final reportType = meta?['type'] as String? ?? '体检报告';
    final reportDate = meta?['date'] as String? ?? '';
    final indicators = meta?['indicators'] as List? ?? [];
    final summary = meta?['summary'] as String? ?? '';

    return Align(
      alignment: Alignment.centerLeft,
      child: Container(
        margin: const EdgeInsets.only(bottom: 12),
        constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.88),
        decoration: BoxDecoration(
          color: const Color(0xFFFFFFFF),
          borderRadius: BorderRadius.circular(20),
          boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
        ),
        clipBehavior: Clip.antiAlias,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            // ── 报告头部 ──
            Container(
              width: double.infinity,
              padding: const EdgeInsets.fromLTRB(18, 18, 18, 14),
              decoration: const BoxDecoration(
                gradient: LinearGradient(colors: [Color(0xFFE8EAF6), Color(0xFFEDE7F6)]),
              ),
              child: Row(
                children: [
                  Container(
                    width: 40,
                    height: 40,
                    decoration: BoxDecoration(
                      color: const Color(0xFFC5CAE9),
                      borderRadius: BorderRadius.circular(10),
                    ),
                    child: const Icon(Icons.description_outlined, size: 20, color: Color(0xFF3F51B5)),
                  ),
                  const SizedBox(width: 12),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(reportType, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w700, color: Color(0xFF1A1A2E))),
                        if (reportDate.isNotEmpty)
                          Text(reportDate, style: const TextStyle(fontSize: 12, color: Color(0xFF888888))),
                      ],
                    ),
                  ),
                ],
              ),
            ),

            Padding(
              padding: const EdgeInsets.all(16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  // 指标表格
                  Container(
                    decoration: BoxDecoration(
                      color: const Color(0xFFFAFAFC),
                      borderRadius: BorderRadius.circular(12),
                      border: Border.all(color: const Color(0xFFEEEEEE), width: 1),
                    ),
                    child: Column(
                      children: [
                        // 表头
                        Container(
                          padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
                          decoration: const BoxDecoration(
                            color: Color(0xFFF5F4FA),
                            borderRadius: BorderRadius.vertical(top: Radius.circular(12)),
                          ),
                          child: const Row(
                            children: [
                              Expanded(flex: 2, child: Text('指标名称', style: TextStyle(fontSize: 11, fontWeight: FontWeight.w600, color: Color(0xFF666666)))),
                              Expanded(flex: 1, child: Text('数值', style: TextStyle(fontSize: 11, fontWeight: FontWeight.w600, color: Color(0xFF666666)), textAlign: TextAlign.center)),
                              Expanded(flex: 1, child: Text('状态', style: TextStyle(fontSize: 11, fontWeight: FontWeight.w600, color: Color(0xFF666666)), textAlign: TextAlign.center)),
                            ],
                          ),
                        ),
                        // 数据行
                        ...indicators.map((ind) {
                          final i = ind as Map? ?? {};
                          final name = i['name'] as String? ?? '';
                          final value = i['value'] as String? ?? '';
                          final status = i['status'] as String? ?? 'normal';
                          final refRange = i['refRange'] as String? ?? '';
                          final isAbnormal = status != 'normal';
                          Color sc;
                          switch (status) {
                            case 'high': sc = const Color(0xFFE53935); break;
                            case 'low': sc = const Color(0xFFF9A825); break;
                            default: sc = const Color(0xFF43A047);
                          }
                          return Container(
                            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
                            decoration: BoxDecoration(
                              color: isAbnormal ? const Color(0xFFFFF8F5) : Colors.transparent,
                              border: Border(
                                bottom: BorderSide(color: const Color(0xFFF0F0F0), width: 0.5),
                              ),
                            ),
                            child: Row(
                              children: [
                                Expanded(
                                  flex: 2,
                                  child: Column(
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: [
                                      Text(name, style: TextStyle(fontSize: 13, color: isAbnormal ? const Color(0xFFE53935) : const Color(0xFF333333), fontWeight: isAbnormal ? FontWeight.w600 : FontWeight.normal)),
                                      if (refRange.isNotEmpty) Text('参考：$refRange', style: const TextStyle(fontSize: 10, color: Color(0xFFAAAAAA))),
                                    ],
                                  ),
                                ),
                                Expanded(flex: 1, child: Text(value, textAlign: TextAlign.center, style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: sc))),
                                Expanded(
                                  flex: 1,
                                  child: Center(
                                    child: Container(
                                      width: 8,
                                      height: 8,
                                      decoration: BoxDecoration(shape: BoxShape.circle, color: sc),
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          );
                        }),
                      ],
                    ),
                  ),

                  // AI 解读摘要
                  if (summary.isNotEmpty) ...[
                    const SizedBox(height: 14),
                    Container(
                      width: double.infinity,
                      padding: const EdgeInsets.all(14),
                      decoration: BoxDecoration(
                        color: const Color(0xFFF3EFFF),
                        borderRadius: BorderRadius.circular(12),
                        border: Border.all(color: const Color(0xFFDDD8FF), width: 0.8),
                      ),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const Row(
                            children: [
                              Icon(Icons.auto_awesome, size: 16, color: Color(0xFF8B9CF7)),
                              SizedBox(width: 6),
                              Text('AI 解读摘要', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF8B9CF7))),
                            ],
                          ),
                          const SizedBox(height: 8),
                          Text(summary, style: const TextStyle(fontSize: 13, color: Color(0xFF555555), height: 1.5)),
                        ],
                      ),
                    ),
                  ],

                  // 查看完整解读按钮
                  const SizedBox(height: 14),
                  SizedBox(
                    width: double.infinity,
                    child: _cardFilledBtn('查看完整解读', Icons.article_outlined),
                  ),
                  const SizedBox(height: 4),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  // ═══════════════════════════════════════════════════════════
  // 6. OnboardingCard — 首次建档引导
  Widget _buildOnboardingCard(BuildContext context, WidgetRef ref) {
    return Align(
      alignment: Alignment.centerLeft,
      child: Container(
        margin: const EdgeInsets.only(bottom: 12),
        constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.88),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(20),
          boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(25), blurRadius: 14, offset: const Offset(0, 4))],
        ),
        clipBehavior: Clip.antiAlias,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              width: double.infinity,
              padding: const EdgeInsets.fromLTRB(20, 24, 20, 16),
              decoration: const BoxDecoration(
                gradient: LinearGradient(colors: [Color(0xFF8B9CF7), Color(0xFFA78BFA)], begin: Alignment.topLeft, end: Alignment.bottomRight),
              ),
              child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                Row(children: [
                  Container(width: 48, height: 48, decoration: BoxDecoration(color: Colors.white.withAlpha(30), borderRadius: BorderRadius.circular(14)), child: const Icon(Icons.health_and_safety, size: 28, color: Colors.white)),
                  const SizedBox(width: 14),
                  const Text('欢迎来到健康管家！', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: Colors.white)),
                ]),
                const SizedBox(height: 12),
                Text('我是您的AI健康管家。为了给您更精准的建议，\n我先了解一些基本信息好吗？大约2-3分钟。',
                    style: TextStyle(fontSize: 14, color: Colors.white.withAlpha(220), height: 1.5)),
              ]),
            ),
            Padding(
              padding: const EdgeInsets.fromLTRB(18, 18, 18, 20),
              child: Column(children: [
                SizedBox(
                  width: double.infinity,
                  child: ElevatedButton(
                    onPressed: () {
                      ref.read(chatProvider.notifier).startOnboarding();
                    },
                    style: ElevatedButton.styleFrom(backgroundColor: const Color(0xFF8B9CF7), foregroundColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), padding: const EdgeInsets.symmetric(vertical: 14)),
                    child: const Text('开始建档', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
                  ),
                ),
                const SizedBox(height: 10),
                TextButton(
                    onPressed: () => ref.read(chatProvider.notifier).dismissOnboarding(),
                    child: const Text('以后再说', style: TextStyle(fontSize: 14, color: Color(0xFF999999)))),
              ]),
            ),
          ],
        ),
      ),
    );
  }

  // 7. QuickOptionsCard — 优化样式
  // ═══════════════════════════════════════════════════════════

  Widget _buildQuickOptionsCard(BuildContext context, ChatMessage msg) {
    final meta = msg.metadata;
    final options = meta?['options'] as List? ?? [];

    return Align(
      alignment: Alignment.centerLeft,
      child: Container(
        margin: const EdgeInsets.only(bottom: 12),
        constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.88),
        decoration: BoxDecoration(
          color: const Color(0xFFFFFFFF),
          borderRadius: BorderRadius.circular(20),
          boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
        ),
        child: Padding(
          padding: const EdgeInsets.fromLTRB(18, 16, 18, 14),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(msg.content, style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w500, color: Color(0xFF1A1A2E))),
              const SizedBox(height: 14),
              Wrap(spacing: 8, runSpacing: 8, children: options.map((opt) {
                final o = opt as Map? ?? {};
                return ElevatedButton(
                  onPressed: () {},
                  style: ElevatedButton.styleFrom(
                    backgroundColor: const Color(0xFFF0F2FF),
                    foregroundColor: const Color(0xFF8B9CF7),
                    elevation: 0,
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
                    padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 11),
                  ),
                  child: Text(o['label'] as String? ?? '', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500)),
                );
              }).toList()),
            ],
          ),
        ),
      ),
    );
  }

  // ═══════════════════════════════════════════════════════════
  // 公共组件：思考气泡 & 文本气泡
  // ═══════════════════════════════════════════════════════════

  Widget _buildThinkingBubble(BuildContext context, String? thinkingText) {
    return Align(
      alignment: Alignment.centerLeft,
      child: Container(
        margin: const EdgeInsets.only(bottom: 12),
        padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 14),
        decoration: BoxDecoration(
          color: const Color(0xFFFEFEFF),
          borderRadius: const BorderRadius.only(topLeft: Radius.circular(4), topRight: Radius.circular(20), bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
          border: Border.all(color: const Color(0xFFD8DCFD), width: 1.5),
          boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(12), blurRadius: 10, offset: const Offset(0, 3))],
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              width: 26,
              height: 26,
              padding: const EdgeInsets.all(5),
              decoration: BoxDecoration(
                color: const Color(0xFFF0F2FF),
                borderRadius: BorderRadius.circular(13),
              ),
              child: const CircularProgressIndicator(strokeWidth: 2.2, color: Color(0xFF8B9CF7)),
            ),
            const SizedBox(width: 10),
            Text(thinkingText?.isNotEmpty == true ? thinkingText! : '正在分析...', style: const TextStyle(fontSize: 14, color: Color(0xFF999999))),
          ],
        ),
      ),
    );
  }

  Widget _buildTextBubble(BuildContext context, ChatMessage msg) {
    final isUser = msg.isUser;
    final imageUrl = msg.metadata?['imageUrl'] as String?;
    final localPath = msg.metadata?['localImagePath'] as String?;
    final hasImage = imageUrl != null || localPath != null;

    return Align(
      alignment: isUser ? Alignment.centerRight : Alignment.centerLeft,
      child: Container(
        margin: const EdgeInsets.only(bottom: 12),
        constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.82),
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
        decoration: BoxDecoration(
          color: isUser ? const Color(0xFF8B9CF7) : const Color(0xFFFEFEFF),
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(isUser ? 20 : 4),
            topRight: Radius.circular(isUser ? 4 : 20),
            bottomLeft: const Radius.circular(20),
            bottomRight: const Radius.circular(20),
          ),
          border: isUser ? null : Border.all(color: const Color(0xFFD8DCFD), width: 1.5),
          boxShadow: isUser ? [] : [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(12), blurRadius: 10, offset: const Offset(0, 3))],
        ),
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 文字内容
              if (isUser)
                Text(msg.content, style: const TextStyle(fontSize: 16, color: Colors.white, height: 1.4))
              else
                MarkdownBody(
                  data: msg.content,
                  selectable: true,
                  styleSheet: MarkdownStyleSheet(
                    p: const TextStyle(fontSize: 16, color: Color(0xFF1A1A1A), height: 1.5),
                    h1: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)),
                    h2: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)),
                    code: const TextStyle(fontSize: 14, backgroundColor: Color(0xFFF0F2FF)),
                  ),
                ),

              // 图片缩略图（在文字下方）
              if (hasImage)
                Padding(
                  padding: const EdgeInsets.only(top: 8),
                  child: GestureDetector(
                    onTap: () => _showFullImage(context, localPath ?? imageUrl),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(8),
                      child: ConstrainedBox(
                        constraints: const BoxConstraints(maxWidth: 160, maxHeight: 120),
                        child: localPath != null
                            ? Image.file(File(localPath), fit: BoxFit.cover)
                            : imageUrl != null
                                ? Image.network(imageUrl, fit: BoxFit.cover, errorBuilder: (_, e, s) => Container(
                                    width: 80, height: 60,
                                    decoration: BoxDecoration(color: const Color(0xFFF0F0F0), borderRadius: BorderRadius.circular(8)),
                                    child: const Icon(Icons.image, size: 24, color: Color(0xFFBBBBBB)),
                                  ))
                                : const SizedBox.shrink(),
                      ),
                    ),
                  ),
                ),

              if (!isUser && msg.content.isNotEmpty)
              Padding(
                padding: const EdgeInsets.only(top: 10),
                child: Row(children: [
                  const CircleAvatar(radius: 10, backgroundColor: Color(0xFFF0F2FF), child: Icon(Icons.chat_bubble_outline, size: 14, color: Color(0xFF8B9CF7))),
                  const SizedBox(width: 6),
                  const Text('健康管家', style: TextStyle(fontSize: 12, color: Color(0xFF9E9E9E))),
                  const SizedBox(width: 4),
                  const Text('仅供参考', style: TextStyle(fontSize: 11, color: Color(0xFFCCCCCC))),
                ]),
              ),
          ],
        ),
      ),
    );
  }

  // ═══════════════════════════════════════════════════════════
  // 公共组件：通用按钮
  // ═══════════════════════════════════════════════════════════

  Widget _cardFilledBtn(String label, IconData icon) {
    return ElevatedButton(
      onPressed: () {},
      style: ElevatedButton.styleFrom(
        backgroundColor: const Color(0xFF8B9CF7),
        foregroundColor: Colors.white,
        elevation: 0,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
        padding: const EdgeInsets.symmetric(vertical: 11),
      ),
      child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
        Icon(icon, size: 16),
        const SizedBox(width: 5),
        Text(label, style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500)),
      ]),
    );
  }

  Widget _cardOutlineBtn(String label, IconData icon) {
    return OutlinedButton(
      onPressed: () {},
      style: OutlinedButton.styleFrom(
        foregroundColor: const Color(0xFF8B9CF7),
        side: const BorderSide(color: Color(0xFF8B9CF7), width: 1.2),
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
        padding: const EdgeInsets.symmetric(vertical: 11),
      ),
      child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
        Icon(icon, size: 15),
        const SizedBox(width: 4),
        Text(label, style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500)),
      ]),
    );
  }

  // ═══════════════════════════════════════════════════════════
  // 工具方法
  // ═══════════════════════════════════════════════════════════

  static void _showFullImage(BuildContext context, String? path) {
    if (path == null) return;
    showDialog(
      context: context,
      builder: (ctx) => Dialog(
        backgroundColor: Colors.black,
        insetPadding: const EdgeInsets.all(24),
        child: Stack(alignment: Alignment.center, children: [
          ClipRRect(borderRadius: BorderRadius.circular(12), child: InteractiveViewer(child: path.startsWith('http')
              ? Image.network(path, fit: BoxFit.contain)
              : Image.file(File(path), fit: BoxFit.contain))),
          Positioned(top: 8, right: 8, child: GestureDetector(
            onTap: () => Navigator.pop(ctx),
            child: Container(padding: const EdgeInsets.all(6), decoration: BoxDecoration(color: Colors.white54, shape: BoxShape.circle), child: const Icon(Icons.close, size: 18)),
          )),
        ]),
      ),
    );
  }

  String _formatTime(DateTime dt) {
    final now = DateTime.now();
    final today = DateTime(now.year, now.month, now.day);
    final thatDay = DateTime(dt.year, dt.month, dt.day);
    if (thatDay == today) {
      return '今天 ${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}';
    }
    if (thatDay == today.subtract(const Duration(days: 1))) {
      return '昨天 ${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}';
    }
    return '${dt.month}/${dt.day} ${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}';
  }

  String _getMetricUnit(String type) {
    switch (type.toLowerCase()) {
      case 'blood_pressure': return 'mmHg';
      case 'heart_rate': return 'bpm';
      case 'glucose': return 'mmol/L';
      case 'spo2': return '%';
      case 'weight': return 'kg';
      default: return '';
    }
  }

  String _getMetricIcon(String type) {
    switch (type.toLowerCase()) {
      case 'blood_pressure': return '🩺';
      case 'heart_rate': return '💓';
      case 'glucose': return '💉';
      case 'spo2': return '🫁';
      case 'weight': return '⚖️';
      default: return '📊';
    }
  }

  String _getMetricName(String type) {
    switch (type.toLowerCase()) {
      case 'blood_pressure': return '血压';
      case 'heart_rate': return '心率';
      case 'glucose': return '血糖';
      case 'spo2': return '血氧';
      case 'weight': return '体重';
      default: return '健康指标';
    }
  }

  static void _medicationCheckIn(WidgetRef ref, BuildContext context) async {
    try {
      final service = ref.read(medicationServiceProvider);
      final reminders = await ref.read(medicationReminderProvider.future);
      if (reminders.isEmpty) {
        if (!context.mounted) return;
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('暂无待服药记录'), backgroundColor: Color(0xFFFF9800)),
        );
        return;
      }
      for (final m in reminders) {
        await service.confirm(m['id']?.toString() ?? '');
      }
      ref.invalidate(medicationReminderProvider);
      if (!context.mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('打卡成功 已记录 ${reminders.length} 项服药'),
          backgroundColor: const Color(0xFF43A047),
        ),
      );
    } catch (e) {
      if (!context.mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('打卡失败：$e'), backgroundColor: Colors.red),
      );
    }
  }

  static _AgentColors _agentColors(ActiveAgent agent) {
    return switch (agent) {
      ActiveAgent.consultation => _AgentColors(
        gradient: [const Color(0xFFC5D5F8), const Color(0xFFA0B8F0), const Color(0xFF7B98E0)],
        bg: const Color(0xFFF0F4FF),
        border: const Color(0xFFD8E0FA),
        iconBg: const Color(0xFFE4ECFC),
        accent: const Color(0xFF7B98E0),
      ),
      ActiveAgent.health => _AgentColors(
        gradient: [const Color(0xFFB8E6CF), const Color(0xFF8ED4AE), const Color(0xFF5FB88D)],
        bg: const Color(0xFFF0FAF4),
        border: const Color(0xFFD0ECD8),
        iconBg: const Color(0xFFE4F8EC),
        accent: const Color(0xFF5FB88D),
      ),
      ActiveAgent.diet => _AgentColors(
        gradient: [const Color(0xFFFFD8B8), const Color(0xFFFFC896), const Color(0xFFF0A060)],
        bg: const Color(0xFFFFF6F0),
        border: const Color(0xFFFFE8D4),
        iconBg: const Color(0xFFFFEEDC),
        accent: const Color(0xFFF0A060),
      ),
      ActiveAgent.medication => _AgentColors(
        gradient: [const Color(0xFFFFD4E0), const Color(0xFFFFB8CC), const Color(0xFFE898A8)],
        bg: const Color(0xFFFFF0F4),
        border: const Color(0xFFFFE0E8),
        iconBg: const Color(0xFFFFE8EE),
        accent: const Color(0xFFE898A8),
      ),
      ActiveAgent.report => _AgentColors(
        gradient: [const Color(0xFFD8D0F0), const Color(0xFFC4B8EC), const Color(0xFFA898D8)],
        bg: const Color(0xFFF8F4FF),
        border: const Color(0xFFECE4F8),
        iconBg: const Color(0xFFF0E8FC),
        accent: const Color(0xFFA898D8),
      ),
      ActiveAgent.exercise => _AgentColors(
        gradient: [const Color(0xFFB8E0E0), const Color(0xFF90D0D0), const Color(0xFF68B4B4)],
        bg: const Color(0xFFF0FAFA),
        border: const Color(0xFFD4ECEC),
        iconBg: const Color(0xFFE4F4F4),
        accent: const Color(0xFF68B4B4),
      ),
      _ => _AgentColors(
        gradient: [const Color(0xFFC5D0F8), const Color(0xFFA0B0F0), const Color(0xFF7B90E0)],
        bg: const Color(0xFFF5F5FF),
        border: const Color(0xFFE0E0F8),
        iconBg: const Color(0xFFEDEDFC),
        accent: const Color(0xFF7B90E0),
      ),
    };
  }

  static (_AgentIcon, String, String) _agentInfo(ActiveAgent agent) {
    return switch (agent) {
      ActiveAgent.health => (Icons.favorite_border, '记数据', '录入血压、血糖、心率等日常指标'),
      ActiveAgent.diet => (Icons.restaurant, '拍饮食', '拍照识别食物热量和营养成分'),
      ActiveAgent.medication => (Icons.medication, '药管家', '管理药品、提醒服药、追踪用量'),
      ActiveAgent.consultation => (Icons.local_hospital, '问诊', '在线咨询医生，描述症状获取建议'),
      ActiveAgent.report => (Icons.assignment, '看报告', '上传体检报告，AI 辅助解读'),
      ActiveAgent.exercise => (Icons.directions_run, '运动', '制定运动计划，打卡记录进度'),
      _ => (Icons.smart_toy, 'AI 助手', '您的智能健康管家'),
    };
  }

  static ActiveAgent _parseAgentFromName(String? name) {
    switch (name) {
      case 'consultation': return ActiveAgent.consultation;
      case 'health': return ActiveAgent.health;
      case 'diet': return ActiveAgent.diet;
      case 'medication': return ActiveAgent.medication;
      case 'report': return ActiveAgent.report;
      case 'exercise': return ActiveAgent.exercise;
      default: return ActiveAgent.default_;
    }
  }

  Widget _buildTaskCardInChat(BuildContext context, WidgetRef ref) {
    final health = ref.watch(latestHealthProvider);
    final reminders = ref.watch(medicationReminderProvider);
    return health.when(
      data: (data) => _taskCardBubble(context, ref, data, reminders),
      loading: () => _taskCardBubble(context, ref, {}, const AsyncValue.loading()),
      error: (_, e) => _taskCardBubble(context, ref, {}, const AsyncValue.loading()),
    );
  }

  Widget _taskCardBubble(BuildContext context, WidgetRef ref, Map<String, dynamic> healthData, AsyncValue<List<Map<String, dynamic>>> reminders) {
    final now = DateTime.now();
    final tasks = <Widget>[];

    // 1. 健康数据摘要行
    final bp = healthData['BloodPressure'];
    final bpText = bp is Map ? '${bp['systolic'] ?? '--'}/${bp['diastolic'] ?? '--'}' : null;
    final hr = healthData['HeartRate'];
    final hrText = hr is int ? '$hr' : null;
    final bs = healthData['BloodSugar'];
    final bsText = bs is num ? '$bs' : null;
    final bo = healthData['BloodOxygen'];
    final boText = bo is num ? '$bo' : null;
    final wt = healthData['Weight'];
    final wtText = wt is num ? '$wt' : null;

    final allNull = bpText == null && hrText == null && bsText == null && boText == null && wtText == null;

    if (!allNull) {
      tasks.add(_taskRow(context, Icons.check_circle, '今日已记录', trailing: [
        if (bpText != null) '血压 $bpText',
        if (hrText != null) '心率 $hrText',
        if (bsText != null) '血糖 $bsText',
        if (boText != null) '血氧 $boText',
        if (wtText != null) '体重 $wtText',
      ].join(' · '), status: 'done', onTap: () => pushRoute(ref, 'trend')));
    }

    // 2. 用药提醒
    reminders.whenOrNull(data: (meds) {
      for (final m in meds) {
        final name = m['name'] ?? '';
        final dosage = m['dosage'] ?? '';
        final times = (m['timeOfDay'] as List?)?.map((t) => t.toString().substring(0, 5)).join(', ') ?? '';
        final medOverdue = now.hour >= 8;
        tasks.add(_taskRow(
          context, Icons.medication_rounded, '$name $dosage ($times)',
          status: medOverdue ? 'overdue' : 'pending',
          onTap: () {},
        ));
      }
    });
    if (tasks.length <= (allNull ? 0 : 1)) {
      tasks.add(_taskRow(context, Icons.medication_rounded, '暂无用药提醒', status: 'pending'));
    }

    // 3. 运动 — 从所有计划中找今日待打卡项
    final plans = ref.read(exerciseServiceProvider).getPlans();
    plans.then((list) {
      for (final p in list) {
        final items = (p['items'] as List?)?.cast<Map<String, dynamic>>() ?? [];
        final today = now.weekday - 1;
        final todayItem = items.cast<Map<String, dynamic>?>().firstWhere(
          (i) => i?['dayOfWeek'] == today, orElse: () => null);
        if (todayItem != null) {
          final done = todayItem['isCompleted'] == true;
          final name = items.isNotEmpty ? (items.first['exerciseType']?.toString() ?? '运动') : '运动';
          final dur = items.isNotEmpty ? (items.first['durationMinutes']?.toString() ?? '30') : '30';
          tasks.add(_taskRow(context, Icons.directions_run,
            '$name $dur分钟',
            status: done ? 'done' : (now.hour >= 18 ? 'overdue' : 'pending'),
            onTap: () => pushRoute(ref, 'exercisePlan'),
          ));
          break;
        }
      }
    });

    // 4. 测量
    tasks.add(_taskRow(
      context, Icons.today, '今日测量：血压',
      status: 'pending',
      onTap: () => pushRoute(ref, 'trend', params: {'type': 'blood_pressure'}),
    ));

    // 5. 异常指标
    if (bp is Map) {
      final s = bp['systolic'];
      if (s is int && s >= 140) {
        tasks.add(_taskRow(
          context, Icons.warning_amber_rounded, '血压 $s/${bp['diastolic'] ?? '--'} 偏高',
          status: 'warning',
          onTap: () => pushRoute(ref, 'trend', params: {'type': 'blood_pressure'}),
        ));
      }
    }

    return Container(
      margin: const EdgeInsets.only(bottom: 12),
      padding: const EdgeInsets.all(14),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(16),
        boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(10), blurRadius: 8, offset: const Offset(0, 2))],
      ),
      child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
        Row(children: [
          Icon(Icons.today, size: 18, color: const Color(0xFF8B9CF7)),
          const SizedBox(width: 8),
          const Text('今日任务', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))),
        ]),
        const SizedBox(height: 10),
        ...tasks,
      ]),
    );
  }

  Widget _taskRow(BuildContext context, IconData icon, String label, {String status = 'pending', String? trailing, VoidCallback? onTap}) {
    final colors = {'done': const Color(0xFF43A047), 'warning': const Color(0xFFFF9800), 'pending': const Color(0xFF9E9E9E), 'overdue': const Color(0xFFE53935)};
    final icons = {'done': Icons.check_circle, 'warning': Icons.warning, 'pending': Icons.circle_outlined, 'overdue': Icons.error};
    final isOverdue = status == 'overdue';
    return Padding(
      padding: const EdgeInsets.only(bottom: 8),
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: onTap,
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
          decoration: BoxDecoration(
            color: isOverdue ? const Color(0xFFFFEBEE) : Colors.transparent,
            borderRadius: BorderRadius.circular(8),
          ),
          child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
            Container(width: 30, height: 30, decoration: BoxDecoration(color: const Color(0xFFF0F2FF), borderRadius: BorderRadius.circular(8)), child: Icon(icon, size: 15, color: const Color(0xFF8B9CF7))),
            const SizedBox(width: 10),
            Expanded(child: Text(trailing ?? label, style: const TextStyle(fontSize: 13, color: Color(0xFF333333)))),
            Icon(icons[status] ?? Icons.circle_outlined, size: 18, color: colors[status] ?? Colors.grey),
          ]),
        ),
      ),
    );
  }
}

// ════════════════════════════════════════════════════════════════
// 内部数据类
// ════════════════════════════════════════════════════════════════

typedef _AgentIcon = IconData;

class _AgentColors {
  final List<Color> gradient;
  final Color bg;
  final Color border;
  final Color iconBg;
  final Color accent;
  const _AgentColors({
    required this.gradient,
    required this.bg,
    required this.border,
    required this.iconBg,
    required this.accent,
  });
}

class _AgentAction {
  final String label;
  final IconData icon;
  final bool isWide;
  final String? route;
  final String? action;

  const _AgentAction({required this.label, required this.icon, this.isWide = false, this.route, this.action});
}

final _agentActions = <ActiveAgent, List<_AgentAction>>{
  ActiveAgent.health: [
    _AgentAction(label: '录入血压', icon: Icons.monitor_heart_outlined, route: 'trend'),
    _AgentAction(label: '录入血糖', icon: Icons.bloodtype_outlined, route: 'trend'),
    _AgentAction(label: '录入心率', icon: Icons.favorite_border, route: 'trend'),
    _AgentAction(label: '录入血氧', icon: Icons.air_outlined, route: 'trend'),
    _AgentAction(label: '录入体重', icon: Icons.monitor_weight_outlined, route: 'trend'),
  ],
  ActiveAgent.diet: [
    _AgentAction(label: '拍照识别', icon: Icons.camera_alt_outlined, isWide: true, route: 'dietCapture'),
    _AgentAction(label: '上传照片', icon: Icons.photo_library_outlined, isWide: true, route: 'dietCapture'),
  ],
  ActiveAgent.medication: [
    _AgentAction(label: '用药管理', icon: Icons.medication_liquid_outlined, isWide: true, route: 'medications'),
    _AgentAction(label: '服药打卡', icon: Icons.check_circle_outline, isWide: true),
  ],
  ActiveAgent.consultation: [],
  ActiveAgent.report: [
    _AgentAction(label: '上传报告', icon: Icons.upload_file_outlined, isWide: true, route: 'reports'),
    _AgentAction(label: '查看历史', icon: Icons.history_outlined, isWide: true, route: 'reports'),
  ],
  ActiveAgent.exercise: [
    _AgentAction(label: '查看计划', icon: Icons.calendar_month_outlined, isWide: true, route: 'exercisePlan'),
    _AgentAction(label: '新建计划', icon: Icons.add_task_outlined, isWide: true, route: 'exerciseCreate'),
  ],
};

extension _AgentActionsExt on ActiveAgent {
  List<_AgentAction> get actions => _agentActions[this] ?? [const _AgentAction(label: '开始对话', icon: Icons.chat_outlined)];
}

// ════════════════════════════════════════════════════════════════
// 可展开的 AI 建议小组件
// ════════════════════════════════════════════════════════════════

class _ExpandableAdvice extends StatefulWidget {
  final String advice;
  const _ExpandableAdvice({required this.advice});

  @override
  State<_ExpandableAdvice> createState() => _ExpandableAdviceState();
}

class _ExpandableAdviceState extends State<_ExpandableAdvice> {
  bool _expanded = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => setState(() => _expanded = !_expanded),
      child: Container(
        width: double.infinity,
        padding: const EdgeInsets.all(14),
        decoration: BoxDecoration(
          color: const Color(0xFFF7F5FF),
          borderRadius: BorderRadius.circular(12),
          border: Border.all(color: const Color(0xFFE8E4FF), width: 0.8),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                const Icon(Icons.lightbulb_outline, size: 16, color: Color(0xFF8B9CF7)),
                const SizedBox(width: 6),
                const Text('AI 建议', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF8B9CF7))),
                const Spacer(),
                Icon(_expanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, size: 18, color: const Color(0xFFAAAAAA)),
              ],
            ),
            if (_expanded) ...[
              const SizedBox(height: 10),
              Text(widget.advice, style: const TextStyle(fontSize: 13, color: Color(0xFF555555), height: 1.6)),
            ],
          ],
        ),
      ),
    );
  }

}
