import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../../../core/theme/app_colors.dart';
import '../../../../core/di/injection_container.dart';
import '../../../../core/services/contract_check_service.dart';
import '../../../../core/services/notification_service.dart';
import '../../../../core/updater/update_service.dart';
import '../../../../core/providers/maintenance_provider.dart';
import '../../../../core/providers/notification_badge_provider.dart';
import '../../../../routes/route_paths.dart';
import '../../../../routes/app_router.dart';
import '../../../../bootstrap.dart';
import '../../../auth/presentation/providers/auth_provider.dart';
import '../../../notification/presentation/widgets/force_read_notification_dialog.dart';
import '../widgets/bottom_nav_bar.dart';

class HomeShellPage extends ConsumerStatefulWidget {
  final Widget child;

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

  @override
  ConsumerState<HomeShellPage> createState() => _HomeShellPageState();
}

class _HomeShellPageState extends ConsumerState<HomeShellPage>
    with WidgetsBindingObserver {
  /// 下次允许检查更新的时间
  static DateTime? _nextCheckAllowedTime;

  /// 是否已检查过合同（防止重复检查）
  static bool _hasCheckedContracts = false;

  /// 后台合同检查定时器
  Timer? _contractCheckTimer;

  /// 维护状态检查定时器
  Timer? _maintenanceCheckTimer;

  /// 是否正在显示弹窗（防止重复弹窗）
  bool _isShowingDialog = false;

  /// 是否正在显示强制阅读通知弹窗
  bool _isShowingForceReadDialog = false;

  /// 上次显示强制阅读弹窗的时间（60 秒内不重复触发）
  static DateTime? _lastForceReadDialogShownAt;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    // 首次进入时检查维护状态、更新和未签署合同
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _checkMaintenanceStatus();
      _checkForUpdateIfNeeded();
      _checkContractsAndKyc();
      _checkAndShowForceReadDialog();
      // 启动后台定时检查
      _startBackgroundContractCheck();
      // 启动维护状态定时检查
      _startMaintenanceCheck();
    });
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _contractCheckTimer?.cancel();
    _maintenanceCheckTimer?.cancel();
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // 从后台恢复时检查维护状态和更新
    if (state == AppLifecycleState.resumed) {
      _checkMaintenanceStatus();
      _checkForUpdateIfNeeded();
      // 从后台恢复时也触发一次检查
      _scheduleNextContractCheck();
      // 恢复维护检查定时器
      _startMaintenanceCheck();
      // 从后台恢复时检查是否有需要强制阅读的通知
      _checkAndShowForceReadDialog();
    } else if (state == AppLifecycleState.paused) {
      // 进入后台时取消定时器
      _contractCheckTimer?.cancel();
      _maintenanceCheckTimer?.cancel();
    }
  }

  /// 启动维护状态定时检查（随机 30-60 秒检查一次）
  void _startMaintenanceCheck() {
    _scheduleNextMaintenanceCheck();
  }

  /// 安排下一次维护检查
  void _scheduleNextMaintenanceCheck() {
    _maintenanceCheckTimer?.cancel();
    // 随机 30-60 秒，平衡及时性和服务器压力
    final randomSeconds = 30 + Random().nextInt(31); // 30 + 0~30 = 30~60
    _maintenanceCheckTimer = Timer(Duration(seconds: randomSeconds), () async {
      await _checkMaintenanceStatus();
      // 检查完成后安排下一次检查
      if (mounted) {
        _scheduleNextMaintenanceCheck();
      }
    });
  }

  /// 检查系统维护状态
  Future<void> _checkMaintenanceStatus() async {
    if (!mounted) return;

    try {
      final maintenanceNotifier = ref.read(maintenanceProvider.notifier);
      await maintenanceNotifier.showMaintenanceDialogIfNeeded(context);
    } catch (e) {
      debugPrint('[HomeShellPage] 检查维护状态失败: $e');
    }
  }

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

    // 如果从未检查过，或者已过冷却时间，则检查
    if (_nextCheckAllowedTime == null || now.isAfter(_nextCheckAllowedTime!)) {
      // 设置下次允许检查时间（90-300秒随机间隔）
      final randomSeconds = 90 + Random().nextInt(211); // 90 + 0~210 = 90~300
      _nextCheckAllowedTime = now.add(Duration(seconds: randomSeconds));
      await checkForAppUpdate(context);
    }
  }

  /// 启动后台合同检查定时器
  void _startBackgroundContractCheck() {
    _scheduleNextContractCheck();
  }

  /// 安排下一次合同检查（随机 5-20 秒）
  void _scheduleNextContractCheck() {
    _contractCheckTimer?.cancel();

    // 随机 5-20 秒
    final randomSeconds = 5 + Random().nextInt(16); // 5 + 0~15 = 5~20

    _contractCheckTimer = Timer(Duration(seconds: randomSeconds), () async {
      await _performBackgroundContractCheck();
      // 检查完成后安排下一次检查
      if (mounted) {
        _scheduleNextContractCheck();
      }
    });
  }

  /// 检查当前是否在合同签署或KYC相关页面，或者正在显示升级弹窗
  bool _shouldSkipContractCheck() {
    // 1. 检查是否正在显示升级弹窗
    if (UpdateService().isShowingUpdateDialog) {
      return true;
    }

    // 2. 检查是否在合同/KYC页面
    // 遍历整个路由栈，检查是否有任何合同/KYC相关页面
    try {
      final router = ref.read(appRouterProvider);
      final matches = router.routerDelegate.currentConfiguration.matches;

      for (final match in matches) {
        final location = match.matchedLocation;
        // 合同签署相关页面
        if (location.startsWith('/contract-signing')) return true;
        // KYC 相关页面
        if (location.startsWith('/kyc')) return true;
      }
      return false;
    } catch (e) {
      return false;
    }
  }

  /// 执行后台综合检查（合同 + KYC）
  Future<void> _performBackgroundContractCheck() async {
    if (!mounted || _isShowingDialog) return;

    // 如果用户在合同签署、KYC页面，或正在升级，跳过检查
    if (_shouldSkipContractCheck()) return;

    try {
      final contractCheckService = ref.read(contractCheckServiceProvider);
      final result = await contractCheckService.checkAll();

      if (!mounted || _isShowingDialog) return;

      // 再次检查，防止在请求期间用户进入了相关页面或开始升级
      if (_shouldSkipContractCheck()) return;

      // 1. 优先处理待签署合同
      if (result.hasPendingContracts) {
        await _showContractRequiredDialog();
        return;
      }

      // 2. 处理需要 KYC 的情况
      if (result.requiresKyc) {
        await _showKycRequiredDialog(result);
      }
    } catch (e) {
      // 静默失败，不阻止用户使用
    }
  }

  /// 综合检查：待签署合同和 KYC 需求
  Future<void> _checkContractsAndKyc() async {
    // 每次会话只检查一次
    if (_hasCheckedContracts) return;
    _hasCheckedContracts = true;

    // 如果用户已在合同/KYC页面，跳过检查
    if (_shouldSkipContractCheck()) return;

    try {
      final contractCheckService = ref.read(contractCheckServiceProvider);
      final result = await contractCheckService.checkAll();

      if (!mounted) return;

      // 再次检查，防止在请求期间用户进入了相关页面
      if (_shouldSkipContractCheck()) return;

      // 1. 优先处理待签署合同
      if (result.hasPendingContracts) {
        // 有待签署合同，跳转到待签署列表页面
        // forceSign=true 表示必须签署后才能继续使用
        context.push(RoutePaths.pendingContracts, extra: true);
        return;
      }

      // 2. 处理需要 KYC 的情况
      if (result.requiresKyc) {
        await _showKycRequiredDialog(result);
      }
    } catch (e) {
      // 检查失败不阻止用户使用 App
    }
  }

  /// 显示合同签署必需弹窗（后台检测触发）
  Future<void> _showContractRequiredDialog() async {
    if (_isShowingDialog) return;
    _isShowingDialog = true;

    const message =
        '系统检测到您已认种了榴莲树，但尚未按国家法规签署合规的认种合同。请先完成合同签署，才能继续使用APP。';

    await showDialog(
      context: context,
      barrierDismissible: false, // 不允许点击外部关闭
      builder: (context) => PopScope(
        canPop: false, // 不允许返回键关闭
        child: AlertDialog(
          title: Row(
            children: [
              Icon(Icons.description_outlined, color: Colors.orange[700], size: 28),
              const SizedBox(width: 8),
              const Text('需要签署合同'),
            ],
          ),
          content: const Text(
            message,
            style: TextStyle(fontSize: 15, height: 1.5),
          ),
          actions: [
            ElevatedButton(
              onPressed: () {
                Navigator.of(context).pop();
                _isShowingDialog = false;
                // 跳转到待签署合同列表页面
                context.push(RoutePaths.pendingContracts, extra: true);
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: AppColors.primary,
                foregroundColor: Colors.white,
                minimumSize: const Size(double.infinity, 48),
              ),
              child: const Text('立即签署', style: TextStyle(fontSize: 16)),
            ),
          ],
        ),
      ),
    );

    _isShowingDialog = false;
  }

  /// 显示 KYC 必需弹窗
  Future<void> _showKycRequiredDialog(ContractCheckResult result) async {
    if (_isShowingDialog) return;
    _isShowingDialog = true;

    final message = result.kycMessage ??
        '系统检测到您已认种了榴莲树，但尚未按国家法规完成实名认证，无法签署合同。请先完成实名认证后才能继续使用APP。';

    await showDialog(
      context: context,
      barrierDismissible: false, // 不允许点击外部关闭
      builder: (context) => PopScope(
        canPop: false, // 不允许返回键关闭
        child: AlertDialog(
          title: Row(
            children: [
              Icon(Icons.warning_amber_rounded, color: Colors.orange[700], size: 28),
              const SizedBox(width: 8),
              const Text('需要实名认证'),
            ],
          ),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                message,
                style: const TextStyle(fontSize: 15, height: 1.5),
              ),
              if (result.paidOrderCount > 0) ...[
                const SizedBox(height: 12),
                Container(
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    color: Colors.orange.withValues(alpha: 0.1),
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Row(
                    children: [
                      Icon(Icons.info_outline, color: Colors.orange[700], size: 20),
                      const SizedBox(width: 8),
                      Expanded(
                        child: Text(
                          '您有 ${result.paidOrderCount} 笔认种订单待签署合同',
                          style: TextStyle(
                            color: Colors.orange[800],
                            fontSize: 14,
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ],
          ),
          actions: [
            ElevatedButton(
              onPressed: () {
                Navigator.of(context).pop();
                _isShowingDialog = false;
                // 跳转到 KYC 入口页面
                context.push(RoutePaths.kycEntry);
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: AppColors.primary,
                foregroundColor: Colors.white,
                minimumSize: const Size(double.infinity, 48),
              ),
              child: const Text('立即认证', style: TextStyle(fontSize: 16)),
            ),
          ],
        ),
      ),
    );

    _isShowingDialog = false;
  }

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

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

    // 防护 3：用户未登录
    final authState = ref.read(authProvider);
    final userSerialNum = authState.userSerialNum;
    if (userSerialNum == null) return;

    // 防护 4：其他系统弹窗（合同/KYC/升级）正在展示
    if (_isShowingDialog) return;

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

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

    _isShowingForceReadDialog = true;
    _isShowingDialog = true; // 防止后台合同/KYC 检查在此期间叠加弹窗
    _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,
      );
    }

    _isShowingDialog = false;
    _isShowingForceReadDialog = false;

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

  /// 重置合同检查状态（用于用户切换账号时）
  static void resetContractCheckState() {
    _hasCheckedContracts = false;
    // 同时重置强制阅读弹窗冷却时间，确保新账号可以立即检查
    _lastForceReadDialogShownAt = null;
  }

  int _getCurrentIndex(BuildContext context) {
    final location = GoRouterState.of(context).uri.path;
    // 索引: 0-龙虎榜, 1-监控, 2-兑换, 3-我
    if (location.startsWith(RoutePaths.ranking)) return 0;
    if (location.startsWith(RoutePaths.mining)) return 1;
    if (location.startsWith(RoutePaths.trading)) return 2;
    if (location.startsWith(RoutePaths.profile)) return 3;
    return 0;
  }

  void _onTabTapped(BuildContext context, int index) {
    // 索引: 0-龙虎榜, 1-监控, 2-兑换, 3-我
    switch (index) {
      case 0:
        context.go(RoutePaths.ranking);
        break;
      case 1:
        context.go(RoutePaths.mining);
        break;
      case 2:
        context.go(RoutePaths.trading);
        break;
      case 3:
        context.go(RoutePaths.profile);
        break;
    }
  }

  @override
  Widget build(BuildContext context) {
    final unreadCount = ref.watch(unreadNotificationCountProvider);

    return Scaffold(
      body: widget.child,
      bottomNavigationBar: BottomNavBar(
        currentIndex: _getCurrentIndex(context),
        onTap: (index) => _onTabTapped(context, index),
        profileBadgeCount: unreadCount,
      ),
    );
  }
}
