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

import '../../core/api_client.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/navigation_provider.dart';
import '../../providers/data_providers.dart';
import '../../widgets/app_empty_state.dart';
import '../../widgets/app_future_view.dart';
import '../../widgets/app_toast.dart';
import '../../widgets/common_widgets.dart';
import '../care_plan_ui_logic.dart';

class EnterpriseExercisePlanPage extends ConsumerStatefulWidget {
  const EnterpriseExercisePlanPage({super.key});

  @override
  ConsumerState<EnterpriseExercisePlanPage> createState() =>
      _EnterpriseExercisePlanPageState();
}

class _EnterpriseExercisePlanPageState
    extends ConsumerState<EnterpriseExercisePlanPage> {
  final Set<String> _busyItems = {};
  final Set<String> _deletingPlans = {};

  Future<void> _refresh() => ref.refresh(exercisePlansProvider.future);

  Future<void> _toggleCheckIn(String itemId) async {
    if (itemId.isEmpty || _busyItems.contains(itemId)) return;
    setState(() => _busyItems.add(itemId));
    try {
      await ref.read(exerciseServiceProvider).checkIn(itemId);
      ref.invalidate(currentExercisePlanProvider);
      ref.invalidate(exercisePlansProvider);
    } catch (error) {
      if (mounted) {
        AppToast.show(
          context,
          error is ApiException ? error.message : '打卡失败，请稍后重试',
          type: AppToastType.error,
        );
      }
    } finally {
      if (mounted) setState(() => _busyItems.remove(itemId));
    }
  }

  Future<void> _confirmDelete(String id, String title) async {
    if (id.isEmpty || _deletingPlans.contains(id)) return;
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (dialogContext) => AlertDialog(
        title: const Text('删除运动计划'),
        content: Text('确定删除“$title”吗？删除后无法恢复。'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(dialogContext, false),
            child: const Text('取消'),
          ),
          TextButton(
            onPressed: () => Navigator.pop(dialogContext, true),
            style: TextButton.styleFrom(foregroundColor: AppColors.errorText),
            child: const Text('删除'),
          ),
        ],
      ),
    );
    if (confirmed != true || !mounted) return;
    setState(() => _deletingPlans.add(id));
    try {
      await ref.read(exerciseServiceProvider).deletePlan(id);
      ref.invalidate(currentExercisePlanProvider);
      ref.invalidate(exercisePlansProvider);
      if (mounted) {
        AppToast.show(context, '运动计划已删除', type: AppToastType.success);
      }
    } catch (error) {
      if (mounted) {
        AppToast.show(
          context,
          error is ApiException ? error.message : '删除失败，请稍后重试',
          type: AppToastType.error,
        );
      }
    } finally {
      if (mounted) setState(() => _deletingPlans.remove(id));
    }
  }

  @override
  Widget build(BuildContext context) {
    return GradientScaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () => popRoute(ref),
        ),
        title: const Text('运动计划'),
      ),
      floatingActionButton: AppCreateFab(
        tooltip: '新建运动计划',
        onPressed: () => pushRoute(ref, 'exerciseCreate'),
      ),
      body: AppAsyncValueView<List<Map<String, dynamic>>>(
        value: ref.watch(exercisePlansProvider),
        onRetry: () => ref.invalidate(exercisePlansProvider),
        errorTitle: '运动计划加载失败',
        onData: (_, plans) {
          if (plans.isEmpty) {
            return AppEmptyState(
              icon: AppModuleVisuals.exercise.icon,
              title: '暂无运动计划',
              subtitle: '点击右下角添加运动计划',
              iconColor: AppColors.exercise,
            );
          }
          final todayKey = _dateKey(DateTime.now());
          final validPlans = plans.where((plan) {
            return (plan['items'] as List?)?.isNotEmpty == true;
          }).toList();
          final todayItems = validPlans
              .expand(_itemsOf)
              .where((item) => item['scheduledDate']?.toString() == todayKey)
              .where((item) => item['isRestDay'] != true)
              .toList();
          final completedToday = todayItems
              .where((item) => item['isCompleted'] == true)
              .length;
          final groups = <CarePlanPhase, List<Map<String, dynamic>>>{
            for (final phase in CarePlanPhase.values) phase: [],
          };
          for (final plan in validPlans) {
            groups[resolveCarePlanPhase(
                  startDate: plan['startDate']?.toString(),
                  endDate: plan['endDate']?.toString(),
                )]!
                .add(plan);
          }

          return RefreshIndicator(
            onRefresh: _refresh,
            child: ListView(
              physics: const AlwaysScrollableScrollPhysics(),
              padding: AppSpacing.pageWithFab,
              children: [
                _TodayExercisePanel(
                  items: todayItems,
                  completed: completedToday,
                  busyItems: _busyItems,
                  onCheckIn: _toggleCheckIn,
                ),
                const SizedBox(height: 18),
                for (final phase in CarePlanPhase.values)
                  if (groups[phase]!.isNotEmpty) ...[
                    _ExercisePlanGroup(
                      phase: phase,
                      plans: groups[phase]!,
                      todayKey: todayKey,
                      busyItems: _busyItems,
                      deletingPlans: _deletingPlans,
                      onCheckIn: _toggleCheckIn,
                      onDelete: _confirmDelete,
                    ),
                    const SizedBox(height: 18),
                  ],
              ],
            ),
          );
        },
      ),
    );
  }
}

