package com.amz.genie.helpers

import com.google.gson.JsonArray
import com.google.gson.JsonObject
import java.util.Locale

data class AttachmentItem(
    val label: String,        // "PDF", "JPG"
    val fileName: String,     // "xxx.jpg"
    val relativePath: String, // "aksi/30030/xxx.jpg" / "aksi_lampiran/16/xxx.jpg" / "reaksi/xxx.jpg"
    val url: String           // full url
)

private enum class Source { AKSI, REAKSI, AKSI_LAMPIRAN, UNKNOWN }

object AttachmentExtractor {
    fun extractAll(msg: JsonObject?): List<AttachmentItem> {
        if (msg == null) return emptyList()

        val base = Preferences.BASE_UPLOAD_URL.trimEnd('/') // contoh: https://api.../uploads
        val out = mutableListOf<AttachmentItem>()

        // A) lampiran umum (aksi) -> path_to_arsip: "aksi/30030/xxx.jpg"
        out += extractFromArray(
            arr = msg.getArray("lampiran"),
            baseUrl = base,
            defaultSource = Source.AKSI,
            possiblePathKeys = listOf("path_to_arsip", "path", "isian", "file", "filename")
        )

        // B) lampiran reaksi -> kadang cuma filename "Screenshot_....jpg"
        out += extractFromArray(
            arr = msg.getArray("lampiran_reaksi"),
            baseUrl = base,
            defaultSource = Source.REAKSI,
            possiblePathKeys = listOf("path_to_arsip", "path", "isian", "file", "filename")
        )

        // C) komunikasi detail lampiran -> isian/nilai/value: "aksi_lampiran/16/xxx.jpg"
        out += extractFromArray(
            arr = msg.getArray("aksi_komunikasi_lampiran"),
            baseUrl = base,
            defaultSource = Source.AKSI_LAMPIRAN,
            possiblePathKeys = listOf("nilai", "value", "isian", "path", "path_to_arsip", "filename")
        )

        // D) fallback (optional)
        val fallbackKeys = listOf("aksi_komunikasi_teks", "aksi_komunikasi_string")
        for (k in fallbackKeys) {
            out += extractFromArray(
                arr = msg.getArray(k),
                baseUrl = base,
                defaultSource = Source.UNKNOWN,
                possiblePathKeys = listOf("nilai", "value", "isian", "path", "path_to_arsip", "filename")
            )
        }

        return out.distinctBy { it.url }
    }

    private fun extractFromArray(
        arr: JsonArray?,
        baseUrl: String,
        defaultSource: Source,
        possiblePathKeys: List<String>
    ): List<AttachmentItem> {
        if (arr == null || arr.size() == 0) return emptyList()

        val out = mutableListOf<AttachmentItem>()

        for (el in arr) {
            if (!el.isJsonObject) continue
            val obj = el.asJsonObject

            val rawPath = pickFirstString(obj, possiblePathKeys)?.trim().orEmpty()
            if (rawPath.isBlank()) continue

            val normalized = normalizeRelativePath(rawPath, defaultSource) ?: continue

            val fileName = normalized.substringAfterLast('/')
            if (fileName.isBlank()) continue

            val ext = fileName.substringAfterLast('.', missingDelimiterValue = "")
                .lowercase(Locale.getDefault())

            val label = if (ext.isBlank()) "FILE" else ext.uppercase(Locale.getDefault())
            val url = "$baseUrl/$normalized"

            out += AttachmentItem(
                label = label,
                fileName = fileName,
                relativePath = normalized,
                url = url
            )
        }

        return out
    }

    private fun pickFirstString(obj: JsonObject, keys: List<String>): String? {
        for (k in keys) {
            val el = obj.get(k) ?: continue
            if (el.isJsonNull) continue
            val s = runCatching { el.asString }.getOrNull()
            if (!s.isNullOrBlank()) return s
        }
        return null
    }

    /**
     * Sesuai data DB kamu:
     * - aksi: "aksi/30030/...."
     * - aksi_lampiran: "aksi_lampiran/16/...."
     * - reaksi: kadang cuma filename -> jadi "reaksi/<filename>"
     */
    private fun normalizeRelativePath(raw: String, defaultSource: Source): String? {
        val p = raw.replace("\\", "/").trim().trimStart('/')
        if (p.isBlank()) return null

        val lower = p.lowercase(Locale.getDefault())
        if (lower.startsWith("aksi/") || lower.startsWith("aksi_lampiran/") || lower.startsWith("reaksi/")) {
            return p
        }

        // cuma filename
        return when (defaultSource) {
            Source.REAKSI -> "reaksi/$p"
            Source.AKSI -> "aksi/$p"
            Source.AKSI_LAMPIRAN -> "aksi_lampiran/$p"
            Source.UNKNOWN -> p
        }
    }
}

// extension helper
private fun JsonObject.getArray(key: String) =
    get(key)?.takeIf { it.isJsonArray }?.asJsonArray