package com.stand.standapp

import android.app.ProgressDialog
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore
import timber.log.Timber
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import okhttp3.*
import org.json.JSONObject
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream

class UpdateManager(private val context: Context) {

    private var progressDialog: ProgressDialog? = null
    private val handler = Handler(Looper.getMainLooper())
    private var call: Call? = null
    private val fileName = "StandApp_Update.apk"

    /**
     * 获取或创建公共下载目录下的文件 URI
     */
    private fun getPublicDownloadUri(): Uri? {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val contentValues = ContentValues().apply {
                put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
                put(MediaStore.MediaColumns.MIME_TYPE, "application/vnd.android.package-archive")
                put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
            }
            val contentResolver = context.contentResolver
            return contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)
        } else {
            val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName)
            return Uri.fromFile(file)
        }
    }

    fun checkUpdate() {
        val serverUrl = AppConfig.getServerUrl(context)
        val currentVersionCode = try {
            context.packageManager.getPackageInfo(context.packageName, 0).let {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) it.longVersionCode.toInt() else it.versionCode
            }
        } catch (e: Exception) { 0 }

        val url = "$serverUrl/api/app-version/check-update?versionCode=$currentVersionCode"

        val client = OkHttpClient()
        val request = Request.Builder().url(url).build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                Timber.tag("UpdateManager").e(e, "检查更新失败")
            }

            override fun onResponse(call: Call, response: Response) {
                try {
                    val body = response.body?.string() ?: throw IOException("返回内容为空")
                    if (!response.isSuccessful) {
                        handler.post { Toast.makeText(context.applicationContext, "更新检查失败: ${response.code}", Toast.LENGTH_SHORT).show() }
                        return
                    }
                    
                    val json = JSONObject(body)
                    if (json.getInt("code") == 0) {
                        val data = json.optJSONObject("data")
                        if (data != null) {
                            val newVersionCode = data.optInt("versionCode", 0)
                            if (newVersionCode > currentVersionCode) {
                                val versionName = data.optString("versionName", "New")
                                val content = data.optString("updateContent", "优化系统体验")
                                val id = data.optLong("id", -1)
                                
                                if (id != -1L) {
                                    (context as? AppCompatActivity)?.runOnUiThread {
                                        try {
                                            showUpdateDialog(versionName, content, id)
                                        } catch (e: Exception) {
                                            Toast.makeText(context.applicationContext, "显示更新弹窗失败", Toast.LENGTH_SHORT).show()
                                        }
                                    }
                                }
                            } else {
                                handler.post { Toast.makeText(context.applicationContext, "当前已是最新版本", Toast.LENGTH_SHORT).show() }
                            }
                        } else {
                            handler.post { Toast.makeText(context.applicationContext, "当前已是最新版本", Toast.LENGTH_SHORT).show() }
                        }
                    } else {
                        val msg = json.optString("msg", "未知错误")
                        handler.post { Toast.makeText(context.applicationContext, "更新服务提示: $msg", Toast.LENGTH_SHORT).show() }
                    }
                } catch (e: Exception) {
                    Timber.tag("UpdateManager").e(e, "解析或处理更新结果失败")
                    handler.post { Toast.makeText(context.applicationContext, "更新信息解析失败", Toast.LENGTH_SHORT).show() }
                }
            }
        })
    }

    private fun showUpdateDialog(versionName: String, content: String, id: Long) {
        val view = (context as AppCompatActivity).layoutInflater.inflate(R.layout.dialog_update, null)
        val tvTitle = view.findViewById<android.widget.TextView>(R.id.tv_update_title)
        val tvContent = view.findViewById<android.widget.TextView>(R.id.tv_update_content)

        tvTitle.text = "新版本 V$versionName"
        tvContent.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            android.text.Html.fromHtml(content, android.text.Html.FROM_HTML_MODE_LEGACY)
        } else {
            @Suppress("DEPRECATION")
            android.text.Html.fromHtml(content)
        }

        AlertDialog.Builder(context)
            .setView(view)
            .setCancelable(false)
            .setPositiveButton("立即升级") { _, _ ->
                val serverUrl = AppConfig.getServerUrl(context)
                val downloadUrl = "$serverUrl/app-version/download/$id"
                startManualDownload(downloadUrl)
            }
            .setNegativeButton("稍后再说", null)
            .show()
    }

    private fun startManualDownload(url: String) {
        showProgressDialog()
        
        val client = OkHttpClient()
        val request = Request.Builder()
            .url(url)
            .addHeader("User-Agent", "Mozilla/5.0 (Android)")
            .build()

        call = client.newCall(request)
        call?.enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                handler.post {
                    progressDialog?.dismiss()
                    Toast.makeText(context.applicationContext, "连接服务器失败", Toast.LENGTH_SHORT).show()
                }
            }

            override fun onResponse(call: Call, response: Response) {
                if (!response.isSuccessful) {
                    handler.post {
                        progressDialog?.dismiss()
                        Toast.makeText(context.applicationContext, "下载失败: ${response.code}", Toast.LENGTH_SHORT).show()
                    }
                    return
                }
                val body = response.body
                if (body != null) {
                    try {
                        saveFileToPublic(body)
                    } catch (e: Exception) {
                        handler.post {
                            progressDialog?.dismiss()
                            Toast.makeText(context.applicationContext, "保存失败", Toast.LENGTH_SHORT).show()
                        }
                    }
                }
            }
        })
    }

    private fun saveFileToPublic(body: ResponseBody) {
        var inputStream: InputStream? = null
        var outputStream: OutputStream? = null
        var targetUri: Uri? = null

        try {
            targetUri = getPublicDownloadUri()
            if (targetUri == null) throw IOException("无法创建文件记录")

            outputStream = context.contentResolver.openOutputStream(targetUri)
            inputStream = body.byteStream()
            
            val totalBytes = body.contentLength()
            val buffer = ByteArray(8192)
            var bytesRead: Int
            var totalRead: Long = 0
            
            while (inputStream.read(buffer).also { bytesRead = it } != -1) {
                outputStream?.write(buffer, 0, bytesRead)
                totalRead += bytesRead
                
                if (totalBytes > 0) {
                    val progress = (totalRead * 100 / totalBytes).toInt()
                    handler.post {
                        progressDialog?.progress = progress
                        progressDialog?.setMessage("已下载: $progress%")
                    }
                }
            }
            outputStream?.flush()
            
            handler.post {
                progressDialog?.dismiss()
                Toast.makeText(context.applicationContext, "下载完成，文件已保存到系统下载目录", Toast.LENGTH_SHORT).show()
                installApk(targetUri)
            }
        } catch (e: Exception) {
            handler.post {
                progressDialog?.dismiss()
                Toast.makeText(context.applicationContext, "保存失败: ${e.message}", Toast.LENGTH_LONG).show()
            }
        } finally {
            inputStream?.close()
            outputStream?.close()
        }
    }

    private fun showProgressDialog() {
        progressDialog = ProgressDialog(context).apply {
            setTitle("正在下载")
            setMessage("正在连接服务器...")
            setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)
            max = 100
            setCancelable(false)
            setButton(ProgressDialog.BUTTON_NEGATIVE, "取消下载") { _, _ ->
                call?.cancel()
            }
            show()
        }
    }

    private fun installApk(uri: Uri) {
        try {
            // Android 8.0+ 检查安装权限
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                if (!context.packageManager.canRequestPackageInstalls()) {
                    val intent = Intent(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
                    intent.data = Uri.parse("package:" + context.packageName)
                    context.startActivity(intent)
                    Toast.makeText(context.applicationContext, "请先授予安装权限", Toast.LENGTH_SHORT).show()
                    return
                }
            }

            val intent = Intent(Intent.ACTION_VIEW)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            
            // 如果是 content:// URI 直接使用，否则通过 FileProvider 转换
            val installUri = if (uri.scheme == "content") {
                uri
            } else {
                val file = File(uri.path!!)
                FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
            }
            
            intent.setDataAndType(installUri, "application/vnd.android.package-archive")
            context.startActivity(intent)
        } catch (e: Exception) {
            Timber.tag("UpdateManager").e(e, "安装失败")
            Toast.makeText(context.applicationContext, "无法自动调起安装，请在系统下载目录中手动安装", Toast.LENGTH_LONG).show()
        }
    }
}