class _TodayExercisePanel extends StatelessWidget {
  final List<Map<String, dynamic>> items;
  final int completed;
  final Set<String> busyItems;
  final Future<void> Function(String) onCheckIn;

  const _TodayExercisePanel({
    required this.items,
    required this.completed,
    required this.busyItems,
    required this.onCheckIn,
  });

  @override
  Widget build(BuildContext context) {
    final progress = items.isEmpty ? 0.0 : completed / items.length;
    final next = items.cast<Map<String, dynamic>?>().firstWhere(
      (item) => item?['isCompleted'] != true,
      orElse: () => null,
    );
    if (items.isEmpty) {
      return Container(
        padding: AppSpacing.panel,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: AppRadius.lgBorder,
        ),
        child: Row(
          children: [
            Container(
              width: 42,
              height: 42,
              decoration: BoxDecoration(
                color: AppColors.exerciseLight,
                borderRadius: AppRadius.smBorder,
              ),
              child: Icon(
                AppModuleVisuals.exercise.icon,
                color: AppColors.exercise,
                size: 22,
              ),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text('今日休息', style: AppTextStyles.sectionTitle),
                  SizedBox(height: 3),
                  Text('今天没有安排运动，保持轻松活动即可', style: AppTextStyles.listSubtitle),
                ],
              ),
            ),
          ],
        ),
      );
    }
    return Container(
      padding: AppSpacing.panel,
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: AppRadius.lgBorder,
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text('今日任务', style: AppTextStyles.sectionTitle),
                    const SizedBox(height: 3),
                    Text(
                      '$completed / ${items.length} 已完成',
                      style: AppTextStyles.listSubtitle,
                    ),
                  ],
                ),
              ),
              if (next != null)
                _CompactActionButton(
                  busy: busyItems.contains(next['id']?.toString() ?? ''),
                  completed: false,
                  onPressed: () => onCheckIn(next['id']?.toString() ?? ''),
                ),
            ],
          ),
          const SizedBox(height: 14),
          ClipRRect(
            borderRadius: AppRadius.pillBorder,
            child: LinearProgressIndicator(
              minHeight: 5,
              value: progress,
              backgroundColor: AppColors.cardInner,
              valueColor: const AlwaysStoppedAnimation(AppColors.exercise),
            ),
          ),
          if (next != null) ...[
            const SizedBox(height: 12),
            Text(
              '${next['exerciseType'] ?? '运动'} · ${next['durationMinutes'] ?? 0} 分钟',
              style: AppTextStyles.listTitle.copyWith(fontSize: 16),
            ),
          ],
        ],
      ),
    );
  }
}

