import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter_branch_sdk/flutter_branch_sdk.dart';
import 'package:mypoint_flutter_app/core/utils/extensions/string_extension.dart';
import 'package:uni_links/uni_links.dart';
import 'package:mypoint_flutter_app/shared/navigation/directional_screen.dart';
import 'package:mypoint_flutter_app/core/utils/crypto.dart' as mycrypto;
import '../../app/routing/directional_action_type.dart';

class DeepLinkService {
  DeepLinkService._internal();
  static final DeepLinkService _instance = DeepLinkService._internal();
  factory DeepLinkService() => _instance;

  StreamSubscription? _linkSub;
  StreamSubscription<Map>? _branchSub;
  bool _initialized = false;

  Future<void> initialize() async {
    if (kIsWeb) return;
    if (_initialized) return;
    _initialized = true;
    debugPrint('🔗 Initializing DeepLinkService...');

    // await _initBranchSdk();
    await _handleInitialLink();
    _listenLinkStream();
  }

  Future<void> dispose() async {
    await _linkSub?.cancel();
    _linkSub = null;
    await _branchSub?.cancel();
    _branchSub = null;
    _initialized = false;
  }

  Future<void> _initBranchSdk() async {
    try {
      await FlutterBranchSdk.init(enableLogging: kDebugMode);
      debugPrint('🌿 Branch SDK init ');
      _branchSub = FlutterBranchSdk.listSession().listen(
        _handleBranchSession,
        onError: (error) {
          debugPrint('❌ Branch session stream error: $error');
        },
      );
    } catch (e) {
      debugPrint('❌ Failed to initialize Branch SDK: $e');
    }
  }

  Future<void> _handleInitialLink() async {
    try {
      final initial = await getInitialLink();
      if (initial == null) return;
      _routeFromUriString(initial);
    } catch (_) {}
  }

  bool handleIncomingUri(String uri) {
    return _routeFromUriString(uri) ?? false;
  }

  void _listenLinkStream() {
    try {
      _linkSub = linkStream.listen((uri) {
        if (uri == null) return;
        _routeFromUriString(uri.toString());
      }, onError: (_) {});
    } catch (_) {}
  }

  // Firebase Dynamic Links removed due to version constraints.
  bool? _routeFromUriString(String uriStr) {
    debugPrint('🔗 Deep link received: $uriStr');
    final uri = Uri.tryParse(uriStr);
    if (uri == null) return false;

    final type = uri.queryParameters[Defines.actionType] ?? uri.queryParameters['action_type'];
    final param = uri.queryParameters[Defines.actionParams] ?? uri.queryParameters['action_param'];

    // Optional: decrypt phone from `key` if present (compat with iOS scheme handler)
    final cipherHex = uri.queryParameters['key'];
    if (cipherHex != null && cipherHex.isNotEmpty) {
      // Try multiple known secrets (match iOS CommonAPI.schemeCryptKey variants)
      const candidates = <String>['mypointdeeplinkk', 'PVt3FWQibsB7xaLx'];
      for (final secret in candidates) {
        final phone = mycrypto.Crypto(cipherHex: cipherHex, secretKey: secret).decryption().orEmpty;
        if (phone.isNotEmpty) {
          debugPrint('🔐 Decrypted phone from key: $phone');
          final direction = DirectionalScreen.buildByName(
              name: DirectionalScreenName.linkMBPAccount,
              clickActionParam: phone
          );
          direction?.extraData = {
            'password': param,
          };
          return direction?.begin(); // Use if you need to attach to userInfo later
        }
      }
    }
    final screen = DirectionalScreen.build(clickActionType: type, clickActionParam: param);
    return screen?.begin();
  }

  void _handleBranchSession(Map<dynamic, dynamic> data) {
    debugPrint('🌿 Branch session data: $data');

    final dynamic clickedLink = data["+clicked_branch_link"];
    if (clickedLink != true && clickedLink != "true") {
      return;
    }

    final type = _stringOrNull(data[Defines.actionType]) ?? _stringOrNull(data['action_type']);
    final param = _stringOrNull(data[Defines.actionParams]) ?? _stringOrNull(data['action_param']);
    if (type != null) {
      final screen = DirectionalScreen.build(clickActionType: type, clickActionParam: param);
      if (screen != null) {
        screen.begin();
        return;
      }
    }

    final fallbackLink =
        _stringOrNull(data['~referring_link']) ?? _stringOrNull(data['+url']) ?? _stringOrNull(data['deeplink']);
    if (fallbackLink != null) {
      _routeFromUriString(fallbackLink);
    }
  }

  String? _stringOrNull(dynamic value) {
    if (value is String && value.isNotEmpty) return value;
    return null;
  }
}
