package com.sunny.app.soft.timberkeyboardnew.ui.activity

import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.util.Log
import android.view.View
import android.widget.Toast

import com.bumptech.glide.Glide
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.sunny.app.soft.timberkeyboardnew.R
import com.sunny.app.soft.timberkeyboardnew.data.entity.BackgroundEntity
import com.sunny.app.soft.timberkeyboardnew.databinding.ActivityDownloadBinding
import com.sunny.app.soft.timberkeyboardnew.tools.AppConstant
import com.sunny.app.soft.timberkeyboardnew.tools.KeyboardManager
import com.sunny.app.soft.timberkeyboardnew.tools.ZipTools
import com.sunny.app.soft.timberkeyboardnew.ui.listener.ApplyListener
import com.sunny.app.soft.timberkeyboardnew.unityad.UnityAdManager
import com.sunny.app.soft.timberkeyboardnew.unityad.onShowCallBack
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.InputStream

class DownloadActivity :
    BaseActivity(),
    View.OnClickListener,
    ApplyListener {

    private lateinit var binding: ActivityDownloadBinding

    private lateinit var backgroundEntity: BackgroundEntity

    private lateinit var zipPath: String

    private lateinit var unzipPath: String

    private lateinit var sp: SharedPreferences

    override fun setRootView(): View {
        binding = ActivityDownloadBinding.inflate(layoutInflater)
        return binding.root
    }

    override fun initView() {
        super.initView()
        backgroundEntity = intent.getSerializableExtra(AppConstant.KEY_EXTRA) as BackgroundEntity

        // TODO:  load Ad

        sp = getSharedPreferences(
            AppConstant.SHARE_NAME, Context.MODE_PRIVATE
        )

        val path =
            sp.getString("${AppConstant.KEY_CUR_Path_img}_${backgroundEntity.skinNumber}", "")
        val file = File(path)
        if (file.exists()) {
            val bitmapDrawable =
                BitmapDrawable(resources, BitmapFactory.decodeFile(path))
            binding.downloadImg.setImageDrawable(bitmapDrawable)

            Log.d("----------", "exists")
        } else {
            initImg()
        }

        //187df1496820a65c01b38bc74333cc1bae249226b337397125f7c6367023e86c.0
        unzipPath = "$cacheDir/${backgroundEntity.skinNumber}/skin_${backgroundEntity.skinNumber}"


        initDownload()
        initButton()
        initTitle()
    }

    private fun initTitle() {
        binding.bgName.text = "Keyboard background"
    }

    private fun initDownload() {
        val cacheDir = cacheDir
        val dataUrl = backgroundEntity.contentPath
        zipPath = "$cacheDir/$dataUrl"
    }

    private fun onShowAd() {
        val readyUnitAd = UnityAdManager.getReadyUnitAd()
        if (readyUnitAd == null) {
            startSetSkin()
        } else {
            UnityAdManager.showUnityAd(this, readyUnitAd, object : onShowCallBack {
                override fun onShowFail() {
                    startSetSkin()
                }

                override fun onShowClose() {
                    startSetSkin()
                }

                override fun onShowSuccess() {

                }

            })
        }

    }

    private fun initButton() {
        binding.downloadBack.setOnClickListener(this)
        binding.btnDownload.setOnClickListener(this)
    }

    private fun initImg() {
        try {
            Glide
                .with(this)
                .downloadOnly()
                .load(backgroundEntity.coverPath)
//                .apply(
//                    RequestOptions().placeholder(R.drawable.png_loading)
//                )
//                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .addListener(object : RequestListener<File> {
                    override fun onLoadFailed(
                        e: GlideException?,
                        model: Any?,
                        target: Target<File>?,
                        isFirstResource: Boolean
                    ): Boolean {
                        Log.d(
                            "----------",
                            "onLoadFailed    backgroundEntity.coverPath=${backgroundEntity.coverPath} e=${e?.message}   "
                        )
                        return false
                    }

                    override fun onResourceReady(
                        resource: File?,
                        model: Any?,
                        target: Target<File>?,
                        dataSource: DataSource?,
                        isFirstResource: Boolean
                    ): Boolean {
                        resource?.let {
                            Log.d("----------", "it.absolutePath=${it.absolutePath}")

                            val edit = sp.edit()
                            // 存放键值对
                            edit.run {
                                putString(
                                    "${AppConstant.KEY_CUR_Path_img}_${backgroundEntity.skinNumber}",
                                    it.absolutePath
                                )
                                apply()
                            }

                            val bitmapDrawable =
                                BitmapDrawable(resources, BitmapFactory.decodeFile(it.absolutePath))
                            binding.downloadImg.setImageDrawable(bitmapDrawable)
                        }

                        return false
                    }

                }).preload()

        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun onClick(v: View?) {
        when (v) {
            binding.downloadBack -> finish()
            binding.btnDownload -> {
                applySkin()
            }
        }
    }

    private fun applySkin() {


        if (!KeyboardManager.isChoose() || !KeyboardManager.isEnable()) {
            Toast.makeText(this, getString(R.string.unEnable), Toast.LENGTH_SHORT).show()
            val intent = Intent(this, SetKeyboardActivity::class.java)
            startActivity(intent)
            return
        }

        onShowAd()


    }

    private fun startSetSkin() {
        binding.downloadProgress.visibility = View.VISIBLE

        val zipFile = File(unzipPath)

        if (zipFile.exists()) {
//            val allThemePath: String = getAllThemePath(backgroundEntity.skinNumber.toString())
            val edit = sp.edit()
            edit.run {
                putString(AppConstant.KEY_CUR_Path, backgroundEntity.skinNumber.toString())
                apply()
            }

            binding.downloadProgress.visibility = View.GONE
            Toast.makeText(this, getString(R.string.succ_apply), Toast.LENGTH_LONG).show()
            finish()

        } else {
            getZipData(
                backgroundEntity.skinNumber,
                backgroundEntity.contentPath,
                this@DownloadActivity,
                this
            )
        }
    }

    private fun getAllThemePath(zip: String): String {
        val result = sp.getString(zip, "")
        return result!!
    }

    private fun getZipData(
        skinNumber: Int,
        contentPath: String,
        context: Context,
        listener: ApplyListener
    ) {
        Glide.with(context).asFile().load(contentPath).addListener(object : RequestListener<File> {
            override fun onLoadFailed(
                e: GlideException?,
                model: Any?,
                target: Target<File>?,
                isFirstResource: Boolean
            ): Boolean {
                listener.applyListener(false, "")
                return false
            }

            override fun onResourceReady(
                resource: File?,
                model: Any?,
                target: Target<File>?,
                dataSource: DataSource?,
                isFirstResource: Boolean
            ): Boolean {
                val fileInputStream = FileInputStream(resource)
                saveFile(skinNumber, contentPath, fileInputStream, listener)
                return false
            }

        }).preload()
    }

    private fun saveFile(
        skinNumber: Int,
        contentPath: String,
        fileInputStream: FileInputStream,
        listener: ApplyListener
    ) {
        val zipPath = "${cacheDir}/${skinNumber}_zip"
        val unZipPath = "${cacheDir}/${skinNumber}"
        val b = writeNewFile(fileInputStream, zipPath)
        if (b) {
            ZipTools.unzip(zipPath, unZipPath)
            if (unZipPath.isNotEmpty()) {
                listener.applyListener(true, unZipPath)
            } else {
                listener.applyListener(false, "")
            }
        }

    }

    private fun writeNewFile(input: InputStream, filePath: String): Boolean {
        var stream: FileOutputStream? = null
        var outStream: ByteArrayOutputStream? = null
        try {
            val outStream = ByteArrayOutputStream()
            val bytes = ByteArray(4096)
            var length = 0
            while (input.read(bytes).also {
                    length = it
                } != -1) {
                outStream.write(bytes, 0, length)
            }
            val file = File(filePath)
            if (!file.exists()) {
                file.createNewFile()
            }
            stream = FileOutputStream(file)
            stream.run {
                write(outStream.toByteArray())
            }
            outStream.close()
            stream.close()
            return true
        } catch (ex: Exception) {
            outStream?.close()
            stream?.close()
            return false
        }
    }

    override fun applyListener(isSuccess: Boolean, str: String) {
        binding.downloadProgress.visibility = View.GONE
        if (isSuccess) {
            val lastIndexOf: Int = str.lastIndexOf(AppConstant.res_path)
            val substring = str.subSequence(0, lastIndexOf + AppConstant.res_path.length).toString()
            val edit = sp.edit()
            edit.run {
                putString(AppConstant.KEY_CUR_Path, backgroundEntity.skinNumber.toString())
                apply()
            }
            edit.run {
                putString(
                    backgroundEntity.skinNumber.toString(),
                    backgroundEntity.skinNumber.toString()
                )
                apply()
            }
            Toast.makeText(this, getString(R.string.succ_apply), Toast.LENGTH_LONG).show()
            finish()
        } else {
            Toast.makeText(this, getString(R.string.fail_apply), Toast.LENGTH_LONG).show()
        }
    }

}