package com.example.shiftalarm

import android.content.Context
import java.time.LocalDate
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

class ShiftRepository(private val context: Context) {
    private val db = AppDatabase.getDatabase(context)
    private val dao = db.shiftDao()

    suspend fun getShift(date: LocalDate, team: String, factory: String): String = withContext(Dispatchers.IO) {
        try {
            val override = dao.getOverride(factory, team, date.toString())
            if (override != null) {
                return@withContext override.shift
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        ShiftCalculator.getShift(date, team, factory)
    }

    suspend fun setOverride(date: LocalDate, shift: String, team: String, factory: String) = withContext(Dispatchers.IO) {
        try {
            dao.insertOverride(ShiftOverride(factory, team, date.toString(), shift))
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    suspend fun clearOverride(date: LocalDate, team: String, factory: String) = withContext(Dispatchers.IO) {
        try {
            dao.deleteOverride(factory, team, date.toString())
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    suspend fun getMemo(date: LocalDate): String? = withContext(Dispatchers.IO) {
        try {
            dao.getMemo(date.toString())?.content
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

    suspend fun setMemo(date: LocalDate, content: String) = withContext(Dispatchers.IO) {
        try {
            if (content.isEmpty()) {
                dao.deleteMemo(date.toString())
            } else {
                dao.insertMemo(DailyMemo(date.toString(), content))
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    // Custom Alarms
    suspend fun getAllCustomAlarms(): List<CustomAlarm> = withContext(Dispatchers.IO) {
        try {
            val list = dao.getAllCustomAlarms()
            if (list.isEmpty()) {
                val defaults = listOf(
                    CustomAlarm(time = "07:00", shiftType = "주간", isEnabled = true),
                    CustomAlarm(time = "15:00", shiftType = "석간", isEnabled = true),
                    CustomAlarm(time = "23:00", shiftType = "야간", isEnabled = true)
                )
                for (d in defaults) {
                    dao.insertCustomAlarm(d)
                }
                return@withContext dao.getAllCustomAlarms()
            }
            list
        } catch (e: Exception) {
            e.printStackTrace()
            emptyList()
        }
    }

    suspend fun addCustomAlarm(alarm: CustomAlarm): Long = withContext(Dispatchers.IO) {
        try {
            dao.insertCustomAlarm(alarm)
        } catch (e: Exception) {
            e.printStackTrace()
            -1L
        }
    }

    suspend fun updateCustomAlarm(alarm: CustomAlarm) = withContext(Dispatchers.IO) {
        try {
            dao.updateCustomAlarm(alarm)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    suspend fun deleteCustomAlarm(alarm: CustomAlarm) = withContext(Dispatchers.IO) {
        try {
            dao.deleteCustomAlarm(alarm)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    suspend fun clearAllCustomAlarms() = withContext(Dispatchers.IO) {
        try {
            dao.clearCustomAlarms()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    // Annual Leave
    suspend fun calculateUsedAnnualLeave(): Float = withContext(Dispatchers.IO) {
        try {
            val currentYear = java.time.Year.now(java.time.ZoneId.of("Asia/Seoul")).toString()
            val overrides = dao.getAllOverrides()

            var usedDays = 0f
            for (override in overrides) {
                if (override.date.startsWith(currentYear)) {
                    when (override.shift) {
                        "연차" -> usedDays += 1f
                        "반년" -> usedDays += 0.5f
                    }
                }
            }
            usedDays
        } catch (e: Exception) {
            e.printStackTrace()
            0f
        }
    }

    suspend fun getAnnualLeave(): AnnualLeave? = withContext(Dispatchers.IO) {
        try {
            dao.getAnnualLeave()
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

    suspend fun recalculateAndSaveAnnualLeave(totalDays: Float) = withContext(Dispatchers.IO) {
        try {
            val usedDays = calculateUsedAnnualLeave()
            val remainingDays = totalDays - usedDays
            
            dao.insertAnnualLeave(AnnualLeave(
                id = 1,
                totalDays = totalDays,
                remainingDays = remainingDays
            ))
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    suspend fun updateRemainingAnnualLeave() = withContext(Dispatchers.IO) {
        try {
            val annualLeave = dao.getAnnualLeave()
            val usedDays = calculateUsedAnnualLeave()
            
            if (annualLeave != null) {
                val remainingDays = annualLeave.totalDays - usedDays
                dao.insertAnnualLeave(annualLeave.copy(remainingDays = remainingDays))
            } else {
                dao.insertAnnualLeave(AnnualLeave(
                    id = 1,
                    totalDays = 15f,
                    remainingDays = 15f - usedDays
                ))
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    suspend fun getSaturdayOvertimeHours(): Int = withContext(Dispatchers.IO) {
        getMonthlyOvertimeHours(java.time.YearMonth.now())
    }

    suspend fun getMonthlyOvertimeHours(yearMonth: java.time.YearMonth = java.time.YearMonth.now()): Int = withContext(Dispatchers.IO) {
        try {
            var totalHours = 0
            var date = yearMonth.atDay(1)
            val lastDay = yearMonth.atEndOfMonth()
            
            // 1. 토요일 기본 특근 (1일당 2시간)
            while (!date.isAfter(lastDay)) {
                if (date.dayOfWeek == java.time.DayOfWeek.SATURDAY) {
                    totalHours += 2
                }
                date = date.plusDays(1)
            }

            // 2. 해당 월의 커스텀 지정 근무 복합 가산 (주맞/야맞 +4시간, 교육 +2시간)
            val monthStr = yearMonth.toString()
            val overrides = dao.getAllOverrides().filter { it.date.startsWith(monthStr) }
            for (override in overrides) {
                when (override.shift) {
                    "주간 맞교대", "주맞" -> totalHours += 4
                    "야간 맞교대", "야맞" -> totalHours += 4
                    "교육" -> totalHours += 2
                }
            }

            totalHours
        } catch (e: Exception) {
            e.printStackTrace()
            0
        }
    }
}
