import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../core/router/routes.dart';
import '../../core/constants/app_colors.dart';
import '../../core/updater/update_service.dart';
import '../../core/updater/channels/self_hosted_updater.dart';
import '../../core/services/notification_service.dart';
import '../providers/notification_providers.dart';
import '../providers/user_providers.dart';
import 'force_read_notification_dialog.dart';

/// 主壳 Widget，包含底部导航栏和强制通知弹窗检查
///
/// 在 APP 启动和从后台恢复前台时：
/// 1. 检查版本更新（已有逻辑）
/// 2. 检查并展示强制阅读通知弹窗（新增逻辑）
class MainShell extends ConsumerStatefulWidget {
  final Widget child;

  const MainShell({super.key, required this.child});

  @override
  ConsumerState<MainShell> createState() => _MainShellState();
}

class _MainShellState extends ConsumerState<MainShell> with WidgetsBindingObserver {
  /// 下次允许检查更新的时间（static 防止 widget rebuild 重置）
  static DateTime? _nextCheckAllowedTime;

  /// 强制阅读弹窗互斥锁：防止同时弹出多个弹窗
  static bool _isShowingForceReadDialog = false;

  /// 上次展示强制阅读弹窗的时间（60秒冷却，防止快速切后台重弹）
  static DateTime? _lastForceReadDialogShownAt;

