import audio.AudioPlayer
import codes.Somecodes.Companion.dateformat1
import codes.Somecodes.Companion.timeformat2
import com.sun.jna.Platform
import content.ContentCache
import content.ScheduleDay
import database.MariaDB
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.tinylog.Logger
import oshi.util.GlobalConfig
import web.WebApp
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.LocalTime


fun main() {
    if (Platform.isWindows()) {
        // supaya OSHI bisa mendapatkan CPU usage di Windows seperti di Task Manager
        GlobalConfig.set(GlobalConfig.OSHI_OS_WINDOWS_CPU_UTILITY, true)
    }
    Logger.info("Application started" as Any)
    val audioPlayer = AudioPlayer(44100) // 44100 Hz sampling rate
    audioPlayer.InitAudio(1)
    val content = ContentCache()
    val db = MariaDB()
    // Coroutine untuk cek Paging Queue dan AAS Queue setiap detik
    CoroutineScope(Dispatchers.Default).launch {
        while (isActive) {
            delay(1000)
            val broadcastzones = db.GetBroadcastZones()
            // baca dulu queue paging, prioritas 1
            db.Read_Queue_Paging().forEach {
                // cek apakah queue paging ada broadcast zone nya
                if (it.BroadcastZones.isNotBlank()) {
                    val zz = it.BroadcastZones.split(";")
                    // cek apakah semua target broadcast zone dari queue paging ada di dalam database broadcast zones
                    if (zz.all { z -> broadcastzones.any { bz -> bz.equals(z) } }) {
                        // semua target broadcast zone valid, sekarang cek apakah semua target broadcast zone idle

                    } else {
                        // ada broadcast zone yang tidak valid, delete from queue paging
                        db.Delete_Queue_Paging_by_index(it.index)
                        db.Add_Log("AAS", "Cancelled paging message with index ${it.index} due to invalid broadcast zone"
                        )
                    }
                } else {
                    // invalid broadcast zone, delete from queue paging
                    db.Delete_Queue_Paging_by_index(it.index)
                    db.Add_Log("AAS", "Cancelled paging message with index ${it.index} due to empty broadcast zone")
                }
            }
            // baca kemudian queue table, prioritas 2
            db.Read_Queue_Table().forEach {
                if (it.BroadcastZones.isNotBlank()) {
                    val zz = it.BroadcastZones.split(";")
                    // cek apakah semua target broadcast zone dari queue table ada di dalam database broadcast zones
                    if (zz.all { z -> broadcastzones.any { bz -> bz.equals(z) } }) {
                        // semua target broadcast zone valid, sekarang cek apakah semua target broadcast zone idle

                    } else {
                        // ada broadcast zone yang tidak valid, delete from queue table
                        db.Delete_Queue_Table_by_index(it.index)
                        db.Add_Log("AAS", "Cancelled table message with index ${it.index} due to invalid broadcast zone"
                        )
                    }
                } else {
                    // invalid broadcast zone, delete from queue table
                    db.Delete_Queue_Table_by_index(it.index)
                    db.Add_Log("AAS", "Cancelled table message with index ${it.index} due to empty broadcast zone")
                }
            }
        }

    }
    // Coroutine untuk cek Schedulebank tiap menit saat detik 00
    CoroutineScope(Dispatchers.Default).launch {
        while (isActive) {
            delay(1000)
            val localtime = LocalTime.now()
            // detik harus 00
            if (localtime.second!=0) continue
            val timestring = timeformat2.format(localtime)
            val sch = db.SchedulebankList.filter{
                it.Time==timestring && it.Enable
            }
            // tidak ada schedule dengan time sekarang dan enable=true
            if (sch.isEmpty()) continue

            val localdate = LocalDate.now()
            val ddmmyyyy = dateformat1.format(localdate)
            // check special date dulu
            val specialdate = sch.find {
                it.Day==ddmmyyyy
            }
            if (specialdate!=null) {
                // TODO Masukin ke queue table sebagai schedule special date

            }
            // cek weekly schedule
            val weekly = sch.find {
                it.Day == when(localdate.dayOfWeek){
                    DayOfWeek.MONDAY -> ScheduleDay.Monday.name
                    DayOfWeek.TUESDAY -> ScheduleDay.Tuesday.name
                    DayOfWeek.WEDNESDAY -> ScheduleDay.Wednesday.name
                    DayOfWeek.THURSDAY -> ScheduleDay.Thursday.name
                    DayOfWeek.FRIDAY -> ScheduleDay.Friday.name
                    DayOfWeek.SATURDAY -> ScheduleDay.Saturday.name
                    DayOfWeek.SUNDAY -> ScheduleDay.Sunday.name
                }
            }
            if (weekly!=null) {
                // TODO Masukin ke queue table sebagai schedule weekly

            }
            // check daily schedule
            val daily = sch.find {
                it.Day == ScheduleDay.Everyday.name
            }
            if (daily!=null) {
                // TODO Masukin ke queue table sebagai schedule daily

            }



        }
    }

    val web = WebApp(
        3030,
        listOf(
            Pair("admin", "password"),
            Pair("user", "password")
        ), db
    )
    web.Start()


}
