package com.applemand.zmanim.core.jewcal

import com.kosherjava.zmanim.hebrewcalendar.JewishCalendar
import com.kosherjava.zmanim.hebrewcalendar.JewishCalendar.Parsha
import kotlinx.datetime.DayOfWeek
import kotlinx.datetime.LocalDate
import kotlinx.datetime.DateTimeUnit
import kotlinx.datetime.plus

data class Parasha(
    val parsha: Parsha,
    val nameEn: String,
    val nameHe: String,
    val isCombined: Boolean,
)

class ParashaCalculator(private val inIsrael: Boolean = false) {

    fun forWeekOf(date: LocalDate): Parasha? {
        // Shift to the upcoming (or current) Shabbat.
        val delta = (DayOfWeek.SATURDAY.ordinal - date.dayOfWeek.ordinal + 7) % 7
        val shabbat = date.plus(delta, DateTimeUnit.DAY)

        val jc = shabbat.toJewishCalendar().also { it.inIsrael = inIsrael }
        val p = jc.parshah ?: return null
        if (p == Parsha.NONE) return null
        val combined = p.name.contains("_") // KosherJava names combined parshiyot with underscores
        return Parasha(
            parsha = p,
            nameEn = ParashaNames.en(p),
            nameHe = ParashaNames.he(p),
            isCombined = combined,
        )
    }
}

/**
 * Localized parasha names.  English = KosherJava names cleaned up; Hebrew = printed siddur form.
 */
