package com.sunzones.domain.usecase

import com.sunzones.domain.model.MonthDaylight
import org.shredzone.commons.suncalc.SunTimes
import java.time.Duration
import java.time.LocalDate
import java.time.Month
import java.time.ZoneId
import javax.inject.Inject

class CalculateYearlyDaylightUseCase @Inject constructor() {

    operator fun invoke(
        latitude: Double,
        longitude: Double,
        timezoneId: String
    ): List<MonthDaylight> {
        val zoneId = ZoneId.of(timezoneId)
        val year = LocalDate.now(zoneId).year

        return Month.entries.map { month ->
            val representativeDay = LocalDate.of(year, month, 15)

            val sunTimes = SunTimes.compute()
                .on(representativeDay)
                .at(latitude, longitude)
                .timezone(zoneId)
                .execute()

            val sunrise = sunTimes.rise?.toLocalTime()
            val sunset = sunTimes.set?.toLocalTime()

            val isAlwaysUp = sunTimes.isAlwaysUp
            val isAlwaysDown = sunTimes.isAlwaysDown

            val dayLengthMinutes: Long
            val sunriseMinuteOfDay: Int
            val sunsetMinuteOfDay: Int

            when {
                isAlwaysUp -> {
                    dayLengthMinutes = 1440L
                    sunriseMinuteOfDay = 0
                    sunsetMinuteOfDay = 1440
                }
                isAlwaysDown -> {
                    dayLengthMinutes = 0L
                    sunriseMinuteOfDay = 0
                    sunsetMinuteOfDay = 0
                }
                sunrise != null && sunset != null -> {
                    dayLengthMinutes = Duration.between(sunrise, sunset).toMinutes()
                    sunriseMinuteOfDay = sunrise.hour * 60 + sunrise.minute
                    sunsetMinuteOfDay = sunset.hour * 60 + sunset.minute
                }
                else -> {
                    dayLengthMinutes = 0L
                    sunriseMinuteOfDay = 0
                    sunsetMinuteOfDay = 0
                }
            }

            val hours = dayLengthMinutes / 60
            val minutes = dayLengthMinutes % 60
            val dayLengthFormatted = "${hours}h ${minutes}m"

            MonthDaylight(
                month = month,
                dayLengthMinutes = dayLengthMinutes,
                sunriseMinuteOfDay = sunriseMinuteOfDay,
                sunsetMinuteOfDay = sunsetMinuteOfDay,
                dayLengthFormatted = dayLengthFormatted
            )
        }
    }
}
