package com.tt.honeyDue.util

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive

/**
 * Utility object for parsing and cleaning error messages from API responses
 */
object ErrorMessageParser {

    // Network/connection error patterns to detect
    private val networkErrorPatterns = listOf(
        "Could not connect to the server" to "Unable to connect to the server. Please check your internet connection.",
        "NSURLErrorDomain" to "Unable to connect to the server. Please check your internet connection.",
        "UnresolvedAddressException" to "Unable to connect to the server. Please check your internet connection.",
        "ConnectException" to "Unable to connect to the server. Please check your internet connection.",
        "SocketTimeoutException" to "Request timed out. Please try again.",
        "TimeoutException" to "Request timed out. Please try again.",
        "No address associated" to "Unable to connect to the server. Please check your internet connection.",
        "Network is unreachable" to "No internet connection. Please check your network settings.",
        "Connection refused" to "Unable to connect to the server. The server may be down.",
        "Connection reset" to "Connection was interrupted. Please try again.",
        "SSLHandshakeException" to "Secure connection failed. Please try again.",
        "CertificateException" to "Secure connection failed. Please try again.",
        "UnknownHostException" to "Unable to connect to the server. Please check your internet connection.",
        "java.net.SocketException" to "Connection error. Please try again.",
        "CFNetwork" to "Unable to connect to the server. Please check your internet connection.",
        "kCFStreamError" to "Unable to connect to the server. Please check your internet connection.",
        "Code=-1004" to "Unable to connect to the server. Please check your internet connection.",
        "Code=-1009" to "No internet connection. Please check your network settings.",
        "Code=-1001" to "Request timed out. Please try again."
    )

    /**
     * Parses error messages to extract user-friendly text
     * Handles network errors, JSON error responses, and raw error messages
     * @param rawMessage The raw error message from the API or exception
     * @return A user-friendly error message
     */
    fun parse(rawMessage: String): String {
        val trimmed = rawMessage.trim()

        // Check for network/connection errors first (these are technical messages from exceptions)
        for ((pattern, friendlyMessage) in networkErrorPatterns) {
            if (trimmed.contains(pattern, ignoreCase = true)) {
                return friendlyMessage
            }
        }

        // Check if it looks like a technical exception message
        if (isTechnicalError(trimmed)) {
            return "Something went wrong. Please try again."
        }

        // Check if the message looks like JSON (starts with { or [)
        if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
            // Not JSON - if it's a short, readable message, return it
            // Otherwise return a generic message
            return if (isUserFriendly(trimmed)) trimmed else "Something went wrong. Please try again."
        }

        // If it's JSON, try to parse and extract meaningful error info
        return try {
            val jsonElement = Json.parseToJsonElement(trimmed)

            if (jsonElement is kotlinx.serialization.json.JsonObject) {
                val json = jsonElement.jsonObject

                // Try to find common error fields
                json["error"]?.jsonPrimitive?.content?.let { return it }
                json["message"]?.jsonPrimitive?.content?.let { return it }
                json["detail"]?.jsonPrimitive?.content?.let { return it }

                // Check if this looks like a data object (has id, title/name, etc)
                // rather than an error response
                if (json.containsKey("id") && (json.containsKey("title") || json.containsKey("name"))) {
                    return "Request failed. Please check your input and try again."
                }
            }

            // If we couldn't extract a message, return a generic error
            "An error occurred. Please try again."
        } catch (e: Exception) {
            // JSON parsing failed, return generic error
            "An error occurred. Please try again."
        }
    }

    /**
     * Checks if the message looks like a technical/developer error (stack trace, exception, etc)
     */
    private fun isTechnicalError(message: String): Boolean {
        val technicalIndicators = listOf(
            "Exception",
            "Error Domain=",
            "UserInfo=",
            "at com.",
            "at org.",
            "at java.",
            "at kotlin.",
            "at io.",
            "Caused by:",
            "Stack trace:",
            ".kt:",
            ".java:",
            "0x",
            "Code=",
            "interface:",
            "LocalDataTask"
        )
        return technicalIndicators.any { message.contains(it, ignoreCase = true) }
    }

    /**
     * Checks if a message is user-friendly (short, no technical jargon)
     */
    private fun isUserFriendly(message: String): Boolean {
        // If it's short and doesn't contain technical indicators, it's probably user-friendly
        return message.length < 200 && !isTechnicalError(message)
    }
}
