import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../core/app_colors.dart';
import '../../core/app_theme.dart';
import '../../core/navigation_provider.dart';
import '../../providers/auth_provider.dart';
import '../../providers/data_providers.dart';
import '../../widgets/app_empty_state.dart';
import '../../widgets/app_error_state.dart';
import '../../widgets/app_toast.dart';

class MedicationCheckInPage extends ConsumerStatefulWidget {
  final String? medId;

  const MedicationCheckInPage({super.key, this.medId});

  @override
  ConsumerState<MedicationCheckInPage> createState() =>
      _MedicationCheckInPageState();
}

class _MedicationCheckInPageState extends ConsumerState<MedicationCheckInPage> {
  static const _medBlue = Color(0xFF60A5FA);
  static const _medViolet = Color(0xFF8B5CF6);
  static const _softGreen = Color(0xFFEAF8EF);

  Future<List<Map<String, dynamic>>>? _future;
  final Set<String> _busyDoses = {};

  @override
  void initState() {
    super.initState();
    _load();
  }

  void _load() {
    setState(() {
      _future = ref.read(medicationReminderProvider.future);
    });
  }

  Future<void> _refresh() async {
    ref.invalidate(medicationReminderProvider);
    _load();
    await _future;
  }

  Future<void> _toggleDose(String medId, String time, bool taken) async {
    final doseKey = '$medId-$time';
    if (_busyDoses.contains(doseKey)) return;

    setState(() => _busyDoses.add(doseKey));
    try {
      final api = ref.read(apiClientProvider);
      if (taken) {
        await api.delete('/api/medications/$medId/confirm-dose/$time');
      } else {
        await api.post(
          '/api/medications/$medId/confirm-dose',
          data: {'scheduledTime': time, 'status': 'taken'},
        );
      }
      ref.invalidate(medicationReminderProvider);
      ref.invalidate(medicationListProvider);
      _load();
    } catch (e) {
      debugPrint('[MedCheckIn] 打卡失败: $e');
      if (mounted) {
        AppToast.show(
          context,
          '打卡失败，请稍后重试',
          type: AppToastType.error,
        );
      }
    } finally {
      if (mounted) setState(() => _busyDoses.remove(doseKey));
    }
  }

  @override
  Widget build(BuildContext context) {
    return GradientScaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () => popRoute(ref),
        ),
        title: const Text('服药打卡'),
        centerTitle: true,
      ),
      body: FutureBuilder<List<Map<String, dynamic>>>(
        future: _future,
        builder: (ctx, snap) {
          if (snap.connectionState == ConnectionState.waiting &&
              !snap.hasData) {
            return const Center(
              child: CircularProgressIndicator(color: AppTheme.primary),
            );
          }
          if (snap.hasError) {
            return AppErrorState(title: '用药信息加载失败', onRetry: _load);
          }

          final reminders = _filterReminders(snap.data ?? []);
          if (reminders.isEmpty) {
            return RefreshIndicator(
              onRefresh: _refresh,
              child: ListView(
                physics: const AlwaysScrollableScrollPhysics(),
                children: const [
                  SizedBox(height: 92),
                  AppEmptyState(
                    icon: Icons.task_alt_outlined,
                    title: '今天的用药已完成',
                    subtitle: '下拉可刷新最新用药提醒',
                  ),
                ],
              ),
            );
          }

          final grouped = _groupByMedication(reminders);
          final total = reminders.length;
          final taken = reminders.where(_isTaken).length;
          final pending = total - taken;

          return RefreshIndicator(
            onRefresh: _refresh,
            child: ListView(
              physics: const AlwaysScrollableScrollPhysics(),
              padding: const EdgeInsets.fromLTRB(16, 12, 16, 28),
              children: [
                _CheckInSummary(total: total, taken: taken, pending: pending),
                const SizedBox(height: 14),
                ...grouped.entries.map(
                  (entry) => _MedicationDoseCard(
                    name: entry.key,
                    doses: entry.value,
                    busyDoses: _busyDoses,
                    onToggle: _toggleDose,
                  ),
                ),
              ],
            ),
          );
        },
      ),
    );
  }

  List<Map<String, dynamic>> _filterReminders(
    List<Map<String, dynamic>> reminders,
  ) {
    if (widget.medId == null) return reminders;
    return reminders.where((r) => r['id']?.toString() == widget.medId).toList();
  }

  Map<String, List<Map<String, dynamic>>> _groupByMedication(
    List<Map<String, dynamic>> reminders,
  ) {
    final grouped = <String, List<Map<String, dynamic>>>{};
    for (final reminder in reminders) {
      final name = reminder['name']?.toString().trim();
      grouped
          .putIfAbsent(name?.isNotEmpty == true ? name! : '未命名药品', () {
            return <Map<String, dynamic>>[];
          })
          .add(reminder);
    }

    for (final doses in grouped.values) {
      doses.sort(
        (a, b) => _formatTime(
          a['scheduledTime']?.toString() ?? '',
        ).compareTo(_formatTime(b['scheduledTime']?.toString() ?? '')),
      );
    }
    return grouped;
  }
}

