package de.krisenvorrat.app.data.export

import de.krisenvorrat.app.data.db.entity.CategoryEntity
import de.krisenvorrat.app.data.db.entity.ItemEntity
import de.krisenvorrat.app.data.db.entity.LocationEntity
import java.time.format.DateTimeFormatter
import java.util.Locale

internal object CsvExporter {

    private const val BOM = "\uFEFF"
    private const val SEPARATOR = ";"
    private val DATE_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy", Locale.GERMAN)

    private val HEADER = listOf(
        "Name", "Kategorie", "Menge", "Einheit", "Stückpreis",
        "kcal/kg", "MHD", "Lagerort", "Notizen"
    )

    fun export(
        items: List<ItemEntity>,
        categories: List<CategoryEntity>,
        locations: List<LocationEntity>
    ): String {
        val categoryMap = categories.associate { it.id to it.name }
        val locationMap = locations.associate { it.id to it.name }

        val sb = StringBuilder()
        sb.append(BOM)
        sb.appendLine(HEADER.joinToString(SEPARATOR))

        for (item in items) {
            val row = listOf(
                escapeCsv(item.name),
                escapeCsv(categoryMap[item.categoryId] ?: ""),
                formatQuantity(item.quantity),
                escapeCsv(item.unit),
                formatPrice(item.unitPrice),
                item.kcalPerKg?.toString() ?: "",
                item.expiryDate?.format(DATE_FORMATTER) ?: "",
                escapeCsv(locationMap[item.locationId] ?: ""),
                escapeCsv(item.notes)
            )
            sb.appendLine(row.joinToString(SEPARATOR))
        }

        return sb.toString()
    }

    private fun escapeCsv(value: String): String {
        return if (value.contains(SEPARATOR) || value.contains("\"") || value.contains("\n")) {
            "\"${value.replace("\"", "\"\"")}\""
        } else {
            value
        }
    }

    private fun formatQuantity(value: Double): String {
        return if (value == value.toLong().toDouble()) {
            value.toLong().toString()
        } else {
            String.format(Locale.GERMAN, "%.1f", value)
        }
    }

    private fun formatPrice(value: Double): String {
        return String.format(Locale.GERMAN, "%.2f", value)
    }
}
