package com.gh.gamecenter.personalhome.background

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.annotation.RequiresApi
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import com.gh.gamecenter.CropImageActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.feature.selector.LocalMediaActivity
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.FragmentBackgroundPreviewBinding
import com.gh.gamecenter.feature.entity.BackgroundImageEntity
import com.gh.gamecenter.feature.selector.ChooseType
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserViewModel
import com.halo.assistant.HaloApp
import com.zhihu.matisse.Matisse
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException
import java.io.File

class BackgroundPreviewFragment : ToolbarFragment() {

    private var mOriginBitmap: Bitmap? = null
    private var mTempBitmap: Bitmap? = null
    private lateinit var mBinding: FragmentBackgroundPreviewBinding
    private var mPostDialog: WaitingDialogFragment? = null
    private var mLocalPath: String = ""
    private var backgroundImageEntity: BackgroundImageEntity? = null//如果为空，则是本地选择的

    private lateinit var mUserViewModel: UserViewModel

    override fun getLayoutId(): Int = 0

    override fun getInflatedLayout(): View {
        mBinding = FragmentBackgroundPreviewBinding.inflate(layoutInflater, null, false)
        return mBinding.root
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mLocalPath = arguments?.getString(EntranceConsts.KEY_LOCAL_PATH) ?: ""
        backgroundImageEntity =
            arguments?.getParcelable(BackgroundImageEntity::class.java.simpleName)

        mUserViewModel = viewModelProvider(UserViewModel.Factory(HaloApp.getInstance().application))
        mUserViewModel.uploadBackground.observeNonNull(this) {
            mPostDialog?.dismiss()
            if (it) {
                requireActivity().setResult(Activity.RESULT_OK)
                requireActivity().finish()
                mUserViewModel.uploadBackground.value = false
            }
        }

        mBinding.root.post {
            changeViewParams()
        }
    }

    private fun changeViewParams() {
        val screenHeight =
            DisplayUtils.px2dip(requireContext(), DisplayUtils.getScreenHeight().toFloat())
        val picProportion = if (screenHeight > 640) 6 / 13f else 9 / 16f
        val width = mBinding.previewHomeIv.width
        val realHeight = width / picProportion

        mBinding.previewHomeIv.layoutParams =
            (mBinding.previewHomeIv.layoutParams as ConstraintLayout.LayoutParams).apply {
                this.height = realHeight.toInt()
            }

        mBinding.homeContainer.visibility = View.VISIBLE
        mBinding.changeBackgroundTv.visibility = View.VISIBLE
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mLocalPath = arguments?.getString(EntranceConsts.KEY_LOCAL_PATH) ?: ""
        backgroundImageEntity =
            arguments?.getParcelable(BackgroundImageEntity::class.java.simpleName)
        mOriginBitmap = BitmapUtils.getBitmapByFile(mLocalPath, Bitmap.Config.ARGB_8888)
        if (mOriginBitmap == null) return
        mTempBitmap = Bitmap.createBitmap(mOriginBitmap!!)
        mBinding.personalHomeIv.setImageBitmap(mOriginBitmap)

        val screenHeight =
            DisplayUtils.px2dip(requireContext(), DisplayUtils.getScreenHeight().toFloat())
        if (screenHeight > 640) {
            ImageUtils.display(
                mBinding.previewHomeIv,
                "https://and-static.ghzs.com/image/game/home/setting/2024/09/11/66e132305d28e599fc08951a.webp"
            )
        } else {
            ImageUtils.display(
                mBinding.previewHomeIv,
                "https://and-static.ghzs.com/image/game/home/setting/2024/09/11/66e12f335d28e599fc089517.webp"
            )
        }

        mBinding.normalTitle.text = "预览"
        initListener()

        val background = UserManager.getInstance().userInfoEntity?.background
        if (backgroundImageEntity != null && backgroundImageEntity!!.id == background?.id) {
            mBinding.alphaSeek.progress = background.opacity
            if (background.blur in 1..25 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                mBinding.blurSeek.progress = background.blur
                changeAmbiguity()
            }
            mBinding.commitTv.text = "使用中"
        }

        mBinding.topBackground.background =
            if (mIsDarkModeOn) null else R.drawable.bg_background_preview_top.toDrawable(requireContext())
    }

    private fun initListener() {
        mBinding.normalToolbar.setNavigationOnClickListener { requireActivity().finish() }

        mBinding.alphaSeek.doOnSeekBarChangeListener({
            mBinding.personalHomeIv.alpha = it / 100f
            changeCommitButton()
        })

        mBinding.blurSeek.doOnSeekBarChangeListener({
            changeCommitButton()
        }, {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                changeAmbiguity()
            } else {
                ToastUtils.showToast("系统版本太低")
            }
        })

        mBinding.changeBackgroundTv.setOnClickListener {
            if (backgroundImageEntity == null) {
                selectPic(requireActivity())
            } else {
                requireActivity().finish()
            }
        }

