package rasel.lunar.launcher.model

import io.realm.kotlin.ext.query
import io.realm.kotlin.types.RealmList
import rasel.lunar.launcher.R
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.workers.OpenWeatherGetter
import rasel.lunar.launcher.workers.WorkersDb
import java.time.Instant
import java.time.ZoneId
import java.time.ZonedDateTime
import java.util.Calendar

class ShowingWeatherInfo() {
    var textLocation: String? = null
    var amOrPm: String? = null
    var textHour: String? = null
    var dress: String? = null
    var imgDress: Int? = null
    var temp: String? = null

    fun setLocation(loc: Location?): ShowingWeatherInfo {
        textLocation = "${loc?.name ?: "도시"} / ${loc?.country ?: "나라"}"
        return this
    }
    fun setHour(hour: Hour): ShowingWeatherInfo {
        setAmOrPm(hour)
        setTextHour(hour)
        setDress(hour)
        setTemp(hour)
        return this
    }
    private fun setAmOrPm(hour: Hour) = WeatherInfoManager.toZonedDateTime(hour.time_epoch).hour.run {
        amOrPm = if (this < 12) "오전" else "오후"
    }
    private fun setTextHour(hour: Hour) {
        textHour = WeatherInfoManager.toZonedDateTime(hour.time_epoch).run {
            if (this.hour == 0) {
                when (this.dayOfYear - Calendar.getInstance().get(Calendar.DAY_OF_YEAR)) {
                    1 -> "내일"
                    2 -> "모레"
                    3 -> "글피"
                    else -> "${this.dayOfMonth}일"
                }
            } else {
                "${this.hour}시"
            }
        }
    }
    private fun setDress(hour: Hour) {
        if (hour.temp_c >= 23) {
            dress = "반팔"
            imgDress = R.drawable.dress_short_sleeves
        } else if ((23 > hour.temp_c) && (hour.temp_c >= 20)) {
            dress = "긴팔"
            imgDress = R.drawable.dress_long_sleeves
        } else if ((20 > hour.temp_c) && (hour.temp_c >= 17)) {
            dress = "니트"
            imgDress = R.drawable.dress_knitwear
        } else if ((17 > hour.temp_c) && (hour.temp_c >= 12)) {
            dress = "얇은겉옷"
            imgDress = R.drawable.dress_flimsy_outer
        } else if ((12 > hour.temp_c) && (hour.temp_c >= 6)) {
            dress = "두꺼운겉옷"
            imgDress = R.drawable.dress_heavy_outer
        } else {
            dress = "패딩"
            imgDress = R.drawable.dress_padded_coat
        }
    }
    private fun setTemp(hour: Hour) {temp = "${hour.temp_c}도"}
}

object WeatherInfoManager {
    var info: WeatherForcast? = null
//    var showingInfo: ShowingWeatherInfo? = null


//    fun setInfo(data: WeatherForcast) {
//        this.info = data
//        BLog.LOGE("Now WeatherForcast updated. info : ${this.info}")
//    }

    fun readyForSaving(lat: Double, lon: Double) {
        this.info?.lastUpdateTime = System.currentTimeMillis()
        this.fill()
        setLatitudeAndLongitude(lat, lon)
    }

    private fun setLatitudeAndLongitude(lat: Double, lon: Double) {
        info?.forecast?.forecastdayRealm?.forEach {
            it.hourRealm.forEach {h ->
                h.lat = lat
                h.lon = lon
            }
        }
    }

    private fun fill() {
        getForecast()?.let {
            if (it.forecastdayRealm.addAll(it.forecastday)) {
                it.forecastdayRealm.forEach { f -> f.hourRealm.addAll(f.hour) }
            }
        }
    }

    fun toZonedDateTime(timeEpoch: Int): ZonedDateTime = Instant.ofEpochSecond(timeEpoch.toLong())
        .atZone(ZoneId.systemDefault())

    fun getShowingInfo(hour: Hour): ShowingWeatherInfo = ShowingWeatherInfo().setLocation(getLocation()).setHour(hour)


    private fun getLocation(): Location? {
        return if (info?.location == null) {
            WorkersDb.getRealm().query<Location>().also {
                BLog.LOGE("re >>> ${it.description()}") // 쿼리 로그
            }.find().first()
        } else {
            info?.location
        }
    }

    fun getForecast(): Forecast? = info?.forecast
    fun getAllForecastDay(): RealmList<Forecastday>? = getForecast()?.forecastdayRealm
    fun getAllHour(day: Forecastday): RealmList<Hour> = day.hourRealm
}