package com.doctate.watch.net

import android.util.Log
import com.doctate.watch.domain.OnelinersResponse
import com.doctate.watch.domain.onelinersResponseToJson
import com.doctate.watch.domain.parseOnelinersResponse
import java.io.File
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import org.json.JSONObject

/**
 * Disk-persisted copy of the most recent `/api/oneliners` response and
 * its ETag. Loaded on cold-start so the watch can render its case list
 * before any network round-trip — the user never sees a blank list flash
 * just because the service hasn't polled yet.
 *
 * Mirrors `doctate-desktop::snapshot_cache`.
 */
data class CachedSnapshot(
    val etag: String,
    val fetchedAt: String,
    val response: OnelinersResponse,
)

class SnapshotCache(private val file: File) {

    fun load(): CachedSnapshot? {
        if (!file.exists()) return null
        return try {
            val obj = JSONObject(file.readText(Charsets.UTF_8))
            CachedSnapshot(
                etag = obj.getString("etag"),
                fetchedAt = obj.getString("fetched_at"),
                response = parseOnelinersResponse(obj.getString("response")),
            )
        } catch (e: Exception) {
            Log.w(TAG, "snapshot cache load failed: ${e.message} — starting fresh")
            null
        }
    }

    fun store(snapshot: CachedSnapshot) {
        file.parentFile?.takeIf { !it.exists() }?.mkdirs()
        val tmp = File(file.parentFile, "${file.name}.tmp")
        val payload = JSONObject().apply {
            put("etag", snapshot.etag)
            put("fetched_at", snapshot.fetchedAt)
            put("response", onelinersResponseToJson(snapshot.response))
        }.toString()
        tmp.writeText(payload, Charsets.UTF_8)
        Files.move(
            tmp.toPath(),
            file.toPath(),
            StandardCopyOption.REPLACE_EXISTING,
            StandardCopyOption.ATOMIC_MOVE,
        )
    }

    fun clear() {
        if (file.exists() && !file.delete()) {
            Log.w(TAG, "snapshot cache clear failed: ${file.name}")
        }
    }

    companion object {
        private const val TAG = "SnapshotCache"
    }
}