        mBinding.commitTv.setOnClickListener {
            PermissionHelper.checkStoragePermissionBeforeAction(requireContext()) {
                mTempBitmap?.let {
                    val filePath: String =
                        "${requireContext().cacheDir.absolutePath}${File.separator}${
                            MD5Utils.getContentMD5(mLocalPath)
                        }.webp"
                    savePicture(filePath, it)
                }
            }
        }
    }

    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    private fun changeAmbiguity() {
        if (mOriginBitmap == null) return
        val progress = mBinding.blurSeek.progress

        try {
            mTempBitmap = if (progress == 0) {
                Bitmap.createBitmap(mOriginBitmap!!)
            } else {
                BitmapUtils.getBlurBitmap(requireContext(), mOriginBitmap, progress)
            }
            mBinding.personalHomeIv.setImageBitmap(mTempBitmap)
        } catch (t: Throwable) {
            ToastUtils.toast("您的设备暂不支持调整模糊度")
        }
    }

    private fun changeCommitButton() {
        val background = UserManager.getInstance().userInfoEntity?.background
        if (backgroundImageEntity != null && backgroundImageEntity!!.id == background?.id) {
            if (mBinding.alphaSeek.progress != background.opacity || mBinding.blurSeek.progress != background.blur) {
                mBinding.commitTv.text = "使用"
                mBinding.commitTv.isEnabled = true
            } else {
                mBinding.commitTv.isEnabled = false
                mBinding.commitTv.text = "使用中"
            }
        }
    }

    @SuppressLint("CheckResult")
    private fun savePicture(path: String, bitmap: Bitmap) {
        mPostDialog = WaitingDialogFragment.newInstance("加载中...")
        mPostDialog?.show(childFragmentManager, null)
        Single.just(bitmap)
            .map {
                if (mBinding.alphaSeek.progress == 100) {
                    it
                } else {
                    BitmapUtils.getTransparentBitmap(
                        bitmap,
                        Bitmap.Config.ARGB_8888,
                        mBinding.alphaSeek.progress
                    )
                }
            }
            .map {
                BitmapUtils.saveBitmap(it, path)
                path
            }
            .flatMap {
                uploadImage(it)
            }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                mPostDialog?.dismiss()
                val entity = BackgroundImageEntity(
                    backgroundImageEntity?.id
                        ?: "",
                    it,
                    opacity = mBinding.alphaSeek.progress,
                    blur = mBinding.blurSeek.progress
                )
                mUserViewModel.changeUserInfo(
                    GsonUtils.toJson(entity),
                    UserViewModel.TYPE_BACKGROUND
                )
            }, {
                it.printStackTrace()
                mPostDialog?.dismiss()
            })

    }


    private fun uploadImage(path: String): Single<String> {
        return Single.create {
            UploadImageUtils.uploadImage(
                UploadImageUtils.UploadType.user_background,
                path,
                object : UploadImageUtils.OnUploadImageListener {
                    override fun onSuccess(imageUrl: String) {
                        it.onSuccess(imageUrl)
                    }

                    override fun onError(e: Throwable?) {
                        if (e is HttpException) {
                            val entity =
                                e.response()?.errorBody()?.string()?.toObject<ErrorEntity>()
                            if (entity?.code == 403033) {
                                toast("图片违规")
                            }
                        }
                        it.onError(e ?: Throwable())
                    }

                    override fun onProgress(total: Long, progress: Long) {

                    }

                })
        }
    }


    private fun selectPic(activity: Activity) {
        PermissionHelper.checkStoragePermissionBeforeAction(activity) {
            startActivityForResult(
                LocalMediaActivity.getIntent(
                    requireContext(),
                    ChooseType.IMAGE,
                    1,
                    "个性背景"
                ), MEDIA_STORE_REQUEST
            )
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == MEDIA_STORE_REQUEST && resultCode == Activity.RESULT_OK) {
            val selectedPaths = Matisse.obtainPathResult(data)
            if (selectedPaths.size > 0) {
                val intent =
                    BackgroundClipActivity.getIntent(requireContext(), selectedPaths[0], mEntrance)
                startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
            }
        } else if (requestCode == REQUEST_CODE_IMAGE_CROP && resultCode == Activity.RESULT_OK) {
            if (data != null) {
                val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH)
                mOriginBitmap = BitmapUtils.getBitmapByFile(imagePath, Bitmap.Config.ARGB_8888)
                if (mOriginBitmap == null) return
                val progress = mBinding.blurSeek.progress
                mTempBitmap =
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && progress != 0) {
                        BitmapUtils.getBlurBitmap(requireContext(), mOriginBitmap, progress)
                    } else {
                        Bitmap.createBitmap(mOriginBitmap!!)
                    }
                mBinding.personalHomeIv.setImageBitmap(mTempBitmap)
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        mOriginBitmap = null
        mTempBitmap = null
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mBinding.normalToolbar.setNavigationIcon(com.gh.gamecenter.common.R.drawable.ic_bar_back)
        mBinding.topBackground.background =
            if (mIsDarkModeOn) null else R.drawable.bg_background_preview_top.toDrawable(requireContext())
    }

    companion object {
        const val REQUEST_CODE_IMAGE_CROP = 100
        const val MEDIA_STORE_REQUEST = 101
    }
}