  @override
  void initState() {
    super.initState();
    debugPrint('[MainShell] initState called, adding WidgetsBindingObserver');
    WidgetsBinding.instance.addObserver(this);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      debugPrint('[MainShell] postFrameCallback → 触发首次更新检查');
      _checkForUpdateIfNeeded();
      // 延迟 5 秒后检查强制阅读通知，避免和更新弹窗冲突
      Future.delayed(const Duration(seconds: 5), () {
        if (mounted) _checkAndShowForceReadDialog();
      });
    });
  }

  @override
  void dispose() {
    debugPrint('[MainShell] dispose called, removing WidgetsBindingObserver');
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    debugPrint('[MainShell] didChangeAppLifecycleState: $state');
    if (state == AppLifecycleState.resumed) {
      _checkForUpdateIfNeeded();
      // 恢复前台时也检查强制阅读通知
      _checkAndShowForceReadDialog();
    }
  }

  /// ==================== 版本更新检查（原有逻辑） ====================

  Future<void> _checkForUpdateIfNeeded() async {
    final now = DateTime.now();

    // 如果从未检查过，或者已过冷却时间，则检查
    if (_nextCheckAllowedTime != null && now.isBefore(_nextCheckAllowedTime!)) {
      debugPrint('[MainShell] 跳过更新检查，冷却中 (下次: $_nextCheckAllowedTime)');
      return;
    }

    // 设置下次允许检查时间（90-300秒随机间隔）
    final randomSeconds = 90 + Random().nextInt(211);
    _nextCheckAllowedTime = now.add(Duration(seconds: randomSeconds));
    debugPrint('[MainShell] 准备检查更新，延迟3秒...');

    // 延迟3秒，避免启动时干扰用户
    await Future.delayed(const Duration(seconds: 3));
    if (!mounted) {
      debugPrint('[MainShell] widget 已 unmount，取消检查');
      return;
    }

    try {
      debugPrint('[MainShell] 开始调用 UpdateService.checkForUpdate(force: true)');
      // force: true 跳过 UpdateService 内部的60分钟间隔限制
      // 因为我们已有自己的90-300秒冷却节流
      final result = await UpdateService.instance.checkForUpdate(force: true);
      debugPrint('[MainShell] 检查结果: hasUpdate=${result.hasUpdate}, error=${result.error}');
      if (!mounted) return;

      if (result.hasUpdate && result.versionInfo != null) {
        debugPrint('[MainShell] 发现新版本: ${result.versionInfo!.versionName}，弹出更新对话框');
        await SelfHostedUpdater.show(
          context,
          versionInfo: result.versionInfo!,
          isForceUpdate: result.versionInfo!.isForceUpdate,
        );
      }
    } catch (e) {
      debugPrint('[MainShell] 检查更新失败: $e');
    }
  }

  /// ==================== 强制阅读通知弹窗（新增逻辑） ====================
  ///
  /// 仅展示标记了 [requiresForceRead] 且尚未读的通知。
  /// 用户必须逐条查看，最后一条勾选"我已经阅读并知晓"后方可关闭。
  /// 全部确认后逐条调用 markAsRead 并刷新未读角标。
  Future<void> _checkAndShowForceReadDialog() async {
    // 防护 1：已有强制阅读弹窗正在展示
    if (_isShowingForceReadDialog) return;

    // 防护 2：60 秒内不重复触发（防止快速切后台后立刻重弹）
    if (_lastForceReadDialogShownAt != null &&
        DateTime.now().difference(_lastForceReadDialogShownAt!) <
            const Duration(seconds: 60)) {
      return;
    }

    // 防护 3：用户未登录
    final accountSequence = ref.read(currentAccountSequenceProvider);
    if (accountSequence == null || accountSequence.isEmpty) return;

    // 获取未读且需要强制阅读的通知
    List<NotificationItem> forceReadList;
    try {
      final notifService = ref.read(notificationServiceProvider);
      final response = await notifService.getNotifications(
        userSerialNum: accountSequence,
        limit: 20,
      );
      forceReadList = response.notifications
          .where((n) => !n.isRead && n.requiresForceRead)
          .toList();
    } catch (_) {
      // API 失败时静默处理，不阻断用户使用
      return;
    }

    if (forceReadList.isEmpty || !mounted) return;

    _isShowingForceReadDialog = true;
    _lastForceReadDialogShownAt = DateTime.now();

    // 逐条展示强制阅读弹窗
    for (int i = 0; i < forceReadList.length; i++) {
      if (!mounted) break;
      await ForceReadNotificationDialog.show(
        context: context,
        notification: forceReadList[i],
        currentIndex: i + 1,
        totalCount: forceReadList.length,
      );
    }

    _isShowingForceReadDialog = false;

    // 全部通知看完后，逐条标记已读（不影响其他未读普通通知）
    if (mounted) {
      try {
        final notifService = ref.read(notificationServiceProvider);
        final currentAccount = ref.read(currentAccountSequenceProvider);
        if (currentAccount != null && currentAccount.isNotEmpty) {
          for (final n in forceReadList) {
            await notifService.markAsRead(
              userSerialNum: currentAccount,
              notificationId: n.id,
            );
          }
          // 刷新真实未读数量（非直接清零，避免误清其他未读通知的 badge）
          ref.read(notificationBadgeProvider.notifier).refresh();
        }
      } catch (_) {
        // 标记失败时静默处理；下次打开 App 仍会重新检查
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final isDark = AppColors.isDark(context);

    return Scaffold(
      body: widget.child,
      bottomNavigationBar: Container(
        decoration: BoxDecoration(
          color: AppColors.cardOf(context),
          boxShadow: [
            BoxShadow(
              color: isDark
                  ? Colors.black.withOpacity(0.3)
                  : Colors.black.withOpacity(0.05),
              blurRadius: 10,
              offset: const Offset(0, -2),
            ),
          ],
        ),
        child: SafeArea(
          top: false,
          child: Container(
            height: 56,
            padding: const EdgeInsets.symmetric(horizontal: 16),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                _buildNavItem(
                  context,
                  icon: Icons.favorite_outline,
                  activeIcon: Icons.favorite,
                  label: '贡献值',
                  index: 0,
                ),
                _buildNavItem(
                  context,
                  icon: Icons.swap_horiz_outlined,
                  activeIcon: Icons.swap_horiz,
                  label: '兑换',
                  index: 1,
                ),
                _buildNavItem(
                  context,
                  icon: Icons.account_balance_wallet_outlined,
                  activeIcon: Icons.account_balance_wallet,
                  label: '资产',
                  index: 2,
                ),
                _buildNavItem(
                  context,
                  icon: Icons.person_outline,
                  activeIcon: Icons.person,
                  label: '我的',
                  index: 3,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildNavItem(
    BuildContext context, {
    required IconData icon,
    required IconData activeIcon,
    required String label,
    required int index,
  }) {
    final currentIndex = _calculateSelectedIndex(context);
    final isSelected = currentIndex == index;
    final inactiveColor = AppColors.textMutedOf(context);

    return GestureDetector(
      onTap: () => _onItemTapped(index, context),
      behavior: HitTestBehavior.opaque,
      child: SizedBox(
        width: 64,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(
              isSelected ? activeIcon : icon,
              size: 24,
              color: isSelected ? AppColors.orange : inactiveColor,
            ),
            const SizedBox(height: 4),
            Text(
              label,
              style: TextStyle(
                fontSize: 11,
                fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400,
                color: isSelected ? AppColors.orange : inactiveColor,
              ),
            ),
          ],
        ),
      ),
    );
  }

  int _calculateSelectedIndex(BuildContext context) {
    final location = GoRouterState.of(context).uri.path;
    if (location.startsWith(Routes.contribution)) return 0;
    if (location.startsWith(Routes.trading)) return 1;
    if (location.startsWith(Routes.asset)) return 2;
    if (location.startsWith(Routes.profile)) return 3;
    return 0;
  }

  void _onItemTapped(int index, BuildContext context) {
    switch (index) {
      case 0:
        context.go(Routes.contribution);
        break;
      case 1:
        context.go(Routes.trading);
        break;
      case 2:
        context.go(Routes.asset);
        break;
      case 3:
        context.go(Routes.profile);
        break;
    }
  }
}
