package com.joyful.euphoria.board.xmlactivity

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.ad.tradpluslibrary.TPAdManager
import com.bumptech.glide.Glide
import com.bumptech.glide.integration.webp.decoder.WebpDrawable
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.joyful.euphoria.board.EuphoriaBoard
import com.joyful.euphoria.board.R
import com.joyful.euphoria.board.assistant.DatabaseAssistant
import com.joyful.euphoria.board.beaned.BeanDetails
import com.joyful.euphoria.board.frag.Dialog
import com.joyful.euphoria.board.recyclerview.RecyclerviewDownload
import com.joyful.euphoria.board.remember.DownloadBoardRemember
import com.joyful.euphoria.board.remember.OnItemClickRemember
import com.joyful.euphoria.board.utils.DealZipUtils
import com.joyful.euphoria.board.utils.Normal
import com.joyful.euphoria.board.utils.SaveCurrentThemeUtils
import kotlinx.coroutines.launch
import java.io.File

class DownloadXML : AppCompatActivity() {
    companion object {
        @JvmField
        var DISPLAY_URL_KEY: String = "display_url_key"

        @JvmField
        val ZIP_URL_KEY = "zip_url_key"

        @JvmField
        val NAME_KEY = "name_key"

        @JvmField
        val GIF_KEY = "gif_key"

        @JvmField
        val THUMB_KEY = "thumb_key"

        @JvmField
        val SOURCE_KEY = "data_key"

        @JvmField
        val KEYBOARD_ID = "KEYBOARD_ID"

        @JvmField
        val KEYBOARD_IMG = "KEYBOARD_IMG"

        private const val STORAGE_PERMISSION_REQUEST = 1001
    }

    private var dialog: Dialog? = null
    private var displayUrl: String? = null
    private lateinit var gifUrl: String
    private lateinit var zipUrl: String
    private var name: String = ""
    private lateinit var applyBtn: LinearLayout
    private lateinit var imgData: ImageView
    private lateinit var imgBack: ImageView
    private lateinit var textName: TextView
    private lateinit var recommendedRecycler: RecyclerView
    private lateinit var loadingLayout: FrameLayout
    private lateinit var unzipPath: String
    private lateinit var tvDownload: TextView
    private lateinit var imDownload: ImageView
    private lateinit var thumb: String
    private lateinit var imgLike: ImageView


