import 'dart:convert';
import 'dart:async';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:image_picker/image_picker.dart';
import '../../core/app_colors.dart';
import '../../core/app_design_tokens.dart';
import '../../core/app_module_visuals.dart';
import '../../core/app_theme.dart';
import '../../core/api_client.dart' show baseUrl;
import '../../core/navigation_provider.dart';
import '../../providers/auth_provider.dart';
import '../../widgets/common_widgets.dart';
import '../../widgets/enterprise_widgets.dart';

final reportProvider = NotifierProvider<ReportNotifier, ReportState>(
  ReportNotifier.new,
);

Duration? reportAnalysisPollDelay(int attempt) {
  if (attempt > 15) return null;
  if (attempt <= 2) return const Duration(seconds: 4);
  if (attempt <= 5) return const Duration(seconds: 8);
  return const Duration(seconds: 12);
}

class ReportState {
  final List<ReportItem> reports;
  final String? uploadingImage;
  final bool isAnalyzing;
  final ReportAnalysis? currentAnalysis;
  final String? uploadError;

  ReportState({
    this.reports = const [],
    this.uploadingImage,
    this.isAnalyzing = false,
    this.currentAnalysis,
    this.uploadError,
  });

  ReportState copyWith({
    List<ReportItem>? reports,
    String? uploadingImage,
    bool? isAnalyzing,
    ReportAnalysis? currentAnalysis,
    String? uploadError,
    bool clearUploadingImage = false,
    bool clearCurrentAnalysis = false,
    bool clearUploadError = false,
  }) {
    return ReportState(
      reports: reports ?? this.reports,
      uploadingImage: clearUploadingImage
          ? null
          : uploadingImage ?? this.uploadingImage,
      isAnalyzing: isAnalyzing ?? this.isAnalyzing,
      currentAnalysis: clearCurrentAnalysis
          ? null
          : currentAnalysis ?? this.currentAnalysis,
      uploadError: clearUploadError ? null : uploadError ?? this.uploadError,
    );
  }
}

class ReportItem {
  final String id;
  final String title;
  final String type;
  final DateTime uploadedAt;
  final String? fileUrl;
  final bool hasAnalysis;
  final String status; // Legacy combined status from backend.
  final String aiStatus; // Analyzing | Succeeded | Failed
  final String reviewStatus; // Pending | Reviewed
  final String? analysisSummary;
  final String? severity; // Normal | Abnormal | Severe | Critical
  final String? doctorComment;
  final String? doctorRecommendation;
  final String? doctorName;
  final DateTime? reviewedAt;

  ReportItem({
    required this.id,
    required this.title,
    required this.type,
    required this.uploadedAt,
    this.fileUrl,
    this.hasAnalysis = false,
    this.status = 'PendingDoctor',
    this.aiStatus = 'Analyzing',
    this.reviewStatus = 'Pending',
    this.analysisSummary,
    this.severity,
    this.doctorComment,
    this.doctorRecommendation,
    this.doctorName,
    this.reviewedAt,
  });
}

class ReportAnalysis {
  final String reportId;
  final String reportType;
  final List<Indicator> indicators;
  final String summary;
  final String status;
  final String aiStatus;
  final String reviewStatus;
  final String? fileUrl;

  ReportAnalysis({
    required this.reportId,
    required this.reportType,
    required this.indicators,
    required this.summary,
    this.status = 'PendingDoctor',
    this.aiStatus = 'Analyzing',
    this.reviewStatus = 'Pending',
    this.fileUrl,
  });
}

class Indicator {
  final String name;
  final String value;
  final String unit;
  final String status;
  final String? referenceRange;

  Indicator({
    required this.name,
    required this.value,
    required this.unit,
    required this.status,
    this.referenceRange,
  });
}

class ReportNotifier extends Notifier<ReportState> {
  Timer? _pollTimer;
  int _pollAttempt = 0;

