package com.example.shiftalarm

import java.time.LocalDate
import java.time.ZoneId
import java.time.temporal.ChronoUnit

object ShiftCalculator {
    val SEOUL_ZONE: ZoneId = ZoneId.of("Asia/Seoul")
    val BASE_DATE: LocalDate = LocalDate.of(2026, 2, 1)
    
    // Provided list has 20 items. 
    // "석간 석간 석간 휴 휴" (5)
    // "주간 주간 주간 주간 주간 휴 휴" (7)
    // "야간 야간 야간 야간 야간 휴" (6)
    // "석간 석간" (2)
    // Total 20.
    val cycle = listOf(
        "석간", "석간", "석간", "휴무", "휴무",
        "주간", "주간", "주간", "주간", "주간", "휴무", "휴무",
        "야간", "야간", "야간", "야간", "야간", "휴무",
        "석간", "석간"
    )
    
    val CYCLE_LENGTH = cycle.size

    val TEAM_OFFSETS = mapOf(
        "A" to 0,
        "B" to 15,
        "C" to 10,
        "D" to 5
    )

    fun getShift(date: LocalDate, team: String, factory: String = "Jeonju"): String {
        return when (factory) {
            "Nonsan" -> calculateNonsanShift(date, team)
            else -> calculateJeonjuShift(date, team)
        }
    }

    private fun calculateJeonjuShift(date: LocalDate, team: String): String {
        val teamOffset = TEAM_OFFSETS[team] ?: 0
        val days = ChronoUnit.DAYS.between(BASE_DATE, date).toInt()
        val index = Math.floorMod(days + teamOffset, CYCLE_LENGTH)
        return cycle[index]
    }

    private fun calculateNonsanShift(date: LocalDate, team: String): String {
        // Nonsan Factory Logic
        // Mon-Fri: Work, Sat-Sun: Rest (Off) -> "휴무"
        // Base Date: 2026-02-09 (Monday)
        // Groups: A, B, C
        // User Requirement (Step 145):
        // Feb 9 week: Day (주간)
        // Feb 16 week: Night (야간)
        // Feb 23 week: Evening (석간)
        // Cycle: Day -> Night -> Evening
        
        val dayOfWeek = date.dayOfWeek.value // 1=Mon, ..., 7=Sun
        if (dayOfWeek >= 6) return "휴무" // Sat, Sun is OFF

        // Base Date: 2026-02-09 (Monday)
        val baseDateNonsan = LocalDate.of(2026, 2, 9)
        
        // Calculate days between Monday of the target date and base date
        // To be safe for "Any date before", we align target date to its Monday
        val targetMonday = date.minusDays((dayOfWeek - 1).toLong()) // Align to Monday
        val daysDiff = ChronoUnit.DAYS.between(baseDateNonsan, targetMonday).toInt()
        val weeksPassed = daysDiff / 7
        
        // Rotation Pattern: 주간 -> 야간 -> 석간
        // Index: 0=주간, 1=야간, 2=석간
        val rotation = listOf("주간", "야간", "석간")
        
        // Start indices for 2026-02-09 (Week 0)
        // A: 주간 (0) -> Matches User Specification
        // B, C: Distributed to other shifts.
        // Assuming A=0(Day), B=1(Night), C=2(Evening)
        
        val startOffset = when (team) {
            "A" -> 0 // 주간
            "B" -> 1 // 야간
            "C" -> 2 // 석간
            else -> 0
        }
        
        val currentIndex = Math.floorMod(startOffset + weeksPassed, 3)
        return rotation[currentIndex]
    }
}