class _CheckInSummary extends StatelessWidget {
  final int total;
  final int taken;
  final int pending;

  const _CheckInSummary({
    required this.total,
    required this.taken,
    required this.pending,
  });

  @override
  Widget build(BuildContext context) {
    final progress = total == 0 ? 0.0 : taken / total;

    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(16),
        border: Border.all(color: AppColors.border, width: 1.1),
        boxShadow: [AppTheme.shadowLight],
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Container(
                width: 42,
                height: 42,
                decoration: BoxDecoration(
                  gradient: const LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                    colors: [
                      _MedicationCheckInPageState._medBlue,
                      _MedicationCheckInPageState._medViolet,
                    ],
                  ),
                  borderRadius: BorderRadius.circular(14),
                ),
                child: const Icon(
                  Icons.medication_outlined,
                  color: Colors.white,
                  size: 24,
                ),
              ),
              const SizedBox(width: 12),
              const Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      '今日服药进度',
                      style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.w800,
                        color: AppColors.textPrimary,
                      ),
                    ),
                    SizedBox(height: 2),
                    Text(
                      '按提醒时间逐项确认，保持用药节奏',
                      style: TextStyle(
                        fontSize: 13,
                        color: AppColors.textSecondary,
                      ),
                    ),
                  ],
                ),
              ),
              Text(
                '${(progress * 100).round()}%',
                style: const TextStyle(
                  fontSize: 22,
                  fontWeight: FontWeight.w900,
                  color: _MedicationCheckInPageState._medViolet,
                ),
              ),
            ],
          ),
          const SizedBox(height: 16),
          ClipRRect(
            borderRadius: BorderRadius.circular(999),
            child: LinearProgressIndicator(
              minHeight: 9,
              value: progress,
              backgroundColor: AppColors.cardInner,
              valueColor: const AlwaysStoppedAnimation<Color>(
                _MedicationCheckInPageState._medBlue,
              ),
            ),
          ),
          const SizedBox(height: 14),
          Row(
            children: [
              Expanded(
                child: _SummaryStat(
                  label: '待完成',
                  value: '$pending',
                  icon: Icons.schedule_outlined,
                  color: AppColors.warning,
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: _SummaryStat(
                  label: '已打卡',
                  value: '$taken',
                  icon: Icons.check_circle_outline,
                  color: AppTheme.success,
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: _SummaryStat(
                  label: '总次数',
                  value: '$total',
                  icon: Icons.format_list_numbered_outlined,
                  color: _MedicationCheckInPageState._medViolet,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class _SummaryStat extends StatelessWidget {
  final String label;
  final String value;
  final IconData icon;
  final Color color;

  const _SummaryStat({
    required this.label,
    required this.value,
    required this.icon,
    required this.color,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      constraints: const BoxConstraints(minHeight: 58),
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 9),
      decoration: BoxDecoration(
        color: color.withValues(alpha: 0.08),
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: color.withValues(alpha: 0.14)),
      ),
      child: Row(
        children: [
          Icon(icon, color: color, size: 17),
          const SizedBox(width: 7),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  value,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: const TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.w800,
                    color: AppColors.textPrimary,
                  ),
                ),
                Text(
                  label,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: const TextStyle(
                    fontSize: 11,
                    fontWeight: FontWeight.w700,
                    color: AppColors.textSecondary,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class _MedicationDoseCard extends StatelessWidget {
  final String name;
  final List<Map<String, dynamic>> doses;
  final Set<String> busyDoses;
  final Future<void> Function(String medId, String time, bool taken) onToggle;

  const _MedicationDoseCard({
    required this.name,
    required this.doses,
    required this.busyDoses,
    required this.onToggle,
  });

  @override
  Widget build(BuildContext context) {
    final dosage = doses.first['dosage']?.toString().trim() ?? '';
    final takenCount = doses.where(_isTaken).length;
    final allTaken = takenCount == doses.length;

    return Container(
      margin: const EdgeInsets.only(bottom: 12),
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(16),
        border: Border.all(
          color: allTaken
              ? AppTheme.success.withValues(alpha: 0.26)
              : AppColors.border,
          width: 1.1,
        ),
        boxShadow: [AppTheme.shadowLight],
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Container(
                width: 44,
                height: 44,
                decoration: BoxDecoration(
                  color: allTaken
                      ? _MedicationCheckInPageState._softGreen
                      : AppColors.infoLight,
                  borderRadius: BorderRadius.circular(14),
                  border: Border.all(color: AppColors.borderLight),
                ),
                child: Icon(
                  allTaken ? Icons.done_all_rounded : Icons.medication_liquid,
                  color: allTaken
                      ? AppTheme.success
                      : _MedicationCheckInPageState._medBlue,
                  size: 24,
                ),
              ),
              const SizedBox(width: 12),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      name,
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      style: const TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.w800,
                        color: AppColors.textPrimary,
                      ),
                    ),
                    if (dosage.isNotEmpty) ...[
                      const SizedBox(height: 2),
                      Text(
                        dosage,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        style: const TextStyle(
                          fontSize: 14,
                          color: AppColors.textSecondary,
                        ),
                      ),
                    ],
                  ],
                ),
              ),
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 9, vertical: 5),
                decoration: BoxDecoration(
                  color: allTaken
                      ? _MedicationCheckInPageState._softGreen
                      : AppColors.cardInner,
                  borderRadius: BorderRadius.circular(999),
                ),
                child: Text(
                  '$takenCount/${doses.length}',
                  style: TextStyle(
                    fontSize: 13,
                    fontWeight: FontWeight.w800,
                    color: allTaken
                        ? AppTheme.success
                        : AppColors.textSecondary,
                  ),
                ),
              ),
            ],
          ),
          const SizedBox(height: 14),
          for (var i = 0; i < doses.length; i++) ...[
            _DoseRow(
              dose: doses[i],
              isLast: i == doses.length - 1,
              isBusy: busyDoses.contains(
                '${doses[i]['id']?.toString() ?? ''}-${doses[i]['scheduledTime']?.toString() ?? ''}',
              ),
              onToggle: onToggle,
            ),
          ],
        ],
      ),
    );
  }
}

