import 'dart:async';

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

import '../../data/services/sync_service.dart';
import '../../data/services/sound_service.dart';
import '../../core/enums.dart';
import '../../core/sacred_tokens.dart';
import '../../providers.dart';
import '../admin/admin_screen.dart';
import 'main_screen.dart';
import 'adzan_screen.dart';
import 'iqomah_screen.dart';
import 'black_screen.dart';
import 'slideshow_screen.dart';
import 'jumat_screen.dart';
import 'khutbah_screen.dart';

/// The root view that orchestrates all screen states via AnimatedSwitcher.
class HomeView extends ConsumerStatefulWidget {
  const HomeView({super.key});

  @override
  ConsumerState<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends ConsumerState<HomeView> {
  static const List<LogicalKeyboardKey> _adminUnlockSequence = [
    LogicalKeyboardKey.arrowUp,
    LogicalKeyboardKey.arrowUp,
    LogicalKeyboardKey.arrowDown,
    LogicalKeyboardKey.arrowDown,
    LogicalKeyboardKey.arrowLeft,
    LogicalKeyboardKey.arrowRight,
    LogicalKeyboardKey.arrowLeft,
    LogicalKeyboardKey.arrowRight,
    LogicalKeyboardKey.select,
  ];

  final FocusNode _homeFocusNode = FocusNode(debugLabel: 'home_tv_root');
  final List<LogicalKeyboardKey> _recentKeys = [];
  final List<LogicalKeyboardKey> _simulationShortcutKeys = [];
  Timer? _comboResetTimer;
  Timer? _simulationShortcutTimer;
  Timer? _autoRefreshTimer;
  bool _isAutoRefreshRunning = false;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _checkAutoSync();
      _startAutoRefreshMonitor();
      if (mounted) {
        _homeFocusNode.requestFocus();
      }
    });
  }

  @override
  void dispose() {
    _comboResetTimer?.cancel();
    _simulationShortcutTimer?.cancel();
    _autoRefreshTimer?.cancel();
    _homeFocusNode.dispose();
    super.dispose();
  }

  void _startAutoRefreshMonitor() {
    _autoRefreshTimer?.cancel();
    _autoRefreshTimer = Timer.periodic(
      const Duration(hours: 6),
      (_) => _checkAutoSync(),
    );
  }

  Future<void> _checkAutoSync() async {
    if (_isAutoRefreshRunning || !mounted) return;
    _isAutoRefreshRunning = true;
    try {
      final result = await SyncService.instance.autoRefreshIfNeeded();
      if (!mounted) return;

      if (result.synced) {
        debugPrint('[AutoSync] Cache refreshed successfully.');
        ref.invalidate(todayScheduleProvider);
        ref.invalidate(scheduleCacheStatusProvider);
        return;
      }

      if (result.attempted) {
        debugPrint('[AutoSync] Refresh attempt failed. Staying on local cache.');
      }
    } finally {
      _isAutoRefreshRunning = false;
    }
  }

  KeyEventResult _handleTvKey(FocusNode node, KeyEvent event) {
    if (event is! KeyDownEvent) return KeyEventResult.ignored;

    final key = event.logicalKey;
    final isSimulating = ref.read(mockTimeOffsetProvider) != Duration.zero;
    if (isSimulating && key == LogicalKeyboardKey.arrowLeft) {
      _comboResetTimer?.cancel();
      _recentKeys.clear();
      _simulationShortcutTimer?.cancel();
      _simulationShortcutTimer = Timer(
        const Duration(seconds: 2),
        _resetSimulationShortcut,
      );
      _simulationShortcutKeys.add(key);
      if (_simulationShortcutKeys.length > 2) {
        _simulationShortcutKeys.removeAt(0);
      }
      if (_matchesSimulationShortcut()) {
        _resetSimulationShortcut();
        ref.read(mockTimeOffsetProvider.notifier).state = Duration.zero;
        WidgetsBinding.instance.addPostFrameCallback((_) async {
          if (!mounted) return;
          await Navigator.of(context).push(
            MaterialPageRoute(
              builder: (_) => const AdminScreen(
                initialTab: 4,
                focusSelectedTabOnOpen: true,
              ),
            ),
          );
          if (mounted) {
            _homeFocusNode.requestFocus();
          }
        });
      }
      return KeyEventResult.handled;
    } else if (isSimulating) {
      _resetSimulationShortcut();
    }

    if (isSimulating &&
        (key == LogicalKeyboardKey.escape ||
            key == LogicalKeyboardKey.goBack ||
            key == LogicalKeyboardKey.browserBack)) {
      ref.read(mockTimeOffsetProvider.notifier).state = Duration.zero;
      return KeyEventResult.handled;
    }

    if (!_isComboKey(key)) {
      _resetCombo();
      return KeyEventResult.ignored;
    }

    _comboResetTimer?.cancel();
    _comboResetTimer = Timer(const Duration(seconds: 3), _resetCombo);

    _recentKeys.add(key);
    if (_recentKeys.length > _adminUnlockSequence.length) {
      _recentKeys.removeAt(0);
    }

    if (_matchesUnlockSequence()) {
      _resetCombo();
      WidgetsBinding.instance.addPostFrameCallback((_) async {
        if (!mounted) return;
        await Navigator.of(context).push(
          MaterialPageRoute(builder: (_) => const AdminScreen()),
        );
        if (mounted) {
          _homeFocusNode.requestFocus();
        }
      });
      return KeyEventResult.handled;
    }

    return KeyEventResult.ignored;
  }

  bool _isComboKey(LogicalKeyboardKey key) {
    return key == LogicalKeyboardKey.arrowUp ||
        key == LogicalKeyboardKey.arrowDown ||
        key == LogicalKeyboardKey.arrowLeft ||
        key == LogicalKeyboardKey.arrowRight ||
        key == LogicalKeyboardKey.select ||
        key == LogicalKeyboardKey.enter;
  }

  bool _matchesUnlockSequence() {
    if (_recentKeys.length != _adminUnlockSequence.length) return false;

    for (var i = 0; i < _adminUnlockSequence.length; i++) {
      final current = _recentKeys[i] == LogicalKeyboardKey.enter
          ? LogicalKeyboardKey.select
          : _recentKeys[i];
      if (current != _adminUnlockSequence[i]) return false;
    }
    return true;
  }

  void _resetCombo() {
    _comboResetTimer?.cancel();
    _recentKeys.clear();
  }

  bool _matchesSimulationShortcut() {
    return _simulationShortcutKeys.length == 2 &&
        _simulationShortcutKeys[0] == LogicalKeyboardKey.arrowLeft &&
        _simulationShortcutKeys[1] == LogicalKeyboardKey.arrowLeft;
  }

  void _resetSimulationShortcut() {
    _simulationShortcutTimer?.cancel();
    _simulationShortcutKeys.clear();
  }

  @override
  Widget build(BuildContext context) {
    // Audio trigger listener
    ref.listen<ScreenStateData>(screenStateProvider, (previous, next) {
      if (previous == null) return;

      // TRIGGER 1: Adzan Beep (Fires precisely when transitioning to Adzan)
      if (previous.state != ScreenState.adzan && next.state == ScreenState.adzan) {
        SoundService.instance.playAdzanBeep();
      }

      // TRIGGER 2: 3-Second Iqomah Countdown
      if (next.state == ScreenState.menujuIqomah && next.iqomahRemaining != null) {
        // Play precisely on the tick where it is 3 seconds.
        if (previous.iqomahRemaining?.inSeconds != 3 && next.iqomahRemaining!.inSeconds == 3) {
          SoundService.instance.playIqomahCountdown();
        }
      }
    });

    final screenData = ref.watch(screenStateProvider);
    final isMainScreen = ref.watch(isMainScreenProvider);

    // Determine which screen to display
    Widget screen;
    switch (screenData.state) {
      case ScreenState.normal:
      case ScreenState.menujuAdzan:
        if (screenData.isFriday && screenData.nextPrayer?.id == 'dzuhur') {
          screen = const JumatScreen(key: ValueKey('jumat'));
        } else {
          screen = isMainScreen 
              ? const MainScreen(key: ValueKey('main')) 
              : const SlideshowScreen(key: ValueKey('slideshow'));
        }
        break;
      case ScreenState.kembaliNormal:
        screen = const MainScreen(key: ValueKey('main'));
        break;
      case ScreenState.adzan:
        screen = const AdzanAlertScreen(key: ValueKey('adzan'));
        break;
      case ScreenState.menujuIqomah:
        if (screenData.isFriday && screenData.activePrayer?.id == 'dzuhur') {
          screen = const KhutbahScreen(key: ValueKey('khutbah'));
        } else {
          screen = const IqomahScreen(key: ValueKey('iqomah'));
        }
        break;
      case ScreenState.shalat:
        screen = const BlackScreen(key: ValueKey('black'));
        break;
    }

    return Focus(
      autofocus: true,
      focusNode: _homeFocusNode,
      onKeyEvent: _handleTvKey,
      child: Scaffold(
        backgroundColor: SacredColors.background,
        body: Stack(
          children: [
            AnimatedSwitcher(
              duration: const Duration(milliseconds: 800),
              transitionBuilder: (child, animation) {
                return FadeTransition(opacity: animation, child: child);
              },
              child: screen,
            ),
          ],
        ),
      ),
    );
  }
}
