package ru.forbion.f7cloud.feature.mail

import java.time.DayOfWeek
import java.time.Instant
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Locale

enum class MailSendLaterPreset {
    NOW,
    TOMORROW_MORNING,
    TOMORROW_AFTERNOON,
    MONDAY_MORNING,
    CUSTOM,
}

data class MailSendLaterOption(
    val preset: MailSendLaterPreset,
    val title: String,
    val sendAtEpochSeconds: Long?,
)

object MailComposeSchedule {
    private val dateLabelFormatter = DateTimeFormatter.ofPattern("d MMM", Locale("ru"))
    private val customFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm", Locale("ru"))

    fun options(now: LocalDateTime = LocalDateTime.now()): List<MailSendLaterOption> {
        val zone = ZoneId.systemDefault()
        val tomorrow = now.toLocalDate().plusDays(1)
        val mondayMorning = nextMondayMorning(now.toLocalDate())
        return listOf(
            MailSendLaterOption(MailSendLaterPreset.NOW, "Отправить сейчас", null),
            MailSendLaterOption(
                MailSendLaterPreset.TOMORROW_MORNING,
                "Завтра утром - ${formatSlot(tomorrow, LocalTime.of(9, 0))}",
                epochSeconds(tomorrow, LocalTime.of(9, 0), zone),
            ),
            MailSendLaterOption(
                MailSendLaterPreset.TOMORROW_AFTERNOON,
                "Завтра днем - ${formatSlot(tomorrow, LocalTime.of(14, 0))}",
                epochSeconds(tomorrow, LocalTime.of(14, 0), zone),
            ),
            MailSendLaterOption(
                MailSendLaterPreset.MONDAY_MORNING,
                "В понедельник утром - ${formatSlot(mondayMorning, LocalTime.of(9, 0))}",
                epochSeconds(mondayMorning, LocalTime.of(9, 0), zone),
            ),
            MailSendLaterOption(
                MailSendLaterPreset.CUSTOM,
                "Настроить дату и время",
                epochSeconds(now.toLocalDate(), now.toLocalTime().withSecond(0).withNano(0), zone),
            ),
        )
    }

    fun formatCustom(dateTime: LocalDateTime): String = customFormatter.format(dateTime)

    fun parseCustom(value: String): LocalDateTime? =
        runCatching { LocalDateTime.parse(value.trim(), customFormatter) }.getOrNull()

    private fun formatSlot(date: LocalDate, time: LocalTime): String {
        val datePart = dateLabelFormatter.format(date).replace(".", "")
        return "$datePart, ${time.format(DateTimeFormatter.ofPattern("HH:mm"))}"
    }

    private fun epochSeconds(date: LocalDate, time: LocalTime, zone: ZoneId): Long =
        LocalDateTime.of(date, time).atZone(zone).toEpochSecond()

    private fun nextMondayMorning(today: LocalDate): LocalDate {
        var date = today
        if (today.dayOfWeek == DayOfWeek.MONDAY) {
            return today
        }
        while (date.dayOfWeek != DayOfWeek.MONDAY) {
            date = date.plusDays(1)
        }
        return date
    }

    fun toInstant(epochSeconds: Long?): Instant? =
        epochSeconds?.let { Instant.ofEpochSecond(it) }
}