  @override
  ReportState build() {
    ref.onDispose(() => _pollTimer?.cancel());
    Future.microtask(() => loadReports());
    return ReportState();
  }

  Future<void> loadReports() async {
    try {
      final api = ref.read(apiClientProvider);
      final res = await api.get('/api/reports');
      final list = (res.data['data'] as List?) ?? [];
      final reports = list.map((r) {
        final m = r as Map<String, dynamic>;
        final rawTitle = m['title']?.toString() ?? '';
        final rawCat = m['category']?.toString() ?? '';
        final title =
            rawTitle.isNotEmpty && rawTitle != 'Other' && rawTitle != 'other'
            ? rawTitle
            : _catTitle(rawCat);
        return ReportItem(
          id: m['id']?.toString() ?? '',
          title: title,
          type: m['fileType']?.toString() ?? 'Image',
          uploadedAt:
              DateTime.tryParse(m['createdAt']?.toString() ?? '') ??
              DateTime.now(),
          fileUrl: m['fileUrl']?.toString(),
          hasAnalysis: m['aiSummary'] != null,
          status: m['status']?.toString() ?? 'PendingDoctor',
          aiStatus: m['aiStatus']?.toString() ?? _deriveAiStatus(m),
          reviewStatus: m['reviewStatus']?.toString() ?? _deriveReviewStatus(m),
          analysisSummary: m['aiSummary']?.toString(),
          severity: m['severity']?.toString(),
          doctorComment: m['doctorComment']?.toString(),
          doctorRecommendation: m['doctorRecommendation']?.toString(),
          doctorName: m['doctorName']?.toString(),
          reviewedAt: DateTime.tryParse(m['reviewedAt']?.toString() ?? ''),
        );
      }).toList();
      state = state.copyWith(reports: reports);
      _syncAnalysisPolling(reports);
    } catch (e) {
      debugPrint('[Report] 加载报告列表失败: $e');
    }
  }

  void _syncAnalysisPolling(List<ReportItem> reports) {
    final hasAnalyzing = reports.any((r) => r.aiStatus == 'Analyzing');
    if (!hasAnalyzing) {
      _pollTimer?.cancel();
      _pollTimer = null;
      _pollAttempt = 0;
      return;
    }
    if (_pollTimer != null) return;
    final delay = reportAnalysisPollDelay(++_pollAttempt);
    if (delay == null) return;
    _pollTimer = Timer(delay, () {
      _pollTimer = null;
      loadReports();
    });
  }

  void fetchReportDetail(String reportId) async {
    try {
      final api = ref.read(apiClientProvider);
      final res = await api.get('/api/reports/$reportId');
      final m = (res.data['data'] as Map<String, dynamic>?) ?? {};
      if (m.isEmpty) {
        state = state.copyWith(currentAnalysis: _emptyAnalysis(reportId));
        return;
      }
      final indicators = _parseIndicators(m['aiIndicators']?.toString());
      final rawTitle = m['title']?.toString() ?? '';
      final rawCat = m['category']?.toString() ?? '';
      final displayType = rawTitle.isNotEmpty && rawTitle != 'Other'
          ? rawTitle
          : _catTitle(rawCat);
      final analysis = ReportAnalysis(
        reportId: m['id']?.toString() ?? reportId,
        reportType: displayType,
        indicators: indicators,
        summary: m['aiSummary']?.toString() ?? '',
        status: m['status']?.toString() ?? 'PendingDoctor',
        aiStatus: m['aiStatus']?.toString() ?? _deriveAiStatus(m),
        reviewStatus: m['reviewStatus']?.toString() ?? _deriveReviewStatus(m),
        fileUrl: m['fileUrl']?.toString(),
      );
      state = state.copyWith(currentAnalysis: analysis);
    } catch (_) {
      state = state.copyWith(currentAnalysis: _emptyAnalysis(reportId));
    }
  }

