package xyz.etztech.stonks.statisticsimporter

import com.beust.klaxon.*
import com.beust.klaxon.Klaxon
import java.io.File
import java.time.Instant
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.`java-time`.timestamp
import org.jetbrains.exposed.sql.transactions.transaction
import xyz.etztech.stonks.dsl.Statistics

object StatisticsImporter {
    init {}

    private val klaxon = Klaxon()

    fun importStatistics(folder: String, database: Database) {
        File(folder).listFiles().forEach { readFile(it, database) }
    }

    fun readFile(file: File, database: Database) {
        val statsFile = StatsFile.fromJson(file.readText())
        val playerId = file.nameWithoutExtension

        transaction(database) {
            val maxExpr = Statistics.value.max()

            val playerStats = emptyMap<String, MutableMap<String, Long>>().toMutableMap()

            Statistics.slice(Statistics.type, Statistics.name, maxExpr)
                    .select { Statistics.playerId.eq(playerId) }
                    .groupBy(Statistics.type, Statistics.name)
                    .forEach {
                        if (playerStats.containsKey(it[Statistics.type])) {
                            playerStats[it[Statistics.type]]?.put(
                                    it[Statistics.name], it[maxExpr]!!)
                        } else {
                            playerStats.put(
                                    it[Statistics.type],
                                    mapOf<String, Long>(it[Statistics.name] to it[maxExpr]!!)
                                            .toMutableMap())
                        }
                    }

            statsFile?.stats?.forEach { type, stats ->
                stats.forEach { name, value ->
                    if (playerStats.get(type)?.get(name) != value) {
                        Statistics.insert {
                            it[Statistics.playerId] = playerId
                            it[Statistics.type] = type
                            it[Statistics.name] = name
                            it[Statistics.timestamp] = Instant.now() as Instant
                            it[Statistics.value] = value
                        }
                    }
                }
            }
        }
    }

    data class StatsFile(val stats: Map<String, Map<String, Long>>) {
        companion object {
            public fun fromJson(json: String) = klaxon.parse<StatsFile>(json)
        }
    }
}
