import audio.AudioUtility
import audio.OpusStreamReceiver
import somecodes.Codes.Companion.ValidString
import web.webApp
import zello.ZelloClient
import zello.ZelloEvent

//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
fun main() {
    val au = AudioUtility()
    var audioID = 0
    val preferedAudioDevice = "Speakers"
    au.DetectPlaybackDevices().forEach { pair ->
        println("Device ID: ${pair.first}, Name: ${pair.second}")
        if (pair.second.contains(preferedAudioDevice)) {
            audioID = pair.first
        }
    }
    if (audioID!=0){
        val initsuccess = au.InitDevice(audioID)
        println("Audio Device $audioID initialized: $initsuccess")
    }

    val o = OpusStreamReceiver(audioID)

    val w = webApp("0.0.0.0",3030, javafx.util.Pair("admin","admin1234"))
    w.Start()

    val z = ZelloClient.fromConsumerZello("gtcdevice01","GtcDev2025")
    z.Start(object : ZelloEvent {
        override fun onChannelStatus(
            channel: String,
            status: String,
            userOnline: Int,
            error: String?,
            errorType: String?
        ) {
            println("Channel Status: $channel is $status with $userOnline users online.")
            if (ValidString(error) && ValidString(errorType)) {
                println("Error: $error, Type: $errorType")
            }
        }

        override fun onAudioData(streamID: Int, from: String, For: String, channel: String, data: ByteArray) {
            println("Audio Data received from $from for $For on channel $channel with streamID $streamID ")
        }

        override fun onThumbnailImage(imageID: Int, from: String, For: String, channel: String, data: ByteArray, timestamp: Long) {
            println("Thumbnail Image received from $from for $For on channel $channel with imageID $imageID at timestamp $timestamp")
        }

        override fun onFullImage(imageID: Int, from: String, For: String, channel: String, data: ByteArray, timestamp: Long) {
            println("Full Image received from $from for $For on channel $channel with imageID $imageID at timestamp $timestamp")
        }

        override fun onTextMessage(messageID: Int, from: String, For: String, channel: String, text: String, timestamp: Long) {
            println("Text Message received from $from for $For on channel $channel with messageID $messageID at timestamp $timestamp. Text: $text")
        }

        override fun onLocation(messageID: Int, from: String, For: String, channel: String, latitude: Double, longitude: Double, address: String, accuracy: Double, timestamp: Long) {
            println("Location received from $from for $For on channel $channel with messageID $messageID at timestamp $timestamp. Location($latitude,$longitude), Address:$address, Accuracy:$accuracy")
        }

        override fun onConnected() {
            println("Connected to Zello server.")
        }

        override fun onDisconnected() {
            println("Disconnected from Zello server.")
        }

        override fun onError(errorMessage: String) {
            println("Error occurred in Zello client: $errorMessage")
        }

        override fun onStartStreaming(from: String, For: String, channel: String) {
            if (o.Start()){
                println("Opus Receiver ready for streaming from $from for $For on channel $channel")
            } else {
                println("Failed to start Opus Receiver for streaming from $from for $For on channel $channel")
            }
        }

        override fun onStopStreaming(from: String, For: String, channel: String) {
            o.Stop()
            println("Opus Receiver stopped streaming from $from for $For on channel $channel")
        }

        override fun onStreamingData(
            from: String,
            For: String,
            channel: String,
            data: ByteArray
        ) {
            if (o.isPlaying) o.PushData(data)
        }
    })

}