import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

import 'bridge_commands.dart';

typedef BridgeHandler = void Function(BridgeMessage message);

class JsBridge {
  InAppWebViewController? _controller;
  final Map<BridgeCommand, List<BridgeHandler>> _handlers = {};

  void attach(InAppWebViewController controller) {
    _controller = controller;
  }

  void detach() {
    _controller = null;
  }

  void on(BridgeCommand command, BridgeHandler handler) {
    _handlers.putIfAbsent(command, () => []).add(handler);
  }

  void off(BridgeCommand command, BridgeHandler handler) {
    _handlers[command]?.remove(handler);
  }

  void handleMessage(String rawMessage) {
    try {
      final json = jsonDecode(rawMessage) as Map<String, dynamic>;
      final message = BridgeMessage.fromJson(json);
      final handlers = _handlers[message.command];
      if (handlers != null) {
        for (final handler in handlers) {
          handler(message);
        }
      }
    } catch (e) {
      debugPrint('[JsBridge] Error parsing message: $e');
    }
  }

  Future<void> sendToWeb(String method, Map<String, dynamic> data) async {
    if (_controller == null) return;
    final jsonData = jsonEncode(data);
    final js = 'if(window.el3ab_native&&window.el3ab_native.$method){window.el3ab_native.$method($jsonData)}';
    try {
      await _controller!.evaluateJavascript(source: js);
    } catch (e) {
      debugPrint('[JsBridge] Error sending to web: $e');
    }
  }

  Future<void> onDeepLink(String route, String id) async {
    await sendToWeb('onDeepLink', {'route': route, 'id': id});
  }

  Future<void> onPushTap(Map<String, dynamic> payload) async {
    await sendToWeb('onPushTap', payload);
  }

  Future<void> onConnectivityChanged(bool online) async {
    await sendToWeb('onConnectivityChanged', {'online': online});
  }

  Future<void> onTokenRefreshed(String token) async {
    await sendToWeb('onTokenRefreshed', {'token': token});
  }

  Future<void> onNavTap(String world) async {
    await sendToWeb('onNavTap', {'world': world});
  }
}