internal object ParashaNames {
    private val en = mapOf(
        Parsha.BERESHIS to "Bereshit", Parsha.NOACH to "Noach", Parsha.LECH_LECHA to "Lech Lecha",
        Parsha.VAYERA to "Vayera", Parsha.CHAYEI_SARA to "Chayei Sarah", Parsha.TOLDOS to "Toldot",
        Parsha.VAYETZEI to "Vayetzei", Parsha.VAYISHLACH to "Vayishlach", Parsha.VAYESHEV to "Vayeshev",
        Parsha.MIKETZ to "Miketz", Parsha.VAYIGASH to "Vayigash", Parsha.VAYECHI to "Vayechi",
        Parsha.SHEMOS to "Shemot", Parsha.VAERA to "Vaera", Parsha.BO to "Bo", Parsha.BESHALACH to "Beshalach",
        Parsha.YISRO to "Yitro", Parsha.MISHPATIM to "Mishpatim", Parsha.TERUMAH to "Terumah",
        Parsha.TETZAVEH to "Tetzaveh", Parsha.KI_SISA to "Ki Tisa",
        Parsha.VAYAKHEL to "Vayakhel", Parsha.PEKUDEI to "Pekudei", Parsha.VAYAKHEL_PEKUDEI to "Vayakhel-Pekudei",
        Parsha.VAYIKRA to "Vayikra", Parsha.TZAV to "Tzav", Parsha.SHMINI to "Shemini",
        Parsha.TAZRIA to "Tazria", Parsha.METZORA to "Metzora", Parsha.TAZRIA_METZORA to "Tazria-Metzora",
        Parsha.ACHREI_MOS to "Acharei Mot", Parsha.KEDOSHIM to "Kedoshim",
        Parsha.ACHREI_MOS_KEDOSHIM to "Acharei Mot-Kedoshim", Parsha.EMOR to "Emor",
        Parsha.BEHAR to "Behar", Parsha.BECHUKOSAI to "Bechukotai", Parsha.BEHAR_BECHUKOSAI to "Behar-Bechukotai",
        Parsha.BAMIDBAR to "Bamidbar", Parsha.NASSO to "Nasso", Parsha.BEHAALOSCHA to "Beha'alotcha",
        Parsha.SHLACH to "Shelach", Parsha.KORACH to "Korach", Parsha.CHUKAS to "Chukat",
        Parsha.BALAK to "Balak", Parsha.CHUKAS_BALAK to "Chukat-Balak",
        Parsha.PINCHAS to "Pinchas", Parsha.MATOS to "Matot", Parsha.MASEI to "Masei",
        Parsha.MATOS_MASEI to "Matot-Masei",
        Parsha.DEVARIM to "Devarim", Parsha.VAESCHANAN to "Vaetchanan", Parsha.EIKEV to "Ekev",
        Parsha.REEH to "Re'eh", Parsha.SHOFTIM to "Shoftim", Parsha.KI_SEITZEI to "Ki Teitzei",
        Parsha.KI_SAVO to "Ki Tavo", Parsha.NITZAVIM to "Nitzavim", Parsha.VAYEILECH to "Vayelech",
        Parsha.NITZAVIM_VAYEILECH to "Nitzavim-Vayelech", Parsha.HAAZINU to "Haazinu",
        Parsha.VZOS_HABERACHA to "V'Zot HaBerachah",
    )
    private val he = mapOf(
        Parsha.BERESHIS to "בראשית", Parsha.NOACH to "נח", Parsha.LECH_LECHA to "לך לך",
        Parsha.VAYERA to "וירא", Parsha.CHAYEI_SARA to "חיי שרה", Parsha.TOLDOS to "תולדות",
        Parsha.VAYETZEI to "ויצא", Parsha.VAYISHLACH to "וישלח", Parsha.VAYESHEV to "וישב",
        Parsha.MIKETZ to "מקץ", Parsha.VAYIGASH to "ויגש", Parsha.VAYECHI to "ויחי",
        Parsha.SHEMOS to "שמות", Parsha.VAERA to "וארא", Parsha.BO to "בא", Parsha.BESHALACH to "בשלח",
        Parsha.YISRO to "יתרו", Parsha.MISHPATIM to "משפטים", Parsha.TERUMAH to "תרומה",
        Parsha.TETZAVEH to "תצוה", Parsha.KI_SISA to "כי תשא",
        Parsha.VAYAKHEL to "ויקהל", Parsha.PEKUDEI to "פקודי", Parsha.VAYAKHEL_PEKUDEI to "ויקהל־פקודי",
        Parsha.VAYIKRA to "ויקרא", Parsha.TZAV to "צו", Parsha.SHMINI to "שמיני",
        Parsha.TAZRIA to "תזריע", Parsha.METZORA to "מצורע", Parsha.TAZRIA_METZORA to "תזריע־מצורע",
        Parsha.ACHREI_MOS to "אחרי מות", Parsha.KEDOSHIM to "קדושים",
        Parsha.ACHREI_MOS_KEDOSHIM to "אחרי מות־קדושים", Parsha.EMOR to "אמור",
        Parsha.BEHAR to "בהר", Parsha.BECHUKOSAI to "בחוקותי", Parsha.BEHAR_BECHUKOSAI to "בהר־בחוקותי",
        Parsha.BAMIDBAR to "במדבר", Parsha.NASSO to "נשא", Parsha.BEHAALOSCHA to "בהעלותך",
        Parsha.SHLACH to "שלח", Parsha.KORACH to "קורח", Parsha.CHUKAS to "חוקת",
        Parsha.BALAK to "בלק", Parsha.CHUKAS_BALAK to "חוקת־בלק",
        Parsha.PINCHAS to "פינחס", Parsha.MATOS to "מטות", Parsha.MASEI to "מסעי",
        Parsha.MATOS_MASEI to "מטות־מסעי",
        Parsha.DEVARIM to "דברים", Parsha.VAESCHANAN to "ואתחנן", Parsha.EIKEV to "עקב",
        Parsha.REEH to "ראה", Parsha.SHOFTIM to "שופטים", Parsha.KI_SEITZEI to "כי תצא",
        Parsha.KI_SAVO to "כי תבוא", Parsha.NITZAVIM to "נצבים", Parsha.VAYEILECH to "וילך",
        Parsha.NITZAVIM_VAYEILECH to "נצבים־וילך", Parsha.HAAZINU to "האזינו",
        Parsha.VZOS_HABERACHA to "וזאת הברכה",
    )

    fun en(p: Parsha): String = en[p] ?: p.name
    fun he(p: Parsha): String = he[p] ?: p.name
}
