package com.example.shiftalarm

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.view.LayoutInflater
import android.widget.Button
import android.widget.ProgressBar
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.content.FileProvider
import org.json.JSONObject
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
import java.net.HttpURLConnection
import java.net.URL

object AppUpdateManager {

    private const val VERSION_URL = "https://git.webpluss.net/sanjeok77/ShiftRing/raw/branch/main/version.json"

    fun checkUpdate(activity: Activity, silent: Boolean = false) {
        val ctx = activity.applicationContext
        val versionCheckUrl = "$VERSION_URL?t=${System.currentTimeMillis()}"

        Thread {
            try {
                val url = URL(versionCheckUrl)
                val connection = url.openConnection() as HttpURLConnection
                connection.connectTimeout = 5000
                connection.readTimeout = 5000
                connection.requestMethod = "GET"
                connection.useCaches = false

                if (connection.responseCode == 200) {
                    val reader = connection.inputStream.bufferedReader()
                    val result = reader.readText()
                    reader.close()

                    val json = JSONObject(result)
                    val serverVersionCode = json.getInt("versionCode")
                    val serverVersionName = json.getString("versionName")
                    val apkUrl = json.getString("apkUrl")
                    val changelog = json.optString("changelog", "버그 수정 및 성능 향상")

                    val pInfo = ctx.packageManager.getPackageInfo(ctx.packageName, 0)
                    val currentVersionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                        pInfo.longVersionCode.toInt()
                    } else {
                        @Suppress("DEPRECATION")
                        pInfo.versionCode
                    }
                    val currentVersionName = pInfo.versionName ?: "0.0.0"

                    if (serverVersionCode > currentVersionCode) {
                        activity.runOnUiThread {
                            showUpdateDialog(activity, serverVersionName, changelog, apkUrl)
                        }
                    } else if (!silent && serverVersionCode == currentVersionCode) {
                        activity.runOnUiThread {
                            Toast.makeText(ctx, "현재 최신 버전을 사용 중입니다. ($currentVersionName)", Toast.LENGTH_SHORT).show()
                        }
                    }
                } else if (!silent) {
                    activity.runOnUiThread {
                        Toast.makeText(ctx, "서버 연결 실패", Toast.LENGTH_SHORT).show()
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                if (!silent) {
                    activity.runOnUiThread {
                        Toast.makeText(ctx, "업데이트 확인 중 오류 발생", Toast.LENGTH_SHORT).show()
                    }
                }
            }
        }.start()
    }

    private fun showUpdateDialog(activity: Activity, version: String, changelog: String, apkUrl: String) {
        if (activity.isFinishing || activity.isDestroyed) return

        val view = LayoutInflater.from(activity).inflate(R.layout.dialog_app_update_oneui, null)
        val tvVersion = view.findViewById<TextView>(R.id.tvUpdateVersion)
        val tvChangelog = view.findViewById<TextView>(R.id.tvChangelog)
        val btnLater = view.findViewById<Button>(R.id.btnUpdateLater)
        val btnNow = view.findViewById<Button>(R.id.btnUpdateNow)

        tvVersion.text = "Version $version"
        tvChangelog.text = changelog

        val dialog = AlertDialog.Builder(activity)
            .setView(view)
            .setCancelable(true)
            .create()

        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))

        btnLater.setOnClickListener {
            dialog.dismiss()
        }

        btnNow.setOnClickListener {
            dialog.dismiss()
            downloadAndInstallApk(activity, apkUrl, version)
        }

        dialog.show()

        val width = (activity.resources.displayMetrics.widthPixels * 0.88).toInt()
        dialog.window?.setLayout(width, android.view.ViewGroup.LayoutParams.WRAP_CONTENT)
    }

    private fun downloadAndInstallApk(activity: Activity, apkUrl: String, version: String) {
        if (activity.isFinishing || activity.isDestroyed) return

        val view = LayoutInflater.from(activity).inflate(R.layout.dialog_update_progress_oneui, null)
        val tvSub = view.findViewById<TextView>(R.id.tvProgressSub)
        val progressBar = view.findViewById<ProgressBar>(R.id.downloadProgressBar)
        val tvPercent = view.findViewById<TextView>(R.id.tvProgressPercent)

        tvSub.text = "v$version 다운로드 중..."

        val progressDialog = AlertDialog.Builder(activity)
            .setView(view)
            .setCancelable(false)
            .create()

        progressDialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        progressDialog.show()

        val width = (activity.resources.displayMetrics.widthPixels * 0.88).toInt()
        progressDialog.window?.setLayout(width, android.view.ViewGroup.LayoutParams.WRAP_CONTENT)

        Thread {
            try {
                val url = URL(apkUrl)
                val connection = url.openConnection() as HttpURLConnection
                connection.connectTimeout = 15000
                connection.readTimeout = 15000
                connection.requestMethod = "GET"
                connection.connect()

                val fileLength = connection.contentLength
                val inputStream = BufferedInputStream(connection.inputStream)
                
                val apkFile = File(activity.cacheDir, "update.apk")
                val outputStream = FileOutputStream(apkFile)
                
                val buffer = ByteArray(8192)
                var total: Long = 0
                var count: Int
                
                while (inputStream.read(buffer).also { count = it } != -1) {
                    total += count
                    outputStream.write(buffer, 0, count)
                    
                    if (fileLength > 0) {
                        val progress = (total * 100 / fileLength).toInt()
                        activity.runOnUiThread {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                                progressBar.setProgress(progress, true)
                            } else {
                                progressBar.progress = progress
                            }
                            tvPercent.text = "$progress%"
                        }
                    }
                }
                
                outputStream.flush()
                outputStream.close()
                inputStream.close()
                connection.disconnect()
                
                activity.runOnUiThread {
                    progressDialog.dismiss()
                    installApk(activity, apkFile)
                }
                
            } catch (e: Exception) {
                e.printStackTrace()
                activity.runOnUiThread {
                    progressDialog.dismiss()
                    Toast.makeText(activity, "다운로드 실패: ${e.message}", Toast.LENGTH_LONG).show()
                }
            }
        }.start()
    }

    private fun installApk(activity: Activity, apkFile: File) {
        try {
            val apkUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                FileProvider.getUriForFile(activity, "${activity.packageName}.provider", apkFile)
            } else {
                Uri.fromFile(apkFile)
            }
            
            val intent = Intent(Intent.ACTION_VIEW).apply {
                setDataAndType(apkUri, "application/vnd.android.package-archive")
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
            }
            activity.startActivity(intent)
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(activity, "설치 실패: ${e.message}", Toast.LENGTH_LONG).show()
        }
    }
}