  ReportAnalysis _emptyAnalysis(String reportId) => ReportAnalysis(
    reportId: reportId,
    reportType: '检查报告',
    indicators: [],
    summary: '暂无数据，请下拉刷新重试',
    status: 'AnalysisFailed',
    aiStatus: 'Failed',
    reviewStatus: 'Pending',
  );

  String _deriveAiStatus(Map<String, dynamic> m) {
    final status = m['status']?.toString();
    if (status == 'Analyzing') return 'Analyzing';
    if (status == 'AnalysisFailed') return 'Failed';
    return m['aiSummary'] != null ? 'Succeeded' : 'Analyzing';
  }

  String _deriveReviewStatus(Map<String, dynamic> m) =>
      m['status']?.toString() == 'DoctorReviewed' ? 'Reviewed' : 'Pending';

  List<Indicator> _parseIndicators(String? jsonStr) {
    if (jsonStr == null || jsonStr.isEmpty) return [];
    try {
      final list = jsonDecode(jsonStr) as List;
      return list.map((item) {
        final m = item as Map<String, dynamic>;
        return Indicator(
          name: m['name']?.toString() ?? '',
          value: m['value']?.toString() ?? '',
          unit: m['unit']?.toString() ?? '',
          status: m['status']?.toString() ?? 'normal',
          referenceRange: m['referenceRange']?.toString(),
        );
      }).toList();
    } catch (_) {
      return [];
    }
  }

  void uploadImage(String path) async {
    state = state.copyWith(
      uploadingImage: path,
      isAnalyzing: true,
      clearUploadError: true,
    );
    try {
      final api = ref.read(apiClientProvider);
      final file = File(path);
      final formData = FormData.fromMap({
        'file': await MultipartFile.fromFile(
          file.path,
          filename: file.path.split('/').last,
        ),
      });
      // 直接上传到报告端点，后端自动触发 VLM+LLM 分析
      final createRes = await api.dio.post('/api/reports', data: formData);
      final data = createRes.data;
      if (data is Map && data['code'] != 0) {
        final message = data['message']?.toString() ?? '上传失败，请稍后重试';
        state = state.copyWith(
          isAnalyzing: false,
          clearUploadingImage: true,
          uploadError: message,
        );
        return;
      }
      state = state.copyWith(
        isAnalyzing: false,
        clearUploadingImage: true,
        clearUploadError: true,
      );
      loadReports();
    } catch (e) {
      debugPrint('[Report] 上传失败: $e');
      state = state.copyWith(
        isAnalyzing: false,
        clearUploadingImage: true,
        uploadError: '上传失败，请检查网络或文件格式后重试',
      );
    }
  }

  void uploadFile(String path) => uploadImage(path);

  void viewAnalysis(String reportId) {
    fetchReportDetail(reportId);
  }

  Future<void> deleteReport(String id) async {
    try {
      await ref.read(apiClientProvider).delete('/api/reports/$id');
      loadReports();
    } catch (e) {
      debugPrint('[Report] 删除失败: $e');
    }
  }

  Future<void> reanalyzeReport(String id) async {
    try {
      final res = await ref
          .read(apiClientProvider)
          .post('/api/reports/$id/reanalyze');
      final data = res.data;
      if (data is Map && data['code'] != 0) {
        state = state.copyWith(
          uploadError: data['message']?.toString() ?? '重新分析失败',
        );
        return;
      }
      state = state.copyWith(
        clearCurrentAnalysis: true,
        clearUploadError: true,
      );
      await loadReports();
      fetchReportDetail(id);
    } catch (e) {
      debugPrint('[Report] 重新分析失败: $e');
      state = state.copyWith(uploadError: '重新分析失败，请稍后重试');
    }
  }

  void clearAnalysis() {
    state = state.copyWith(clearCurrentAnalysis: true);
  }
}

/// 报告列表页
class ReportListPage extends ConsumerWidget {
  const ReportListPage({super.key});

