package de.krisenvorrat.app.domain.usecase

import de.krisenvorrat.app.data.db.entity.CategoryEntity
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test

class CalculateCategorySummaryUseCaseTest {

    private val useCase = CalculateCategorySummaryUseCase()

    @Test
    fun test_invoke_withItemsInMultipleCategories_returnsCorrectSummaries() {
        // Given
        val categories = listOf(
            CategoryEntity(id = 1, name = "Konserven"),
            CategoryEntity(id = 2, name = "Getränke")
        )
        val items = listOf(
            buildTestItem(id = "1", categoryId = 1, quantity = 2.0, unitPrice = 3.00),
            buildTestItem(id = "2", categoryId = 1, quantity = 1.0, unitPrice = 5.00),
            buildTestItem(id = "3", categoryId = 2, quantity = 6.0, unitPrice = 0.50)
        )

        // When
        val result = useCase(items, categories)

        // Then
        assertEquals(2, result.size)
        val getränke = result.first { it.categoryId == 2 }
        assertEquals("Getränke", getränke.categoryName)
        assertEquals(1, getränke.itemCount)
        assertEquals(3.00, getränke.totalValue, 0.001)

        val konserven = result.first { it.categoryId == 1 }
        assertEquals("Konserven", konserven.categoryName)
        assertEquals(2, konserven.itemCount)
        assertEquals(11.00, konserven.totalValue, 0.001)
    }

    @Test
    fun test_invoke_withEmptyItemList_returnsEmptyList() {
        // Given
        val categories = listOf(CategoryEntity(id = 1, name = "Konserven"))

        // When
        val result = useCase(emptyList(), categories)

        // Then
        assertTrue(result.isEmpty())
    }

    @Test
    fun test_invoke_withUnknownCategory_usesUnbekanntAsName() {
        // Given
        val categories = emptyList<CategoryEntity>()
        val items = listOf(
            buildTestItem(id = "1", categoryId = 99, quantity = 1.0, unitPrice = 2.00)
        )

        // When
        val result = useCase(items, categories)

        // Then
        assertEquals(1, result.size)
        assertEquals("Unbekannt", result[0].categoryName)
    }

    @Test
    fun test_invoke_withSingleCategory_returnsOneSummary() {
        // Given
        val categories = listOf(CategoryEntity(id = 1, name = "Reis"))
        val items = listOf(
            buildTestItem(id = "1", categoryId = 1, quantity = 2.0, unitPrice = 1.50),
            buildTestItem(id = "2", categoryId = 1, quantity = 3.0, unitPrice = 1.50)
        )

        // When
        val result = useCase(items, categories)

        // Then
        assertEquals(1, result.size)
        assertEquals(2, result[0].itemCount)
        assertEquals(7.50, result[0].totalValue, 0.001)
    }

    @Test
    fun test_invoke_resultIsSortedByCategoryName() {
        // Given
        val categories = listOf(
            CategoryEntity(id = 1, name = "Zucker"),
            CategoryEntity(id = 2, name = "Bohnen"),
            CategoryEntity(id = 3, name = "Mehl")
        )
        val items = listOf(
            buildTestItem(id = "1", categoryId = 1, quantity = 1.0, unitPrice = 1.0),
            buildTestItem(id = "2", categoryId = 2, quantity = 1.0, unitPrice = 1.0),
            buildTestItem(id = "3", categoryId = 3, quantity = 1.0, unitPrice = 1.0)
        )

        // When
        val result = useCase(items, categories)

        // Then
        assertEquals(listOf("Bohnen", "Mehl", "Zucker"), result.map { it.categoryName })
    }
}