class _DoseRow extends StatelessWidget {
  final Map<String, dynamic> dose;
  final bool isLast;
  final bool isBusy;
  final Future<void> Function(String medId, String time, bool taken) onToggle;

  const _DoseRow({
    required this.dose,
    required this.isLast,
    required this.isBusy,
    required this.onToggle,
  });

  @override
  Widget build(BuildContext context) {
    final time = dose['scheduledTime']?.toString() ?? '';
    final medId = dose['id']?.toString() ?? '';
    final isTaken = _isTaken(dose);
    final displayTime = _formatTime(time);
    final statusColor = isTaken ? AppTheme.success : AppColors.warning;

    return IntrinsicHeight(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          SizedBox(
            width: 28,
            child: Column(
              children: [
                Container(
                  width: 22,
                  height: 22,
                  decoration: BoxDecoration(
                    color: isTaken ? AppTheme.success : Colors.white,
                    shape: BoxShape.circle,
                    border: Border.all(
                      color: isTaken ? AppTheme.success : AppColors.border,
                      width: 2,
                    ),
                  ),
                  child: isTaken
                      ? const Icon(Icons.check, size: 14, color: Colors.white)
                      : null,
                ),
                if (!isLast)
                  Expanded(
                    child: Container(
                      width: 2,
                      margin: const EdgeInsets.symmetric(vertical: 4),
                      color: isTaken
                          ? AppTheme.success.withValues(alpha: 0.34)
                          : AppColors.borderLight,
                    ),
                  ),
              ],
            ),
          ),
          const SizedBox(width: 10),
          Expanded(
            child: Padding(
              padding: EdgeInsets.only(bottom: isLast ? 0 : 12),
              child: Container(
                padding: const EdgeInsets.fromLTRB(12, 10, 10, 10),
                decoration: BoxDecoration(
                  color: isTaken
                      ? _MedicationCheckInPageState._softGreen
                      : const Color(0xFFF8FAFC),
                  borderRadius: BorderRadius.circular(12),
                  border: Border.all(
                    color: isTaken
                        ? AppTheme.success.withValues(alpha: 0.18)
                        : AppColors.borderLight,
                  ),
                ),
                child: Row(
                  children: [
                    Icon(Icons.access_time, size: 18, color: statusColor),
                    const SizedBox(width: 8),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            displayTime,
                            maxLines: 1,
                            overflow: TextOverflow.ellipsis,
                            style: TextStyle(
                              fontSize: 18,
                              fontWeight: FontWeight.w800,
                              color: isTaken ? AppTheme.textSub : AppTheme.text,
                            ),
                          ),
                          const SizedBox(height: 1),
                          Text(
                            isTaken ? '已完成打卡' : '等待确认服用',
                            maxLines: 1,
                            overflow: TextOverflow.ellipsis,
                            style: TextStyle(
                              fontSize: 12,
                              fontWeight: FontWeight.w600,
                              color: isTaken
                                  ? AppTheme.success
                                  : AppColors.textSecondary,
                            ),
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(width: 8),
                    SizedBox(
                      height: 36,
                      child: FilledButton.icon(
                        onPressed: isBusy || medId.isEmpty || time.isEmpty
                            ? null
                            : () => onToggle(medId, time, isTaken),
                        style: FilledButton.styleFrom(
                          backgroundColor: isTaken
                              ? Colors.white
                              : _MedicationCheckInPageState._medBlue,
                          foregroundColor: isTaken
                              ? AppTheme.success
                              : Colors.white,
                          disabledBackgroundColor: AppColors.cardInner,
                          disabledForegroundColor: AppColors.textHint,
                          padding: const EdgeInsets.symmetric(horizontal: 12),
                          minimumSize: const Size(0, 36),
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(10),
                            side: BorderSide(
                              color: isTaken
                                  ? AppTheme.success.withValues(alpha: 0.34)
                                  : Colors.transparent,
                            ),
                          ),
                        ),
                        icon: isBusy
                            ? const SizedBox(
                                width: 14,
                                height: 14,
                                child: CircularProgressIndicator(
                                  strokeWidth: 2,
                                  color: AppColors.textHint,
                                ),
                              )
                            : Icon(
                                isTaken
                                    ? Icons.undo_rounded
                                    : Icons.check_rounded,
                                size: 17,
                              ),
                        label: Text(
                          isTaken ? '撤销' : '打卡',
                          style: const TextStyle(
                            fontSize: 14,
                            fontWeight: FontWeight.w800,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

bool _isTaken(Map<String, dynamic> dose) {
  return dose['status']?.toString().toLowerCase() == 'taken';
}

String _formatTime(String raw) {
  final value = raw.trim();
  if (value.length >= 5 && value[2] == ':') return value.substring(0, 5);
  final parsed = DateTime.tryParse(value);
  if (parsed == null) return value;
  final hour = parsed.hour.toString().padLeft(2, '0');
  final minute = parsed.minute.toString().padLeft(2, '0');
  return '$hour:$minute';
}
