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

import '../../core/app_colors.dart';
import '../../core/app_theme.dart';
import '../../core/navigation_provider.dart';
import '../../providers/data_providers.dart';
import '../../services/in_app_notification_service.dart';

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

  @override
  ConsumerState<NotificationCenterPage> createState() =>
      _NotificationCenterPageState();
}

class _NotificationCenterPageState
    extends ConsumerState<NotificationCenterPage> {
  InAppNotificationHistory? _history;
  bool _loading = true;
  bool _markingAll = false;
  String? _error;

  InAppNotificationService get _service =>
      ref.read(inAppNotificationServiceProvider);

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

  Future<void> _load() async {
    if (mounted) {
      setState(() {
        _loading = true;
        _error = null;
      });
    }
    try {
      final history = await _service.getHistory();
      if (!mounted) return;
      setState(() {
        _history = history;
        _loading = false;
      });
      ref.invalidate(notificationUnreadCountProvider);
    } catch (error) {
      if (mounted) {
        setState(() {
          _error = '$error';
          _loading = false;
        });
      }
    }
  }

  Future<void> _open(InAppNotification item) async {
    if (!item.isRead) {
      await _service.acknowledge(item.id);
      if (!mounted) return;
      setState(() {
        final current = _history;
        if (current == null) return;
        _history = InAppNotificationHistory(
          unreadCount: (current.unreadCount - 1).clamp(0, current.unreadCount),
          items: current.items
              .map(
                (value) =>
                    value.id == item.id ? value.copyWith(isRead: true) : value,
              )
              .toList(),
        );
      });
      ref.invalidate(notificationUnreadCountProvider);
    }

    if (!mounted || item.actionType == null) return;
    switch (item.actionType) {
      case 'medication':
        pushRoute(ref, 'medCheckIn', params: {'id': item.actionTargetId ?? ''});
        return;
      case 'exercise':
        pushRoute(ref, 'exercisePlan');
        return;
      case 'health':
        pushRoute(ref, 'trend', params: {'type': item.actionTargetId ?? ''});
        return;
      case 'report':
        final reportId = item.actionTargetId;
        if (reportId != null && reportId.isNotEmpty) {
          pushRoute(ref, 'aiAnalysis', params: {'id': reportId});
        }
        return;
    }
  }

  Future<void> _markAllRead() async {
    if (_markingAll || (_history?.unreadCount ?? 0) == 0) return;
    setState(() => _markingAll = true);
    try {
      await _service.markAllRead();
      if (!mounted) return;
      final current = _history;
      if (current != null) {
        setState(
          () => _history = InAppNotificationHistory(
            unreadCount: 0,
            items: current.items
                .map((item) => item.copyWith(isRead: true))
                .toList(),
          ),
        );
      }
      ref.invalidate(notificationUnreadCountProvider);
    } finally {
      if (mounted) setState(() => _markingAll = false);
    }
  }

  Future<void> _delete(InAppNotification item) async {
    try {
      await _service.delete(item.id);
      if (!mounted) return;
      final current = _history;
      if (current != null) {
        setState(
          () => _history = InAppNotificationHistory(
            unreadCount: item.isRead
                ? current.unreadCount
                : (current.unreadCount - 1).clamp(0, current.unreadCount),
            items: current.items.where((value) => value.id != item.id).toList(),
          ),
        );
      }
      ref.invalidate(notificationUnreadCountProvider);
    } catch (_) {
      if (mounted) await _load();
    }
  }

  @override
  Widget build(BuildContext context) {
    final items = _history?.items ?? const <InAppNotification>[];
    return Scaffold(
      body: AppBackground(
        safeArea: true,
        child: Column(
          children: [
            _Header(
              unreadCount: _history?.unreadCount ?? 0,
              markingAll: _markingAll,
              onBack: () => popRoute(ref),
              onMarkAllRead: _markAllRead,
            ),
            Expanded(
              child: RefreshIndicator(
                onRefresh: _load,
                color: const Color(0xFF438CE1),
                child: _buildBody(items),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildBody(List<InAppNotification> items) {
    if (_loading) {
      return const Center(child: CircularProgressIndicator());
    }
    if (_error != null) {
      return _MessageState(
        icon: LucideIcons.wifiOff,
        title: '通知加载失败',
        message: '请检查网络连接后重试',
        buttonText: '重新加载',
        onPressed: _load,
      );
    }
    if (items.isEmpty) {
      return const _MessageState(
        icon: LucideIcons.bellOff,
        title: '暂时没有通知',
        message: '用药、运动、健康指标和报告消息会显示在这里',
      );
    }

    final today = <InAppNotification>[];
    final earlier = <InAppNotification>[];
    final now = DateTime.now();
    for (final item in items) {
      final local = item.createdAt.toLocal();
      final isToday =
          local.year == now.year &&
          local.month == now.month &&
          local.day == now.day;
      (isToday ? today : earlier).add(item);
    }

    return ListView(
      physics: const AlwaysScrollableScrollPhysics(),
      padding: const EdgeInsets.fromLTRB(16, 6, 16, 32),
      children: [
        if (today.isNotEmpty) ...[
          const _SectionTitle('今天'),
          ...today.map(_buildDismissible),
        ],
        if (earlier.isNotEmpty) ...[
          const SizedBox(height: 10),
          const _SectionTitle('更早'),
          ...earlier.map(_buildDismissible),
        ],
      ],
    );
  }

  Widget _buildDismissible(InAppNotification item) => Padding(
    padding: const EdgeInsets.only(bottom: 10),
    child: Dismissible(
      key: ValueKey(item.id),
      direction: DismissDirection.endToStart,
      background: Container(
        alignment: Alignment.centerRight,
        padding: const EdgeInsets.only(right: 24),
        decoration: BoxDecoration(
          color: AppColors.error,
          borderRadius: BorderRadius.circular(18),
        ),
        child: const Icon(LucideIcons.trash2, color: Colors.white),
      ),
      onDismissed: (_) => _delete(item),
      child: _NotificationCard(item: item, onTap: () => _open(item)),
    ),
  );
}

class _Header extends StatelessWidget {
  final int unreadCount;
  final bool markingAll;
  final VoidCallback onBack;
  final VoidCallback onMarkAllRead;

  const _Header({
    required this.unreadCount,
    required this.markingAll,
    required this.onBack,
    required this.onMarkAllRead,
  });

  @override
  Widget build(BuildContext context) => Padding(
    padding: const EdgeInsets.fromLTRB(8, 8, 12, 10),
    child: Row(
      children: [
        IconButton(
          tooltip: '返回',
          onPressed: onBack,
          icon: const Icon(LucideIcons.chevronLeft),
        ),
        const SizedBox(width: 2),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const Text(
                '通知中心',
                style: TextStyle(
                  fontSize: 21,
                  fontWeight: FontWeight.w800,
                  color: AppColors.textPrimary,
                ),
              ),
              const SizedBox(height: 2),
              Text(
                unreadCount == 0 ? '所有消息均已读' : '$unreadCount 条未读消息',
                style: const TextStyle(
                  fontSize: 12,
                  color: AppColors.textSecondary,
                ),
              ),
            ],
          ),
        ),
        if (unreadCount > 0)
          TextButton.icon(
            onPressed: markingAll ? null : onMarkAllRead,
            icon: markingAll
                ? const SizedBox(
                    width: 14,
                    height: 14,
                    child: CircularProgressIndicator(strokeWidth: 2),
                  )
                : const Icon(LucideIcons.checkCheck, size: 17),
            label: const Text('全部已读'),
          ),
      ],
    ),
  );
}

class _SectionTitle extends StatelessWidget {
  final String text;
  const _SectionTitle(this.text);

  @override
  Widget build(BuildContext context) => Padding(
    padding: const EdgeInsets.fromLTRB(4, 6, 4, 10),
    child: Text(
      text,
      style: const TextStyle(
        fontSize: 13,
        fontWeight: FontWeight.w700,
        color: AppColors.textSecondary,
      ),
    ),
  );
}

class _NotificationCard extends StatelessWidget {
  final InAppNotification item;
  final VoidCallback onTap;

  const _NotificationCard({required this.item, required this.onTap});

  @override
  Widget build(BuildContext context) {
    final visual = _NotificationVisual.of(item);
    return Material(
      color: item.isRead
          ? Colors.white.withValues(alpha: 0.72)
          : Colors.white.withValues(alpha: 0.96),
      borderRadius: BorderRadius.circular(18),
      elevation: item.isRead ? 0 : 1,
      shadowColor: visual.color.withValues(alpha: 0.12),
      child: InkWell(
        onTap: onTap,
        borderRadius: BorderRadius.circular(18),
        child: Container(
          padding: const EdgeInsets.all(14),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(18),
            border: Border.all(
              color: item.isRead
                  ? const Color(0xFFE9EEF5)
                  : visual.color.withValues(alpha: 0.18),
            ),
          ),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Container(
                width: 46,
                height: 46,
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                    colors: [visual.lightColor, Colors.white],
                  ),
                  borderRadius: BorderRadius.circular(14),
                ),
                child: Icon(visual.icon, size: 22, color: visual.color),
              ),
              const SizedBox(width: 12),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      children: [
                        Expanded(
                          child: Text(
                            item.title,
                            style: TextStyle(
                              fontSize: 15,
                              fontWeight: item.isRead
                                  ? FontWeight.w600
                                  : FontWeight.w800,
                              color: AppColors.textPrimary,
                            ),
                          ),
                        ),
                        if (!item.isRead)
                          Container(
                            width: 8,
                            height: 8,
                            decoration: BoxDecoration(
                              color: visual.color,
                              shape: BoxShape.circle,
                              boxShadow: [
                                BoxShadow(
                                  color: visual.color.withValues(alpha: 0.3),
                                  blurRadius: 5,
                                ),
                              ],
                            ),
                          ),
                      ],
                    ),
                    const SizedBox(height: 5),
                    Text(
                      item.message,
                      style: const TextStyle(
                        fontSize: 13,
                        height: 1.45,
                        color: AppColors.textSecondary,
                      ),
                    ),
                    const SizedBox(height: 9),
                    Row(
                      children: [
                        Text(
                          _formatTime(item.createdAt),
                          style: const TextStyle(
                            fontSize: 11,
                            color: AppColors.textHint,
                          ),
                        ),
                        const Spacer(),
                        if (item.actionType != null)
                          Row(
                            children: [
                              Text(
                                '查看详情',
                                style: TextStyle(
                                  fontSize: 12,
                                  fontWeight: FontWeight.w600,
                                  color: visual.color,
                                ),
                              ),
                              const SizedBox(width: 2),
                              Icon(
                                LucideIcons.chevronRight,
                                size: 14,
                                color: visual.color,
                              ),
                            ],
                          ),
                      ],
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  static String _formatTime(DateTime value) {
    final local = value.toLocal();
    final now = DateTime.now();
    final time =
        '${local.hour.toString().padLeft(2, '0')}:'
        '${local.minute.toString().padLeft(2, '0')}';
    if (local.year == now.year &&
        local.month == now.month &&
        local.day == now.day) {
      return time;
    }
    if (local.year == now.year) return '${local.month}月${local.day}日 $time';
    return '${local.year}年${local.month}月${local.day}日 $time';
  }
}

class _NotificationVisual {
  final IconData icon;
  final Color color;
  final Color lightColor;

  const _NotificationVisual(this.icon, this.color, this.lightColor);

  factory _NotificationVisual.of(InAppNotification item) {
    switch (item.actionType) {
      case 'exercise':
        return const _NotificationVisual(
          LucideIcons.activity,
          Color(0xFF2C9A70),
          Color(0xFFDDF7EC),
        );
      case 'health':
        if (item.severity == 'critical') {
          return const _NotificationVisual(
            LucideIcons.triangleAlert,
            Color(0xFFE55353),
            Color(0xFFFFE7E7),
          );
        }
        return const _NotificationVisual(
          LucideIcons.heartPulse,
          Color(0xFFE8863A),
          Color(0xFFFFEEDC),
        );
      case 'report':
        if (item.severity == 'error') {
          return const _NotificationVisual(
            LucideIcons.fileWarning,
            Color(0xFFE55353),
            Color(0xFFFFE7E7),
          );
        }
        return const _NotificationVisual(
          LucideIcons.fileCheck2,
          Color(0xFF7B68CE),
          Color(0xFFEDE9FF),
        );
      default:
        return const _NotificationVisual(
          LucideIcons.pill,
          Color(0xFF468AD8),
          Color(0xFFE4F0FF),
        );
    }
  }
}

class _MessageState extends StatelessWidget {
  final IconData icon;
  final String title;
  final String message;
  final String? buttonText;
  final VoidCallback? onPressed;

  const _MessageState({
    required this.icon,
    required this.title,
    required this.message,
    this.buttonText,
    this.onPressed,
  });

  @override
  Widget build(BuildContext context) => ListView(
    physics: const AlwaysScrollableScrollPhysics(),
    padding: const EdgeInsets.fromLTRB(28, 120, 28, 32),
    children: [
      Container(
        padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 34),
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: [
              Colors.white.withValues(alpha: 0.95),
              const Color(0xFFF1F7FF).withValues(alpha: 0.9),
            ],
          ),
          borderRadius: BorderRadius.circular(24),
          border: Border.all(color: const Color(0xFFE5EDF7)),
        ),
        child: Column(
          children: [
            Container(
              width: 64,
              height: 64,
              decoration: BoxDecoration(
                color: const Color(0xFFE5F0FF),
                borderRadius: BorderRadius.circular(20),
              ),
              child: Icon(icon, size: 29, color: const Color(0xFF5D91CF)),
            ),
            const SizedBox(height: 18),
            Text(
              title,
              style: const TextStyle(
                fontSize: 17,
                fontWeight: FontWeight.w800,
                color: AppColors.textPrimary,
              ),
            ),
            const SizedBox(height: 7),
            Text(
              message,
              textAlign: TextAlign.center,
              style: const TextStyle(
                fontSize: 13,
                height: 1.5,
                color: AppColors.textSecondary,
              ),
            ),
            if (buttonText != null) ...[
              const SizedBox(height: 20),
              FilledButton(onPressed: onPressed, child: Text(buttonText!)),
            ],
          ],
        ),
      ),
    ],
  );
}
