package com.aiosman.ravenow.ui.dialogs

import android.content.Intent
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.FileProvider
import com.aiosman.ravenow.ConstVars
import com.aiosman.ravenow.LocalAppTheme
import com.aiosman.ravenow.R
import com.aiosman.ravenow.model.UpdateInfo
import com.aiosman.ravenow.ui.composables.ActionButton
import com.google.firebase.perf.config.RemoteConfigManager.getVersionCode
import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.File

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CheckUpdateDialog() {
    val AppColors = LocalAppTheme.current
    val context = LocalContext.current
    val scope = rememberCoroutineScope()
    var showDialog by remember { mutableStateOf(false) }
    var newApkUrl by remember { mutableStateOf("") }
    var progress by remember { mutableStateOf(0f) }
    var isDownloading by remember { mutableStateOf(false) } // Add downloading state
    var message by remember { mutableStateOf("") }
    var versionName by remember { mutableStateOf("") }
    fun checkUpdate() {
        scope.launch(Dispatchers.IO) {
            try {
                val client = OkHttpClient()
                val request = Request.Builder()
                    .url("${ConstVars.BASE_SERVER}/static/update/beta/version.json")
                    .build()
                val response = client.newCall(request).execute()

                if (response.isSuccessful) {
                    val responseBody = response.body?.string()
                    val updateInfo = Gson().fromJson(responseBody, UpdateInfo::class.java)

                    val versionCode = getVersionCode(context)
                    if (updateInfo.versionCode > versionCode) {
                        withContext(Dispatchers.Main) {
                            message = updateInfo.updateContent
                            versionName = updateInfo.versionName
                            showDialog = true
                            newApkUrl = updateInfo.downloadUrl
                        }
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    fun downloadApk() {
        isDownloading = true
        scope.launch(Dispatchers.IO) {
            val request = Request.Builder()
                .url(newApkUrl)
                .build()
            val client = OkHttpClient()
            client.newCall(request).execute().use { response ->
                if (!response.isSuccessful) throw Exception("Unexpected code $response")
                val body = response.body
                if (body != null) {
                    val apkFile = File(context.cacheDir, "rider_pro.apk")
                    val totalBytes = body.contentLength()
                    var downloadedBytes = 0L

                    apkFile.outputStream().use { output ->
                        body.byteStream().use { input ->
                            val buffer = ByteArray(8 * 1024)
                            var bytesRead: Int
                            while (input.read(buffer).also { bytesRead = it } != -1) {
                                output.write(buffer, 0, bytesRead)
                                downloadedBytes += bytesRead
                                progress = downloadedBytes / totalBytes.toFloat()
                            }
                        }
                    }

                    val apkUri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", apkFile)
                    val intent = Intent(Intent.ACTION_VIEW)
                    intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
                    intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
                    context.startActivity(intent)
                }
            }
            isDownloading = false
        }
    }

    LaunchedEffect(Unit) {
        checkUpdate()
    }

    if (showDialog) {
        BasicAlertDialog(
            onDismissRequest = {
                if (!isDownloading) {
                    showDialog = false
                }
            },
            modifier = Modifier,
        ) {
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(start = 24.dp, end = 24.dp, bottom = 120.dp),
            ) {
                Box(
                    modifier = Modifier.fillMaxWidth(),
                    contentAlignment = Alignment.TopCenter
                ) {
                    Column(
                        modifier = Modifier
                            .fillMaxWidth()
                    ) {
                        Spacer(modifier = Modifier.height(96.dp))
                        Column(
                            modifier = Modifier
                                .fillMaxWidth()
                                .clip(RoundedCornerShape(32.dp))
                                .background(AppColors.background)
                                .padding(vertical = 32.dp, horizontal = 24.dp),
                            horizontalAlignment = Alignment.CenterHorizontally
                        ) {
                            Spacer(modifier = Modifier.height(48.dp))
                            Text(
                                stringResource(id = R.string.update_find_new_version),
                                fontWeight = FontWeight.W900,
                                fontSize = 22.sp,
                                color = AppColors.text
                            )
                            Spacer(modifier = Modifier.height(16.dp))
                            Text(
                                versionName,
                                modifier = Modifier.fillMaxWidth(),
                                color = AppColors.text
                            )
                            Text(
                                message,
                                modifier = Modifier.fillMaxWidth(),
                                color = AppColors.text
                            )
                            if (progress > 0) {
                                Spacer(modifier = Modifier.height(16.dp))
                                LinearProgressIndicator(
                                    progress = { progress },
                                    color = AppColors.main,
                                    modifier = Modifier
                                        .fillMaxWidth()
                                        .clip(RoundedCornerShape(16.dp)),
                                    trackColor = AppColors.basicMain
                                )
                            }

                            Spacer(modifier = Modifier.height(32.dp))
                            Row(
                                modifier = Modifier.fillMaxWidth()
                            ) {
                                ActionButton(
                                    text = stringResource(id = R.string.update_later),
                                    color = AppColors.text,
                                    backgroundColor = AppColors.basicMain,
                                    modifier = Modifier.weight(1f),
                                    fullWidth = false,
                                    roundCorner = 16f,
                                    fontSize = 14.sp,
                                    fontWeight = FontWeight.Normal,
                                ) {
                                    showDialog = false
                                }
                                Spacer(modifier = Modifier.width(16.dp))
                                ActionButton(
                                    text = stringResource(id = R.string.update_update_now),
                                    backgroundColor = AppColors.main,
                                    color = AppColors.mainText,
                                    modifier = Modifier.weight(1f),
                                    fullWidth = false,
                                    roundCorner = 16f,
                                    fontSize = 14.sp,
                                    fontWeight = FontWeight.Normal,
                                ) {
                                    downloadApk()
                                }
                            }
                            Spacer(modifier = Modifier.height(16.dp))

                        }
                    }
                    Image(
                        painter = painterResource(id = R.mipmap.rider_pro_update_header),
                        contentDescription = null,
                        modifier = Modifier.padding(16.dp)
                    )
                }
            }
        }
    }
}