package ru.forbion.f7cloud.feature.tasks

import androidx.compose.ui.graphics.Color
import ru.forbion.f7cloud.core.designsystem.F7Colors
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.Locale

data class TaskGroup(
    val title: String,
    val accentColor: Color,
    val tasks: List<TaskItem>,
)

object TasksGrouping {
    private val ruDateFormatter = DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.forLanguageTag("ru-RU"))

    fun groupByDue(
        tasks: List<TaskItem>,
        sortAscending: Boolean,
    ): List<TaskGroup> {
        if (tasks.isEmpty()) return emptyList()
        val today = LocalDate.now()
        val sorted = if (sortAscending) {
            tasks.sortedWith(compareBy({ it.dueLocalDate() ?: LocalDate.MAX }, { it.summary.lowercase() }))
        } else {
            tasks.sortedWith(compareByDescending<TaskItem> { it.dueLocalDate() ?: LocalDate.MIN }
                .thenBy { it.summary.lowercase() })
        }
        val grouped = linkedMapOf<String, MutableList<TaskItem>>()
        val colors = linkedMapOf<String, Color>()
        sorted.forEach { task ->
            val date = task.dueLocalDate()
            val (title, color) = when {
                date == null -> "Без срока" to F7Colors.TextSecondary
                date == today -> "Сегодня ${date.format(ruDateFormatter)}" to F7Colors.Primary
                date == today.minusDays(1) -> "Вчера ${date.format(ruDateFormatter)}" to F7Colors.Error
                date.isBefore(today) -> date.format(ruDateFormatter) to F7Colors.Error
                else -> date.format(ruDateFormatter) to F7Colors.Primary
            }
            grouped.getOrPut(title) { mutableListOf() }.add(task)
            colors.putIfAbsent(title, color)
        }
        return grouped.map { (title, items) ->
            TaskGroup(title = title, accentColor = colors[title] ?: F7Colors.Primary, tasks = items)
        }
    }

    fun singleListGroup(listName: String, tasks: List<TaskItem>): List<TaskGroup> {
        if (tasks.isEmpty()) return emptyList()
        return listOf(
            TaskGroup(
                title = "Deck: $listName",
                accentColor = F7Colors.Primary,
                tasks = tasks,
            ),
        )
    }
}

fun TaskItem.dueLocalDate(): LocalDate? {
    if (dueRaw.isBlank()) return null
    return runCatching {
        LocalDate.parse(dueRaw.take(8), DateTimeFormatter.BASIC_ISO_DATE)
    }.getOrNull()
}

fun TaskItem.isOverdue(): Boolean {
    val date = dueLocalDate() ?: return false
    return !isCompleted && date.isBefore(LocalDate.now())
}

fun TaskItem.dueDateColor(): Color = when {
    isCompleted -> F7Colors.TextSecondary
    isOverdue() -> F7Colors.Error
    due.isNotBlank() -> F7Colors.Primary
    else -> F7Colors.TextSecondary
}
