package de.arxsilex.maptools.converter.desktop

import de.arxsilex.maptools.converter.core.MapSelectionShape

internal data class AreaSelectionHistory(
    private val undoStates: List<List<MapSelectionShape>> = emptyList(),
    private val redoStates: List<List<MapSelectionShape>> = emptyList(),
) {
    val canUndo: Boolean get() = undoStates.isNotEmpty()
    val canRedo: Boolean get() = redoStates.isNotEmpty()

    fun record(
        before: List<MapSelectionShape>,
        after: List<MapSelectionShape>,
    ): AreaSelectionHistory {
        if (before == after) return this
        return AreaSelectionHistory(
            undoStates = (undoStates + listOf(before.toList())).takeLast(HISTORY_LIMIT),
            redoStates = emptyList(),
        )
    }

    fun undo(current: List<MapSelectionShape>): HistoryStep? {
        val target = undoStates.lastOrNull() ?: return null
        return HistoryStep(
            areas = target,
            history = AreaSelectionHistory(
                undoStates = undoStates.dropLast(1),
                redoStates = (redoStates + listOf(current.toList())).takeLast(HISTORY_LIMIT),
            ),
        )
    }

    fun redo(current: List<MapSelectionShape>): HistoryStep? {
        val target = redoStates.lastOrNull() ?: return null
        return HistoryStep(
            areas = target,
            history = AreaSelectionHistory(
                undoStates = (undoStates + listOf(current.toList())).takeLast(HISTORY_LIMIT),
                redoStates = redoStates.dropLast(1),
            ),
        )
    }

    companion object {
        const val HISTORY_LIMIT = 20
    }
}

internal data class HistoryStep(
    val areas: List<MapSelectionShape>,
    val history: AreaSelectionHistory,
)
