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

import '../../config/theme.dart';
import '../../core/bridge/bridge_commands.dart';
import '../../core/bridge/js_bridge.dart';
import '../../core/services/auth_service.dart';
import '../../core/services/connectivity_service.dart';
import '../../core/services/deep_link_service.dart';
import '../../core/services/haptics_service.dart';
import '../../core/services/push_service.dart';
import '../../core/services/share_service.dart';
import 'webview_container.dart';

class AppShell extends StatefulWidget {
  final AuthService authService;
  final PushService pushService;
  final DeepLinkService deepLinkService;
  final ConnectivityService connectivityService;
  final String? initialToken;

  const AppShell({
    super.key,
    required this.authService,
    required this.pushService,
    required this.deepLinkService,
    required this.connectivityService,
    this.initialToken,
  });

  @override
  State<AppShell> createState() => _AppShellState();
}

class _AppShellState extends State<AppShell> with WidgetsBindingObserver {
  final JsBridge _bridge = JsBridge();
  final HapticsService _haptics = HapticsService();
  final ShareService _share = ShareService();

  bool _isGameMode = false;
  bool _isOffline = false;
  InAppWebViewController? _webController;
  DateTime? _backgroundedAt;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _setupBridge();
    _setupPushHandler();
    _setupDeepLinks();
    _setupConnectivity();
  }

  void _setupBridge() {
    _bridge.on(BridgeCommand.haptic, (msg) {
      _haptics.trigger(msg.data['type'] as String? ?? 'light');
    });

    _bridge.on(BridgeCommand.share, (msg) {
      _share.share(
        text: msg.data['text'] as String? ?? '',
        subject: msg.data['title'] as String?,
      );
    });

    _bridge.on(BridgeCommand.navSync, (msg) {
      final gameMode = msg.data['gameMode'] as bool? ?? false;
      if (gameMode != _isGameMode) {
        setState(() => _isGameMode = gameMode);
        SystemChrome.setEnabledSystemUIMode(
          gameMode ? SystemUiMode.immersiveSticky : SystemUiMode.edgeToEdge,
        );
      }
    });

    _bridge.on(BridgeCommand.authReady, (msg) async {
      final token = msg.data['token'] as String?;
      final userId = msg.data['userId'] as String?;
      if (token != null) {
        await widget.authService.saveToken(token);
        if (userId != null) {
          await widget.authService.saveUserId(userId);
        }
        // Register push token with backend
        _registerPushToken(userId);
        // Offer biometric setup if available and not already enabled
        _offerBiometric();
      }
    });

    _bridge.on(BridgeCommand.authLogout, (msg) async {
      await widget.authService.clearCredentials();
    });

    _bridge.on(BridgeCommand.badge, (msg) {});
  }

  void _setupPushHandler() {
    widget.pushService.onNotificationTap = (data) {
      _bridge.onPushTap(data);
    };
  }

  void _setupDeepLinks() {
    widget.deepLinkService.links.listen((link) {
      _bridge.onDeepLink(link.route, link.id ?? '');
    });
  }

  void _setupConnectivity() {
    _isOffline = !widget.connectivityService.isOnline;
    widget.connectivityService.onConnectivityChanged.listen((online) {
      setState(() => _isOffline = !online);
      _bridge.onConnectivityChanged(online);
    });
  }

  Future<void> _registerPushToken(String? userId) async {
    if (userId == null) return;
    widget.pushService.subscribeToNotifications(userId);
  }

  Future<void> _offerBiometric() async {
    final available = await widget.authService.isBiometricAvailable;
    final alreadyEnabled = await widget.authService.isBiometricEnabled;
    if (available && !alreadyEnabled && mounted) {
      // Show biometric opt-in after a short delay
      Future.delayed(const Duration(seconds: 3), () {
        if (!mounted) return;
        _showBiometricDialog();
      });
    }
  }

  void _showBiometricDialog() {
    showDialog(
      context: context,
      builder: (ctx) => AlertDialog(
        backgroundColor: El3abColors.bgCard,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
        title: const Text(
          'تسجيل دخول سريع',
          style: TextStyle(color: El3abColors.textPrimary),
          textAlign: TextAlign.center,
        ),
        content: const Text(
          'فعّل البصمة لتسجيل الدخول بسرعة في المرة الجاية',
          style: TextStyle(color: El3abColors.textSecondary),
          textAlign: TextAlign.center,
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx),
            child: const Text('لاحقاً', style: TextStyle(color: El3abColors.textSecondary)),
          ),
          FilledButton(
            onPressed: () async {
              await widget.authService.setBiometricEnabled(true);
              if (ctx.mounted) Navigator.pop(ctx);
            },
            style: FilledButton.styleFrom(
              backgroundColor: El3abColors.gold,
              foregroundColor: Colors.black,
            ),
            child: const Text('فعّل'),
          ),
        ],
      ),
    );
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.paused) {
      _backgroundedAt = DateTime.now();
    } else if (state == AppLifecycleState.resumed) {
      if (_backgroundedAt != null) {
        final elapsed = DateTime.now().difference(_backgroundedAt!);
        if (elapsed > const Duration(minutes: 5)) {
          // Reload WebView after long background
          _webController?.reload();
        }
      }
      _backgroundedAt = null;
    }
  }


  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _bridge.detach();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: El3abColors.bgDeep,
      body: SafeArea(
        bottom: false,
        child: WebViewContainer(
          bridge: _bridge,
          initialToken: widget.initialToken,
          isOffline: _isOffline,
          onControllerReady: (controller) {
            _webController = controller;
          },
        ),
      ),
    );
  }
}