    private var data: BeanDetails? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_download_xml)
        this.enableEdgeToEdge()
        ViewCompat.setOnApplyWindowInsetsListener(
            findViewById<View?>(R.id.set),
            OnApplyWindowInsetsListener { v: View?, insets: WindowInsetsCompat? ->
                val systemBars = insets!!.getInsets(WindowInsetsCompat.Type.systemBars())
                v!!.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
                insets
            })
        TPAdManager.loadAllAd(this)
        // 检查存储权限
        checkStoragePermission()

        findViewId()
        getExtraData() // 先赋值
        displayData() // 后使用
        setApply()
        onClick()
        onBackPressedDispatcher.addCallback(
            this,
            object : OnBackPressedCallback(true) {

                override fun handleOnBackPressed() {
                    // 物理返回被拦截
                    back()
                }
            })

        TPAdManager.showTPAD(this@DownloadXML) {}
    }

    private fun back() {
        TPAdManager.showTPAD(this@DownloadXML) {
            finish()
        }
    }

    // 检查存储权限
    private fun checkStoragePermission() {
        if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) {
            Toast.makeText(this, getString(R.string.storage_not_available), Toast.LENGTH_SHORT)
                .show()
            return
        }

    }

    /**
     * 修复3：完善数据获取逻辑，确保所有属性都被赋值，避免空指针
     */
    private fun getExtraData() {
        // 安全获取BeanDetails对象
        data = intent.getSerializableExtra(SOURCE_KEY) as? BeanDetails

        // 强制容错：数据为空则关闭页面
        if (data == null) {
            Toast.makeText(this, getString(R.string.data_error), Toast.LENGTH_SHORT).show()
            finish()
            return
        }

        // 为所有属性赋值，使用orEmpty()避免空值
        displayUrl = intent.getStringExtra(DISPLAY_URL_KEY).orEmpty()
        zipUrl = intent.getStringExtra(ZIP_URL_KEY).orEmpty()
        name = intent.getStringExtra(NAME_KEY).orEmpty() // 确保name被赋值（即使为空字符串）
        gifUrl = intent.getStringExtra(GIF_KEY).orEmpty()
        thumb = intent.getStringExtra(THUMB_KEY).orEmpty()

        if (zipUrl.isEmpty()) {
            zipUrl = data?.getZipUrl().orEmpty()
        }

        // 3. 新增：链接为空时的处理
        if (zipUrl.isEmpty()) {
            tvDownload.text = getString(R.string.download_url_missing) // 提示“下载链接缺失”
            applyBtn.isEnabled = false // 禁用下载按钮
        }

        // 从data中补充name（防止Intent未传递NAME_KEY）
        if (name.isEmpty()) {
            name = data?.getTitleName().orEmpty()
        }

        val serviceZipName = DealZipUtils.getServiceZipName(zipUrl)
        unzipPath = DealZipUtils.getUnzipPath(serviceZipName)

        Log.d("SetActivity", "unzipPath=$unzipPath")
        lifecycleScope.launch {
            DatabaseAssistant.getIsLike(name) {
                imgLike.isSelected = it
            }
        }

        updateDownloadStatus()
    }

    // 更新下载状态显示
    private fun updateDownloadStatus() {
        val file = File(unzipPath)
        if (file.exists() && file.isDirectory) {
            imDownload.isVisible = false
            tvDownload.text = getString(R.string.apply)
        } else {
            imDownload.isVisible = true
            tvDownload.text = getString(R.string.download_apply)
        }
    }

    private fun findViewId() {
        applyBtn = findViewById(R.id.layoutDownloadApply)
        imgData = findViewById(R.id.image_data)
        imgBack = findViewById(R.id.back)
        textName = findViewById(R.id.textview_data_name)
        recommendedRecycler = findViewById(R.id.recommended_recycler)
        imgLike = findViewById(R.id.im_like)
        loadingLayout = findViewById(R.id.loading)
        imDownload = findViewById(R.id.im_download)
        tvDownload = findViewById(R.id.tv_download)
    }

    /**
     * 修复4：displayData中增加name空判断，避免访问未初始化属性
     */
    private fun displayData() {
        textName.text = if (name.isNotEmpty()) name else getString(R.string.unknown_keyboard)

        // 安全获取图片路径，多重备份方案
        val imgPath = displayUrl ?: data?.getImgPath() ?: thumb ?: ""

        val gifPath = gifUrl.takeIf { it.isNotEmpty() } ?: data?.getImgGif() ?: ""

        // 加载图片/GIF
        if (gifPath.isNotEmpty()) {
            loadImgGif(gifPath)
        } else if (imgPath.isNotEmpty()) {
            Glide.with(this)
                .load(imgPath)
                .thumbnail(Glide.with(this).load(thumb))
                .placeholder(R.drawable.euphoria_place_holder)
                .error(R.drawable.euphoria_place_holder)
                .into(imgData)
        } else {
            imgData.setImageResource(R.drawable.euphoria_place_holder)
        }
    }

    private fun onClick() {
        imgBack.setOnClickListener {
            back()

        }

        imgLike.setOnClickListener {
            imgLike.isSelected = !imgLike.isSelected
            lifecycleScope.launch {
                try {
                    val currentData = data ?: return@launch // 安全获取data
                    if (imgLike.isSelected) {
                        DatabaseAssistant.addLike(currentData)
                    } else {
                        DatabaseAssistant.removeLike(currentData)
                    }
                } catch (e: Exception) {
                    Log.e("SetActivity", "Like operation error", e)
                    Toast.makeText(
                        this@DownloadXML,
                        getString(R.string.operation_failed),
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        }

        val forYouList = EuphoriaBoard.list.filter {
            it.parentName == getString(R.string.recommend_name)
        }

        recommendedRecycler.run {
            adapter = RecyclerviewDownload(this@DownloadXML).apply {
                val shuffled = forYouList.getOrNull(0)?.keyboardList?.shuffled() ?: emptyList()
                setForYouList(shuffled)
                setClickAction(object : OnItemClickRemember {
                    override fun OnItemClickListener() {
                        finish()
                    }
                })
            }

            layoutManager = LinearLayoutManager(
                this@DownloadXML,
                LinearLayoutManager.HORIZONTAL, false
            )
            addItemDecoration(object : RecyclerView.ItemDecoration() {
                override fun getItemOffsets(
                    outRect: Rect,
                    view: View,
                    parent: RecyclerView,
                    state: RecyclerView.State
                ) {
                    super.getItemOffsets(outRect, view, parent, state)
                    val position = parent.getChildAdapterPosition(view)
                    if (position > 0) {
                        outRect.left = 8.dpToPx()
                    }
                }
            })
        }
    }

    private fun Int.dpToPx(): Int {
        return (this * resources.displayMetrics.density).toInt()
    }

    @SuppressLint("CheckResult")
    private fun loadImgGif(gifPath: String) {
        Glide.with(this)
            .load(gifPath)
            .thumbnail(Glide.with(this).load(thumb))
            .placeholder(R.drawable.euphoria_place_holder)
            .error(R.drawable.euphoria_place_holder)
            .addListener(object : RequestListener<Drawable> {
                override fun onLoadFailed(
                    e: GlideException?,
                    model: Any?,
                    target: Target<Drawable>,
                    isFirstResource: Boolean
                ): Boolean {
                    Log.e("SetActivity", "GIF load failed", e)
                    return false
                }

                override fun onResourceReady(
                    resource: Drawable,
                    model: Any,
                    target: Target<Drawable>?,
                    dataSource: DataSource,
                    isFirstResource: Boolean
                ): Boolean {
                    if (resource is WebpDrawable) {
                        resource.loopCount = WebpDrawable.LOOP_FOREVER
                    }
                    return false
                }
            }).into(imgData)
    }

    private fun setApply() {
        applyBtn.setOnClickListener {
            TPAdManager.showTPAD(this@DownloadXML) {
                val checkEnable = Normal.checkEnable(this)
                val checkSetDefault = Normal.checkSetDefault(this)
                if (!checkEnable || !checkSetDefault) {
                    showDialog()
                    return@showTPAD
                }
                startDown()

            }

        }
    }

    private fun showDialog() {
        if (dialog == null) {
            dialog = Dialog.newInstance().apply {
                setClickListener {
                    startDown()
                }
            }
        }
        dialog?.show(supportFragmentManager, "")
    }

    private fun startDown() {
        loadingLayout.isVisible = true
        applyBtn.isEnabled = false

        if (!DealZipUtils.isValidZipUrl(zipUrl)) { // 调用工具类校验
            runOnUiThread {
                Toast.makeText(this, getString(R.string.invalid_download_url), Toast.LENGTH_SHORT)
                    .show()
                applyBtn.isEnabled = true
                loadingLayout.isVisible = false
            }
            return
        }

        val file = File(unzipPath)
        if (file.exists() && file.isDirectory) {
            val findFirstDirectory = DealZipUtils.findFirstDirectory(file)
            findFirstDirectory?.let {
                apply("${it}/")
            } ?: run {
                runOnUiThread {
                    Toast.makeText(this, getString(R.string.file_error), Toast.LENGTH_SHORT).show()
                    applyBtn.isEnabled = true
                    loadingLayout.isVisible = false
                }
            }
        } else {
            if (zipUrl.isEmpty()) {
                runOnUiThread {
                    Toast.makeText(this, getString(R.string.download_url_error), Toast.LENGTH_SHORT)
                        .show()
                    applyBtn.isEnabled = true
                    loadingLayout.isVisible = false
                }
                return
            }

            DealZipUtils.startDownloadZip(zipUrl, object : DownloadBoardRemember {
                override fun OnApplySkinListener(fileList: List<File?>?) {
                    runOnUiThread {
                        applyBtn.isEnabled = true
                        loadingLayout.isVisible = false
                    }
                    if (fileList.isNullOrEmpty()) {
                        runOnUiThread {
                            Toast.makeText(
                                this@DownloadXML,
                                getString(R.string.download_fail),
                                Toast.LENGTH_SHORT
                            ).show()
                        }
                    } else {
                        if (file.exists()) {
                            val findFirstDirectory = DealZipUtils.findFirstDirectory(file)
                            Log.d(EuphoriaBoard.TAG, "apply path: $findFirstDirectory")
                            runOnUiThread {
                                findFirstDirectory?.let {
                                    apply("${it}/")
                                } ?: run {
                                    Toast.makeText(
                                        this@DownloadXML,
                                        getString(R.string.file_error),
                                        Toast.LENGTH_SHORT
                                    ).show()
                                }
                            }
                        }
                    }
                }
            })
        }
    }

    private fun apply(path: String) {
        var skinParentPath = path
        if (path.contains("res")) {
            skinParentPath = path.substringBeforeLast("res")
        }

        try {
            SaveCurrentThemeUtils.updateSkinPath(skinParentPath)
            Toast.makeText(
                this@DownloadXML,
                getString(R.string.theme_application_successful),
                Toast.LENGTH_SHORT
            ).show()
            startActivity(Intent(this, PreviewXML::class.java).apply {
                putExtra(PreviewXML.key_name, name)
            })
            finish()
        } catch (e: Exception) {
            Log.e("SetActivity", "Apply theme error", e)
            Toast.makeText(this, getString(R.string.apply_failed), Toast.LENGTH_SHORT).show()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        dialog?.dismiss()
    }
}