  static const _reportVisual = AppModuleVisuals.report;
  static const _reportBlue = AppColors.report;
  static const _reportCyan = Color(0xFF60A5FA);

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

    if (state.isAnalyzing) {
      return GradientScaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: const Icon(Icons.arrow_back),
            onPressed: () => popRoute(ref),
          ),
          title: const Text('报告管理'),
        ),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const CircularProgressIndicator(color: _reportBlue),
              const SizedBox(height: 16),
              Text(
                state.uploadingImage == null ? 'AI 正在分析报告...' : '正在上传报告...',
                style: const TextStyle(
                  fontSize: 16,
                  color: AppColors.textSecondary,
                ),
              ),
            ],
          ),
        ),
      );
    }

    return GradientScaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () => popRoute(ref),
        ),
        title: const Text('报告管理'),
        centerTitle: true,
      ),
      floatingActionButton: _buildUploadButton(context, ref),
      body: RefreshIndicator(
        onRefresh: () async => ref.read(reportProvider.notifier).loadReports(),
        child: ListView(
          padding: const EdgeInsets.all(16),
          children: [
            EnterpriseHeader(
              title: '报告处理概览',
              subtitle: '上传检查报告后自动进行 AI 结构化解读',
              icon: _reportVisual.icon,
              color: _reportBlue,
              accent: _reportCyan,
              showIcon: false,
              stats: [
                EnterpriseStat(
                  label: '报告总数',
                  value: '${state.reports.length} 份',
                  icon: Icons.folder_copy_outlined,
                ),
                EnterpriseStat(
                  label: '待处理',
                  value:
                      '${state.reports.where((r) => r.aiStatus == 'Analyzing' || r.reviewStatus != 'Reviewed').length} 份',
                  icon: Icons.pending_actions_outlined,
                ),
              ],
            ),
            const SizedBox(height: 10),
            if (state.uploadError != null) ...[
              _buildUploadError(state.uploadError!),
              const SizedBox(height: 12),
            ],
            if (state.reports.isEmpty)
              _buildEmptyState(context)
            else
              _ReportListGroup(
                children: [
                  for (var i = 0; i < state.reports.length; i++)
                    SwipeDeleteTile(
                      key: Key(state.reports[i].id),
                      onDelete: () => ref
                          .read(reportProvider.notifier)
                          .deleteReport(state.reports[i].id),
                      onTap: () => pushRoute(
                        ref,
                        'aiAnalysis',
                        params: {'id': state.reports[i].id},
                      ),
                      margin: EdgeInsets.zero,
                      child: _buildReportRow(
                        state.reports[i],
                        showDivider: i < state.reports.length - 1,
                      ),
                    ),
                ],
              ),
          ],
        ),
      ),
    );
  }

  Widget _buildUploadError(String message) {
    return Container(
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: AppColors.error.withValues(alpha: 0.08),
        borderRadius: AppRadius.mdBorder,
        border: Border.all(color: AppColors.error.withValues(alpha: 0.22)),
      ),
      child: Row(
        children: [
          const Icon(Icons.error_outline, color: AppColors.error, size: 20),
          const SizedBox(width: 8),
          Expanded(
            child: Text(
              message,
              style: const TextStyle(
                fontSize: 14,
                color: AppColors.error,
                fontWeight: FontWeight.w600,
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildUploadButton(BuildContext context, WidgetRef ref) {
    return FloatingActionButton(
      onPressed: () => _showUploadOptions(context, ref),
      backgroundColor: _reportBlue,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
      child: const Icon(Icons.add, size: 28, color: Colors.white),
    );
  }

  void _showUploadOptions(BuildContext context, WidgetRef ref) {
    showModalBottomSheet(
      context: context,
      backgroundColor: Colors.white,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      builder: (ctx) => SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 8),
          child: Wrap(
            children: [
              ListTile(
                leading: const Icon(
                  Icons.camera_alt_outlined,
                  color: _reportBlue,
                ),
                title: const Text('拍照上传', style: TextStyle(fontSize: 17)),
                onTap: () async {
                  Navigator.pop(ctx);
                  final picker = ImagePicker();
                  final picked = await picker.pickImage(
                    source: ImageSource.camera,
                    imageQuality: 85,
                  );
                  if (picked != null) {
                    ref.read(reportProvider.notifier).uploadImage(picked.path);
                  }
                },
              ),
              ListTile(
                leading: const Icon(
                  Icons.photo_library_outlined,
                  color: _reportCyan,
                ),
                title: const Text('从相册选择', style: TextStyle(fontSize: 17)),
                onTap: () async {
                  Navigator.pop(ctx);
                  final picker = ImagePicker();
                  final picked = await picker.pickImage(
                    source: ImageSource.gallery,
                    imageQuality: 85,
                  );
                  if (picked != null) {
                    ref.read(reportProvider.notifier).uploadImage(picked.path);
                  }
                },
              ),
              ListTile(
                leading: const Icon(
                  Icons.picture_as_pdf_outlined,
                  color: _reportBlue,
                ),
                title: const Text('上传 PDF', style: TextStyle(fontSize: 17)),
                onTap: () async {
                  Navigator.pop(ctx);
                  final result = await FilePicker.platform.pickFiles(
                    type: FileType.custom,
                    allowedExtensions: ['pdf'],
                    withData: false,
                  );
                  if (result == null || result.files.isEmpty) return;
                  final path = result.files.first.path;
                  if (path == null || path.isEmpty) return;
                  ref.read(reportProvider.notifier).uploadFile(path);
                },
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildEmptyState(BuildContext context) {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Container(
            width: 100,
            height: 100,
            decoration: BoxDecoration(
              color: _reportBlue.withValues(alpha: 0.08),
              borderRadius: AppRadius.pillBorder,
            ),
            child: Icon(_reportVisual.icon, size: 44, color: _reportBlue),
          ),
          const SizedBox(height: 20),
          const Text(
            '暂无检查报告',
            style: TextStyle(
              fontSize: 20,
              fontWeight: FontWeight.w500,
              color: AppColors.textPrimary,
            ),
          ),
          const SizedBox(height: 8),
          const Text(
            '点击右下角按钮上传报告',
            style: TextStyle(fontSize: 16, color: AppColors.textHint),
          ),
        ],
      ),
    );
  }

  Widget _buildReportRow(ReportItem report, {required bool showDivider}) {
    final displayTitle = (report.title == 'Other' || report.title == 'other')
        ? '检查报告'
        : report.title;
    return Material(
      color: Colors.white,
      child: InkWell(
        child: Column(
          children: [
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 13),
              child: Row(
                children: [
                  Container(
                    width: 44,
                    height: 44,
                    decoration: BoxDecoration(
                      color: _reportBlue.withValues(alpha: 0.10),
                      borderRadius: AppRadius.mdBorder,
                    ),
                    child: Icon(
                      _reportVisual.icon,
                      size: 24,
                      color: _reportBlue,
                    ),
                  ),
                  const SizedBox(width: 13),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          displayTitle,
                          maxLines: 1,
                          overflow: TextOverflow.ellipsis,
                          style: AppTextStyles.listTitle.copyWith(
                            fontWeight: FontWeight.w800,
                          ),
                        ),
                        const SizedBox(height: 3),
                        Text(
                          _formatDate(report.uploadedAt),
                          style: AppTextStyles.listSubtitle,
                        ),
                        if (report.aiStatus == 'Failed') ...[
                          const SizedBox(height: 4),
                          Text(
                            _failureSummary(report),
                            maxLines: 2,
                            overflow: TextOverflow.ellipsis,
                            style: const TextStyle(
                              fontSize: 13,
                              height: 1.35,
                              color: AppColors.error,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                        ],
                      ],
                    ),
                  ),
                  const SizedBox(width: 8),
                  _buildStatusBadge(report),
                  const SizedBox(width: 8),
                  const Icon(
                    Icons.chevron_right,
                    size: 21,
                    color: AppColors.textHint,
                  ),
                ],
              ),
            ),
            if (showDivider)
              const Padding(
                padding: EdgeInsets.only(left: 71),
                child: Divider(
                  height: 1,
                  thickness: 0.7,
                  color: Color(0xFFE8ECF2),
                ),
              ),
          ],
        ),
      ),
    );
  }

  Widget _buildStatusBadge(ReportItem report) {
    final (label, bg, fg) = switch (report.status) {
      _ when report.reviewStatus == 'Reviewed' => (
        '已审核',
        AppColors.successLight,
        AppColors.success,
      ),
      _ when report.aiStatus == 'Analyzing' => (
        '分析中',
        _reportBlue.withValues(alpha: 0.08),
        _reportBlue,
      ),
      _ when report.aiStatus == 'Failed' => (
        '分析失败',
        AppColors.error.withValues(alpha: 0.08),
        AppColors.error,
      ),
      _ when report.aiStatus == 'Succeeded' => (
        '待审核',
        AppColors.warningLight,
        AppColors.warning,
      ),
      _ => ('分析中', _reportBlue.withValues(alpha: 0.08), _reportBlue),
    };

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
      decoration: BoxDecoration(
        color: bg,
        borderRadius: AppRadius.pillBorder,
        border: Border.all(color: fg.withValues(alpha: 0.12)),
      ),
      child: Text(
        label,
        style: TextStyle(fontSize: 13, color: fg, fontWeight: FontWeight.w700),
      ),
    );
  }

  String _failureSummary(ReportItem report) {
    final summary = report.analysisSummary?.trim();
    if (summary != null && summary.isNotEmpty) {
      return summary;
    }
    return 'AI 暂时无法解读，请稍后重试或重新上传清晰图片';
  }

  String _formatDate(DateTime date) {
    final now = DateTime.now();
    final diff = now.difference(date);
    if (diff.inDays == 0) return '今天';
    if (diff.inDays == 1) return '昨天';
    if (diff.inDays < 7) return '${diff.inDays}天前';
    return '${date.month}月${date.day}日';
  }
}

class _ReportListGroup extends StatelessWidget {
  final List<Widget> children;

  const _ReportListGroup({required this.children});

  @override
  Widget build(BuildContext context) {
    return Container(
      clipBehavior: Clip.antiAlias,
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: AppRadius.xlBorder,
      ),
      child: Column(children: children),
    );
  }
}

