package de.tsschulz.timeclock.data.time

import de.tsschulz.timeclock.data.api.TimeClockApiClient
import de.tsschulz.timeclock.data.api.TimeEntryDto
import de.tsschulz.timeclock.data.api.TimeStatsDto
import de.tsschulz.timeclock.data.api.WeekOverviewDto
import de.tsschulz.timeclock.data.offline.OfflineClockQueue
import java.io.IOException

class TimeRepository(
    private val api: TimeClockApiClient,
    private val offlineClockQueue: OfflineClockQueue? = null,
) {
    suspend fun loadDashboard(): TimeDashboard {
        syncOfflineClockActions()
        val state = api.getCurrentState().state
        val running = api.getRunningEntry()
        val stats = api.getTimeStats()
        return TimeDashboard(
            state = state,
            runningStartTime = running.startTime,
            currentPauseStart = running.currentPauseStart,
            stats = stats,
        )
    }

    suspend fun clock(action: String): TimeDashboard {
        val response = try {
            api.postClock(action)
        } catch (e: IOException) {
            offlineClockQueue?.enqueue(action)
            throw IllegalStateException("Keine Verbindung. Die Stempelaktion wurde offline gespeichert und wird später synchronisiert.", e)
        }
        if (!response.success) {
            throw IllegalStateException(response.error ?: "Stempeln fehlgeschlagen")
        }
        return loadDashboard()
    }

    suspend fun loadWeek(weekOffset: Int): WeekOverviewDto {
        val response = api.getWeekOverview(weekOffset)
        if (!response.success || response.data == null) {
            throw IllegalStateException(response.error ?: "Wochenübersicht konnte nicht geladen werden")
        }
        return response.data
    }

    suspend fun loadEntries(): List<TimeEntryDto> = api.getTimeEntries()
    suspend fun deleteEntry(id: String) = api.deleteTimeEntry(id)
    suspend fun loadStats(): TimeStatsDto = api.getTimeStats()

    private suspend fun syncOfflineClockActions() {
        val queue = offlineClockQueue ?: return
        queue.pending().forEach { pending ->
            try {
                val response = api.postClock(pending.action)
                if (response.success) queue.remove(pending.id)
            } catch (_: IOException) {
                return
            }
        }
    }
}

data class TimeDashboard(
    val state: String?,
    val runningStartTime: String?,
    val currentPauseStart: String?,
    val stats: TimeStatsDto,
)
