//
//  RNLivestreamManager.swift
//  humand
//

import Foundation
import React

@objc(RNLivestreamManager)
class RNLivestreamManager: RCTEventEmitter {
  static var shared: RNLivestreamManager?
  private var hasListeners = false

  override init() {
    super.init()
    RNLivestreamManager.shared = self
    livestreamLog("RNLivestreamManager initialized, shared set")
  }

  override func startObserving() {
    hasListeners = true
    livestreamLog("startObserving: JS listeners registered")
  }

  override func stopObserving() {
    hasListeners = false
    livestreamLog("stopObserving: JS listeners removed")
  }

  override static func requiresMainQueueSetup() -> Bool { true }

  override func supportedEvents() -> [String] {
    return [
      LivestreamConstants.RNEvents.livestreamStateChanged,
      LivestreamConstants.RNEvents.livestreamParticipantsChanged,
      LivestreamConstants.RNEvents.livestreamMediaStateChanged,
      LivestreamConstants.RNEvents.livestreamClosedCaption,
      LivestreamConstants.RNEvents.livestreamError
    ]
  }

  // MARK: - Bridge Methods

  @objc func setListenersReady() {
    livestreamLog("setListenersReady called")
    // Emit current state to catch up any missed events
    let currentState = LivestreamManager.shared.currentCallingState
    if !currentState.isEmpty {
      RNLivestreamManager.emitStateChanged(currentState)
    }
  }

  @objc func startHostLivestream(_ id: String, providerCallId: String, cameraEnabled: Bool) {
    livestreamLog("RNLivestreamManager.startHostLivestream called: id=\(id), providerCallId=\(providerCallId)")
    LivestreamManager.shared.startHostLivestream(id: id, providerCallId: providerCallId, cameraEnabled: cameraEnabled)
  }

  @objc func joinViewerLivestream(_ id: String, providerCallId: String, isHls: Bool) {
    LivestreamManager.shared.joinViewerLivestream(id: id, providerCallId: providerCallId, isHls: isHls)
  }

  @objc func leaveLivestream() {
    LivestreamManager.shared.leaveLivestream()
  }

  @objc func stopLivestream() {
    LivestreamManager.shared.stopLivestream()
  }

  @objc func setMicrophoneEnabled(_ enabled: Bool) {
    LivestreamManager.shared.setMicrophoneEnabled(enabled)
  }

  @objc func setCameraEnabled(_ enabled: Bool) {
    LivestreamManager.shared.setCameraEnabled(enabled)
  }

  @objc func switchCamera() {
    LivestreamManager.shared.switchCamera()
  }

  @objc func getLivestreamState(_ resolve: @escaping RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
    Task { @MainActor in
      let state = LivestreamManager.shared.getCurrentState()
      resolve(state)
    }
  }

  @objc override func addListener(_ eventName: String) {
    super.addListener(eventName)
  }

  @objc override func removeListeners(_ count: Double) {
    super.removeListeners(count)
  }

  // MARK: - Event Emitters

  static func emitStateChanged(_ state: String) {
    livestreamLog("emitStateChanged: state=\(state), shared=\(shared != nil ? "set" : "nil")")
    shared?.sendEvent(withName: LivestreamConstants.RNEvents.livestreamStateChanged, body: ["state": state])
  }

  static func emitParticipantsChanged(_ participants: [[String: Any]], _ totalCount: UInt32) {
    shared?.sendEvent(withName: LivestreamConstants.RNEvents.livestreamParticipantsChanged, body: ["participants": participants, "totalCount": totalCount])
  }

  static func emitMediaStateChanged(microphoneEnabled: Bool, cameraEnabled: Bool, speakerEnabled: Bool) {
    shared?.sendEvent(withName: LivestreamConstants.RNEvents.livestreamMediaStateChanged, body: [
      "microphoneEnabled": microphoneEnabled,
      "cameraEnabled": cameraEnabled,
      "speakerEnabled": speakerEnabled
    ])
  }

  static func emitClosedCaption(_ text: String, speakerId: String) {
    shared?.sendEvent(withName: LivestreamConstants.RNEvents.livestreamClosedCaption, body: [
      "text": text,
      "speakerId": speakerId
    ])
  }

  static func emitError(_ message: String) {
    shared?.sendEvent(withName: LivestreamConstants.RNEvents.livestreamError, body: ["message": message])
  }
}