String _catTitle(String c) => switch (c) {
  'BloodTest' => '抽血化验单',
  'Biochemistry' => '生化检验报告',
  'Ecg' => '心电图报告',
  'Ultrasound' => '超声检查报告',
  'Discharge' => '出院小结',
  'Image' => '影像检查报告',
  _ => '检查报告',
};

class ReportOriginalPage extends ConsumerWidget {
  final String url;
  final String title;

  const ReportOriginalPage({super.key, required this.url, this.title = '原始报告'});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final imageUrl = _absoluteUrl(url);
    return GradientScaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () => popRoute(ref),
        ),
        title: Text(title),
      ),
      body: Center(
        child: InteractiveViewer(
          minScale: 0.7,
          maxScale: 4,
          child: Image.network(
            imageUrl,
            fit: BoxFit.contain,
            errorBuilder: (_, _, _) => const Padding(
              padding: EdgeInsets.all(24),
              child: Text(
                '原始报告图片加载失败',
                style: TextStyle(color: AppColors.textSecondary),
              ),
            ),
          ),
        ),
      ),
    );
  }

  String _absoluteUrl(String value) {
    if (value.startsWith('http://') || value.startsWith('https://')) {
      return value;
    }
    if (value.startsWith('/')) {
      return '$baseUrl$value';
    }
    return '$baseUrl/$value';
  }
}
