package ru.forbion.f7cloud.feature.files

import okhttp3.FormBody
import okhttp3.Request
import org.json.JSONObject
import ru.forbion.f7cloud.core.auth.AuthSession
import ru.forbion.f7cloud.core.network.NetworkFactory
import ru.forbion.f7cloud.core.network.UnauthorizedException

class RichdocumentsRepository {
    /**
     * Создаёт одноразовую ссылку Direct Editing (Collabora / Richdocuments).
     * @see OCA\Richdocuments\Controller\OCSController::createDirect
     */
    fun createDirectUrl(session: AuthSession, fileId: Long): String {
        val client = officeClient(session)
        val url = "${session.serverUrl.trimEnd('/')}/ocs/v2.php/apps/richdocuments/api/v1/document?format=json"
        val body = FormBody.Builder()
            .add("fileId", fileId.toString())
            .build()
        val request = Request.Builder()
            .url(url)
            .header("OCS-APIRequest", "true")
            .header("Accept", "application/json")
            .post(body)
            .build()
        client.newCall(request).execute().use { response ->
            if (!response.isSuccessful || response.body == null) {
                error("Richdocuments HTTP ${response.code}")
            }
            val ocs = JSONObject(response.body!!.string()).optJSONObject("ocs")
                ?: error("Некорректный ответ Richdocuments")
            val meta = ocs.optJSONObject("meta")
            if (meta?.optString("status").equals("failure", ignoreCase = true)) {
                error(meta?.optString("message").orEmpty().ifBlank { "Richdocuments error" })
            }
            val editorUrl = ocs.optJSONObject("data")?.optString("url").orEmpty()
            if (editorUrl.isBlank()) error("Richdocuments не вернул URL редактора")
            return editorUrl
        }
    }

    /**
     * Public Collabora URL from F7cloud capabilities (used for WebView intercept + auth hosts).
     */
    fun fetchCollaboraPublicUrl(session: AuthSession): String {
        val client = officeClient(session)
        val url = "${session.serverUrl.trimEnd('/')}/ocs/v2.php/cloud/capabilities?format=json"
        val request = Request.Builder()
            .url(url)
            .header("OCS-APIRequest", "true")
            .header("Accept", "application/json")
            .get()
            .build()
        return runCatching {
            client.newCall(request).execute().use { response ->
                if (!response.isSuccessful || response.body == null) return ""
                val data = JSONObject(response.body!!.string())
                    .optJSONObject("ocs")
                    ?.optJSONObject("data")
                    ?: return ""
                data.optJSONObject("capabilities")
                    ?.optJSONObject("richdocuments")
                    ?.optJSONObject("config")
                    ?.optString("public_wopi_url")
                    .orEmpty()
                    .trim()
            }
        }.getOrDefault("")
    }

    private fun officeClient(session: AuthSession) =
        NetworkFactory.newAuthedClientForOffice(
            session.username,
            session.appPassword,
            session.trustAllCerts,
        )
}