class _ExercisePlanGroup extends StatelessWidget {
  final CarePlanPhase phase;
  final List<Map<String, dynamic>> plans;
  final String todayKey;
  final Set<String> busyItems;
  final Set<String> deletingPlans;
  final Future<void> Function(String) onCheckIn;
  final Future<void> Function(String, String) onDelete;

  const _ExercisePlanGroup({
    required this.phase,
    required this.plans,
    required this.todayKey,
    required this.busyItems,
    required this.deletingPlans,
    required this.onCheckIn,
    required this.onDelete,
  });

  @override
  Widget build(BuildContext context) {
    final color = _phaseColor(phase);
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.only(left: 2, bottom: 9),
          child: Row(
            children: [
              Container(
                width: 8,
                height: 8,
                decoration: BoxDecoration(color: color, shape: BoxShape.circle),
              ),
              const SizedBox(width: 8),
              Text(
                '${_phaseLabel(phase)}（${plans.length}）',
                style: TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.w600,
                  color: color,
                ),
              ),
            ],
          ),
        ),
        Container(
          clipBehavior: Clip.antiAlias,
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: AppRadius.lgBorder,
          ),
          child: Column(
            children: List.generate(plans.length, (index) {
              final plan = plans[index];
              final items = _itemsOf(plan);
              final id = plan['id']?.toString() ?? '';
              final title = _exerciseTitle(items);
              final isDeleting = deletingPlans.contains(id);
              return SwipeDeleteTile(
                key: ValueKey(id),
                margin: EdgeInsets.zero,
                borderRadius: BorderRadius.zero,
                enabled: !isDeleting,
                onDelete: () => onDelete(id, title),
                child: _ExercisePlanRow(
                  plan: plan,
                  title: title,
                  phase: phase,
                  todayKey: todayKey,
                  busyItems: busyItems,
                  deleting: isDeleting,
                  showDivider: index < plans.length - 1,
                  onCheckIn: onCheckIn,
                ),
              );
            }),
          ),
        ),
      ],
    );
  }
}

class _ExercisePlanRow extends StatelessWidget {
  final Map<String, dynamic> plan;
  final String title;
  final CarePlanPhase phase;
  final String todayKey;
  final Set<String> busyItems;
  final bool deleting;
  final bool showDivider;
  final Future<void> Function(String) onCheckIn;

  const _ExercisePlanRow({
    required this.plan,
    required this.title,
    required this.phase,
    required this.todayKey,
    required this.busyItems,
    required this.deleting,
    required this.showDivider,
    required this.onCheckIn,
  });

