package com.aiosman.ravenow.utils

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import coil3.ImageLoader
import coil3.network.okhttp.OkHttpNetworkFetcherFactory
import coil3.request.CachePolicy
import com.aiosman.ravenow.data.api.AuthInterceptor
import com.aiosman.ravenow.data.api.getSafeOkHttpClient
import java.io.File
import java.io.FileOutputStream
import java.util.Date
import java.util.Locale
import java.util.UUID
import java.util.concurrent.TimeUnit

object Utils {
    // 全局共享的 ImageLoader，避免每次创建导致内存缓存不共享
    private var sharedImageLoader: ImageLoader? = null
    fun generateRandomString(length: Int): String {
        val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
        return (1..length)
            .map { allowedChars.random() }
            .joinToString("")
    }

    fun getImageLoader(context: Context): ImageLoader {
        val appContext = context.applicationContext
        val existing = sharedImageLoader
        if (existing != null) return existing

        val okHttpClient = getSafeOkHttpClient(authInterceptor = AuthInterceptor())
        val loader = ImageLoader.Builder(appContext)
            .components {
                add(
                    OkHttpNetworkFetcherFactory(
                        callFactory = {
                            okHttpClient
                        }
                    )
                )
            }
            .memoryCachePolicy(CachePolicy.ENABLED)
            .diskCachePolicy(CachePolicy.ENABLED)
            .build()
        sharedImageLoader = loader
        return loader
    }

    fun getTimeAgo(date: Date): String {
        val now = Date()
        val diffInMillis = now.time - date.time

        val seconds = TimeUnit.MILLISECONDS.toSeconds(diffInMillis)
        val minutes = TimeUnit.MILLISECONDS.toMinutes(diffInMillis)
        val hours = TimeUnit.MILLISECONDS.toHours(diffInMillis)
        val days = TimeUnit.MILLISECONDS.toDays(diffInMillis)
        val years = days / 365

        return when {
            seconds < 60 -> "$seconds seconds ago"
            minutes < 60 -> "$minutes minutes ago"
            hours < 24 -> "$hours hours ago"
            days < 365 -> "$days days ago"
            else -> "$years years ago"
        }
    }

    fun getCurrentLanguage(): String {
        return Locale.getDefault().language
    }

    /**
     * 获取完整的语言标记，如 "zh-CN", "en-US"
     * 优先使用完整的 BCP-47 语言标记，提升与后端 translations 键的匹配率
     */
    fun getPreferredLanguageTag(): String {
        val locale = Locale.getDefault()
        val language = locale.language
        val country = locale.country
        
        // 如果有国家/地区代码，返回完整的语言标记
        return if (country.isNotEmpty()) {
            "$language-$country"
        } else {
            language
        }
    }

    fun compressImage(context: Context, uri: Uri, maxSize: Int = 512, quality: Int = 85): File {
        val inputStream = context.contentResolver.openInputStream(uri)
        val originalBitmap = BitmapFactory.decodeStream(inputStream)
        val (width, height) = originalBitmap.width to originalBitmap.height

        val (newWidth, newHeight) = if (width > height) {
            maxSize to (height * maxSize / width)
        } else {
            (width * maxSize / height) to maxSize
        }

        val scaledBitmap = Bitmap.createScaledBitmap(originalBitmap, newWidth, newHeight, true)
        val uuidImageName = UUID.randomUUID().toString().let { "$it.jpg" }
        val compressedFile = File(context.cacheDir, uuidImageName)
        val outputStream = FileOutputStream(compressedFile)
        if (quality > 100) {
            throw IllegalArgumentException("Quality must be less than 100")
        }
        if (quality < 0) {
            throw IllegalArgumentException("Quality must be greater than 0")
        }
        scaledBitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream)
        outputStream.flush()
        outputStream.close()

        return compressedFile
    }

    /**
     * HTML 反转义函数
     * 将 HTML 实体编码转换为对应的字符
     * 例如：&#39; -> ', &#34; -> ", &amp; -> &, &lt; -> <, &gt; -> >
     */
    fun unescapeHtml(html: String?): String {
        if (html == null) return ""
        
        return html
            .replace("&#39;", "'")
            .replace("&#34;", "\"")
            .replace("&amp;", "&")
            .replace("&lt;", "<")
            .replace("&gt;", ">")
            .replace("&quot;", "\"")
            .replace("&apos;", "'")
    }
}