import ExpoModulesCore

public class EmbeddedWebViewModule: Module {
  private var emitterToken: UUID?

  public func definition() -> ModuleDefinition {
    Name("EmbeddedWebView")

    Events(
      "onMessage",
      "onShouldStartLoad",
      "onLoadError",
      "onLoadStart",
      "onLoad",
      "onLoadEnd"
    )

    OnCreate {
      self.emitterToken = EmbeddedWebViewController.shared.setEmitter { [weak self] name, payload in
        guard let self = self else { return }
        self.sendEvent(name, payload)
      }
    }

    OnDestroy {
      // Only clear if our emitter is still the live one. Prevents a stale
      // OnDestroy (e.g. during dev hot reload after a newer OnCreate already
      // ran) from nulling the active emitter.
      if let token = self.emitterToken {
        EmbeddedWebViewController.shared.clearEmitter(token: token)
        self.emitterToken = nil
      }
    }

    AsyncFunction("setUrl") { (url: String) in
      DispatchQueue.main.async {
        EmbeddedWebViewController.shared.setUrl(url)
      }
    }

    AsyncFunction("setVisible") { (visible: Bool) in
      DispatchQueue.main.async {
        EmbeddedWebViewController.shared.setVisible(visible)
      }
    }

    AsyncFunction("setDebuggingEnabled") { (enabled: Bool) in
      DispatchQueue.main.async {
        EmbeddedWebViewController.shared.setDebuggingEnabled(enabled)
      }
    }

    AsyncFunction("destroy") {
      DispatchQueue.main.async {
        EmbeddedWebViewController.shared.destroy()
      }
    }

    AsyncFunction("postMessage") { (message: String) in
      DispatchQueue.main.async {
        EmbeddedWebViewController.shared.postMessage(message)
      }
    }

    AsyncFunction("respondToShouldStartLoad") { (id: String, allow: Bool) in
      EmbeddedWebViewController.shared.respondToShouldStartLoad(id: id, allow: allow)
    }
  }
}