  @override
  Widget build(BuildContext context) {
    final items = _itemsOf(plan);
    final done = items.where((item) => item['isCompleted'] == true).length;
    final progress = items.isEmpty ? 0.0 : done / items.length;
    final todayItem = items.cast<Map<String, dynamic>?>().firstWhere(
      (item) => item?['scheduledDate']?.toString() == todayKey,
      orElse: () => null,
    );
    final canCheckIn =
        phase == CarePlanPhase.active &&
        todayItem != null &&
        todayItem['isRestDay'] != true;
    final itemId = todayItem?['id']?.toString() ?? '';
    final completed = todayItem?['isCompleted'] == true;

    return Material(
      color: Colors.white,
      child: Stack(
        children: [
          Padding(
            padding: const EdgeInsets.fromLTRB(16, 12, 12, 12),
            child: Row(
              children: [
                Container(
                  width: 40,
                  height: 40,
                  decoration: BoxDecoration(
                    color: AppColors.exerciseLight,
                    borderRadius: AppRadius.smBorder,
                  ),
                  child: Icon(
                    AppModuleVisuals.exercise.icon,
                    color: AppColors.exercise,
                    size: 22,
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        children: [
                          Expanded(
                            child: Text(
                              title,
                              maxLines: 1,
                              overflow: TextOverflow.ellipsis,
                              style: AppTextStyles.listTitle.copyWith(
                                fontSize: 17,
                              ),
                            ),
                          ),
                          const SizedBox(width: 8),
                          Text(
                            '$done/${items.length}天',
                            style: AppTextStyles.tag,
                          ),
                        ],
                      ),
                      const SizedBox(height: 4),
                      Text(
                        '${_compactDate(plan['startDate'])} - ${_compactDate(plan['endDate'])}',
                        style: AppTextStyles.listSubtitle.copyWith(
                          fontSize: 13,
                        ),
                      ),
                      const SizedBox(height: 8),
                      ClipRRect(
                        borderRadius: AppRadius.pillBorder,
                        child: LinearProgressIndicator(
                          minHeight: 4,
                          value: progress,
                          backgroundColor: AppColors.cardInner,
                          valueColor: AlwaysStoppedAnimation(
                            _phaseColor(phase),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
                if (canCheckIn && !deleting) ...[
                  const SizedBox(width: 8),
                  _CompactActionButton(
                    busy: busyItems.contains(itemId) || deleting,
                    completed: completed,
                    onPressed: () => onCheckIn(itemId),
                  ),
                ],
                if (deleting)
                  const Padding(
                    padding: EdgeInsets.all(12),
                    child: SizedBox(
                      width: 18,
                      height: 18,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    ),
                  ),
              ],
            ),
          ),
          if (showDivider)
            const Positioned(
              left: 68,
              right: 0,
              bottom: 0,
              child: Divider(
                height: 1,
                thickness: 0.7,
                color: AppColors.divider,
              ),
            ),
        ],
      ),
    );
  }
}

class _CompactActionButton extends StatelessWidget {
  final bool busy;
  final bool completed;
  final VoidCallback onPressed;

  const _CompactActionButton({
    required this.busy,
    required this.completed,
    required this.onPressed,
  });

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 38,
      child: OutlinedButton(
        onPressed: busy ? null : onPressed,
        style: OutlinedButton.styleFrom(
          padding: const EdgeInsets.symmetric(horizontal: 14),
          backgroundColor: completed ? AppColors.successLight : Colors.white,
          foregroundColor: completed
              ? AppColors.successText
              : AppColors.exercise,
          side: BorderSide(
            color: completed ? AppColors.successText : AppColors.exercise,
          ),
          shape: RoundedRectangleBorder(borderRadius: AppRadius.smBorder),
        ),
        child: busy
            ? const SizedBox(
                width: 15,
                height: 15,
                child: CircularProgressIndicator(strokeWidth: 2),
              )
            : Text(completed ? '撤销' : '打卡', style: AppTextStyles.miniButton),
      ),
    );
  }
}

List<Map<String, dynamic>> _itemsOf(Map<String, dynamic> plan) =>
    (plan['items'] as List?)?.cast<Map<String, dynamic>>() ?? [];

String _exerciseTitle(List<Map<String, dynamic>> items) {
  final names = items
      .where((item) => item['isRestDay'] != true)
      .map((item) => item['exerciseType']?.toString().trim() ?? '')
      .where((name) => name.isNotEmpty)
      .toSet()
      .toList();
  if (names.isEmpty) return '运动计划';
  return names.length == 1 ? names.first : '${names.first}等${names.length}项';
}

String _dateKey(DateTime date) =>
    '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';

String _compactDate(Object? value) {
  final parsed = DateTime.tryParse(value?.toString() ?? '');
  return parsed == null
      ? '--'
      : '${parsed.year}.${parsed.month.toString().padLeft(2, '0')}.${parsed.day.toString().padLeft(2, '0')}';
}

String _phaseLabel(CarePlanPhase phase) => switch (phase) {
  CarePlanPhase.active => '进行中',
  CarePlanPhase.upcoming => '即将开始',
  CarePlanPhase.ended => '已结束',
};

Color _phaseColor(CarePlanPhase phase) => switch (phase) {
  CarePlanPhase.active => AppColors.successText,
  CarePlanPhase.upcoming => AppColors.blueMeasure,
  CarePlanPhase.ended => AppColors.textHint,
};
