package com.cheng.blzb.ui.fragment.bid.publish.bid

import android.annotation.SuppressLint
import android.os.Build
import android.text.TextUtils
import android.view.ViewOutlineProvider
import android.view.ViewTreeObserver
import androidx.activity.result.contract.ActivityResultContracts
import androidx.constraintlayout.widget.ConstraintLayout
import com.cheng.blzb.R
import com.cheng.blzb.bean.AreaEntity
import com.cheng.blzb.bean.AttachmentEntity
import com.cheng.blzb.bean.BidDetailEntity
import com.cheng.blzb.bean.BidTypeEntity
import com.cheng.blzb.bean.UploadFileEntity
import com.cheng.blzb.common.Constants
import com.cheng.blzb.databinding.FragmentPublishBidMessageBinding
import com.cheng.blzb.event.BidEvent
import com.cheng.blzb.impl.TextWatcherImpl
import com.cheng.blzb.manager.UserConfigManager
import com.cheng.blzb.ui.activity.PublicActivity
import com.cheng.blzb.ui.dialog.SelectAreaDialog
import com.cheng.blzb.ui.dialog.SelectBidTypeDialog
import com.cheng.blzb.ui.dialog.SelectContactsDialog
import com.cheng.blzb.ui.fragment.bid.publish.AddBidContactsAdapter
import com.cheng.blzb.ui.fragment.bid.publish.AddBidFileAdapter
import com.cheng.blzb.ui.fragment.bid.publish.AddBidImageAdapter
import com.cheng.blzb.ui.fragment.bid.publish.my.MyPublishFragment
import com.cheng.blzb.utils.FileProviderUtils
import com.cheng.blzb.utils.GlideEngine
import com.cheng.blzb.utils.PermissionUtils
import com.example.base.common.RxBus
import com.example.base.extensions.getColor
import com.example.base.extensions.gone
import com.example.base.extensions.onClick
import com.example.base.extensions.toast
import com.example.base.extensions.visible
import com.example.base.ui.BaseFragment
import com.example.base.utils.SpanUtils
import com.google.gson.Gson
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.google.gson.reflect.TypeToken
import com.huantansheng.easyphotos.EasyPhotos
import com.huantansheng.easyphotos.callback.SelectCallback
import com.huantansheng.easyphotos.models.album.entity.Photo
import okhttp3.RequestBody.Companion.toRequestBody
import org.jetbrains.anko.sdk27.listeners.onTouch
import java.io.File

class PublishBidMessageFragment : BaseFragment<FragmentPublishBidMessageBinding, PublishBidMessageViewModel>() {
    private var bidDetail: BidDetailEntity? = null

    private val imageAdapter by lazy { AddBidImageAdapter(requireContext(), uploadedImgList) }
    private var uploadedImgList: ArrayList<UploadFileEntity> = ArrayList()

    private val fileAdapter by lazy { AddBidFileAdapter() }
    private val selectedFileList = ArrayList<File>()

    private val deletedList = mutableListOf<String>()

    private val contactsAdapter by lazy { AddBidContactsAdapter() }

    private var contentType: Int = 1 //1 文字 2 图片

    private var city: AreaEntity? = null
    private var bidType: BidTypeEntity? = null

    private val textWatcher = object : TextWatcherImpl() {
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            super.onTextChanged(s, start, before, count)
            SpanUtils.with(binding.tvTextCount)
                .append("${s?.length ?: 0}")
                .setForegroundColor(getColor(R.color.color_1a1a1a))
                .append("/20000")
                .create()
        }
    }

    override fun initView() {
        super.initView()
        binding.tvDesc.typeface = Constants.dtjbt

        binding.rvImages.adapter = imageAdapter
        binding.rvFiles.adapter = fileAdapter
        binding.rvContacts.adapter = contactsAdapter

        binding.ivTopBg.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                val lp1 = binding.tvDesc.layoutParams as ConstraintLayout.LayoutParams
                lp1.topMargin = (binding.ivTopBg.height * 100f / 268f).toInt()
                binding.tvDesc.layoutParams = lp1

                val lp2 = binding.layoutContent.layoutParams as ConstraintLayout.LayoutParams
                lp2.topMargin = (binding.ivTopBg.height * 168f / 268f).toInt()
                binding.layoutContent.layoutParams = lp2

                binding.layoutContent.setupWith(binding.layoutContainer).setFrameClearDrawable(binding.layoutContent.background).setBlurRadius(5f)
                binding.layoutContent.outlineProvider = ViewOutlineProvider.BACKGROUND
                binding.layoutContent.setClipToOutline(true)

                binding.ivTopBg.viewTreeObserver.removeOnGlobalLayoutListener(this)
            }
        })
    }

    override fun initData() {
        super.initData()
        bidDetail = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            arguments?.getSerializable("item", BidDetailEntity::class.java)
        } else {
            arguments?.getSerializable("item") as? BidDetailEntity
        }
        if (bidDetail != null) {
            setData(bidDetail!!)
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    override fun initListener() {
        super.initListener()
        binding.etInfo.addTextChangedListener(textWatcher)

        binding.tvType.onClick {
            val f = SelectBidTypeDialog.newInstance(bidType)
            f.setOnSelectListener {
                bidType = it
                binding.tvType.text = it.name
            }
            f.show(childFragmentManager, SelectBidTypeDialog::class.java.simpleName)
        }

        binding.tvArea.onClick {
            val f = SelectAreaDialog.newInstance(if (city != null) listOf(city!!) else emptyList(), true)
            f.setOnSelectListener {
                city = it[0]
                binding.tvArea.text = city!!.name
            }
            f.show(childFragmentManager, SelectAreaDialog::class.java.simpleName)
        }

        binding.layoutUploadFile.onClick {
            fileLauncher.launch("application/pdf")
        }

        binding.ivAddContacts.onClick {
            val f = SelectContactsDialog.newInstance(contactsAdapter.data)
            f.setOnSelectListener {
                contactsAdapter.setList(it)
                binding.rvContacts.visible()
                binding.tvContacts.gone()
            }
            f.show(childFragmentManager, "")
        }

        binding.tvContacts.onClick {
            binding.ivAddContacts.performClick()
        }

        binding.rvContacts.onTouch { _, _ ->
            binding.ivAddContacts.performClick()
            true
        }

        binding.rgInfoType.setOnCheckedChangeListener { _, checkedId ->
            when (checkedId) {
                R.id.rb1 -> {
                    contentType = 1
                    binding.etInfo.visible()
                    binding.tvTextCount.visible()
                    binding.tvImageCount.gone()
                    binding.tvImageLimitTip.gone()
                    binding.rvImages.gone()
                }

                R.id.rb2 -> {
                    contentType = 2
                    binding.etInfo.gone()
                    binding.tvTextCount.gone()
                    binding.tvImageCount.visible()
                    binding.tvImageLimitTip.visible()
                    binding.rvImages.visible()
                }
            }
        }

        imageAdapter.setOnItemClick { type, position ->
            when (type) {
                AddBidImageAdapter.TYPE_ADD -> {
                    PermissionUtils.checkPhotoPermission(requireActivity(), childFragmentManager, true) { isGranted ->
                        if (isGranted) selectPhoto()
                    }
                }

                AddBidImageAdapter.TYPE_DELETE -> {
                    if (uploadedImgList.isNotEmpty()) {
                        if (bidDetail == null) {
                            mViewModel.deleteFile(uploadedImgList[position].id)
                        }
                        deletedList.add(uploadedImgList[position].id)
                        uploadedImgList.removeAt(position)
                        imageAdapter.notifyDataSetChanged()
                        SpanUtils.with(binding.tvImageCount)
                            .append("(")
                            .append("${uploadedImgList.size}")
                            .setForegroundColor(getColor(R.color.color_ff493c))
                            .append("/10)")
                            .create()
                    }
                }
            }
        }

        fileAdapter.setOnItemChildClickListener { _, _, i ->
            if (bidDetail == null) {
                mViewModel.deleteFile(fileAdapter.getItem(i).id)
            }
            deletedList.add(fileAdapter.getItem(i).id )
            fileAdapter.removeAt(i)
            SpanUtils.with(binding.tvFileCount)
                .append("(")
                .append("${fileAdapter.data.size}")
                .setForegroundColor(getColor(R.color.color_ff493c))
                .append("/5)")
                .create()
        }

        binding.btnNext.onClick {
            val name = binding.etName.text.toString().trim()
            val price = binding.etPrice.text.toString().trim()
            val contentText = binding.etInfo.text.toString().trim()
            if (bidType == null) {
                toast("请选择项目类型")
                return@onClick
            }
            if (TextUtils.isEmpty(name)) {
                toast("请输入项目名称")
                return@onClick
            }
            if (TextUtils.isEmpty(price)) {
                toast("请输入项目价格")
                return@onClick
            }
            if (city == null) {
                toast("请选择发布地区")
                return@onClick
            }
            if (contentType == 1 && TextUtils.isEmpty(contentText)) {
                toast("请输入项目文本信息")
                return@onClick
            }
            if (contentType == 2 && imageAdapter.data.isEmpty()) {
                toast("请上传项目图片信息")
                return@onClick
            }
            if (fileAdapter.data.isEmpty()) {
                toast("请上传项目文件")
                return@onClick
            }
            if (contactsAdapter.data.isEmpty()) {
                toast("请添加联系人")
                return@onClick
            }
            commit()
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    override fun initObserve() {
        super.initObserve()
        mViewModel.addLiveData.observe(this) {
            toast("提交成功")
            RxBus.defaultInstance.post(BidEvent())
            PublicActivity.start(requireContext(), MyPublishFragment::class.java, Pair("type", 1))
            requireActivity().finish()
        }

        mViewModel.imageLiveData.observe(this) {
            uploadedImgList.addAll(it)
            imageAdapter.notifyDataSetChanged()
            SpanUtils.with(binding.tvImageCount)
                .append("(")
                .append("${uploadedImgList.size}")
                .setForegroundColor(getColor(R.color.color_ff493c))
                .append("/10)")
                .create()
        }

        mViewModel.fileLiveData.observe(this) { list ->
            list.forEachIndexed { index, file ->
                fileAdapter.addData(AttachmentEntity(file.id, file.url, "pdf", selectedFileList[index].name))
            }
            SpanUtils.with(binding.tvFileCount)
                .append("(")
                .append("${fileAdapter.data.size}")
                .setForegroundColor(getColor(R.color.color_ff493c))
                .append("/5)")
                .create()
            if (fileAdapter.data.size == 5) {
                binding.layoutUploadFile.gone()
            } else {
                binding.layoutUploadFile.visible()
            }
        }
    }

    private fun commit() {
        val name = binding.etName.text.toString().trim()
        val price = binding.etPrice.text.toString().trim()
        val contentText = binding.etInfo.text.toString().trim()

        val jsonObject = JsonObject()
        jsonObject.addProperty("origin_title", name)
        jsonObject.addProperty("city_id", "${city!!.id}")
        jsonObject.addProperty("type_id", bidType!!.id)
        jsonObject.addProperty("project_amount", price)
        jsonObject.addProperty("content_type", if (contentType == 1) "1" else "2")

        if (contentType == 1) {
            jsonObject.addProperty("origin_content", contentText)
        } else {
            val imageArray = JsonArray()
            uploadedImgList.forEach {
                imageArray.add(it.id)
            }
            jsonObject.add("origin_content", imageArray)
        }

        val attachArray = JsonArray()
        fileAdapter.data.forEach {
            val attachObj = JsonObject()
            attachObj.addProperty("title", it.title)
            attachObj.addProperty("type", "pdf")
            attachObj.addProperty("url", it.url)
            attachArray.add(attachObj)
        }
        jsonObject.add("origin_attachment", attachArray)

        val contactArray = JsonArray()
        contactsAdapter.data.forEach {
            val contactObj = JsonObject()
            contactObj.addProperty("name", it.name)
            contactObj.addProperty("phone", it.phone)
            contactObj.addProperty("job", it.job)
            contactArray.add(contactObj)
        }
        jsonObject.add("contact", contactArray)

        if (bidDetail == null) {
            mViewModel.addBid(jsonObject.toString().toRequestBody())
        } else {
            jsonObject.addProperty("id", bidDetail!!.id)
            mViewModel.updateBid(jsonObject.toString().toRequestBody())
        }
    }

    @SuppressLint("SetTextI18n", "NotifyDataSetChanged")
    private fun setData(detail: BidDetailEntity) {
        if (detail.status == "3") {
            binding.tvReason.text = "理由：${detail.review_remark}"
            binding.tvTime.text = detail.review_time
            binding.layoutRejectReason.visible()
        }
        binding.etName.setText(detail.origin_title)
        binding.etPrice.setText(detail.project_amount)

        city = UserConfigManager.getCityList().find { it.id == detail.city_id.toInt() }
        if (city != null) binding.tvArea.text = city!!.name

        bidType = UserConfigManager.getBidTypes().find { it.id == detail.type_id }
        if (bidType != null) binding.tvType.text = bidType!!.name

        if (detail.content_type == "1") {
            binding.etInfo.setText(detail.origin_content.toString())
            binding.rb1.isChecked = true
        } else {
            val imageList = Gson().fromJson<List<UploadFileEntity>>(Gson().toJson(detail.origin_content), object : TypeToken<List<UploadFileEntity>>(){}.type)
            uploadedImgList.addAll(imageList)
            imageAdapter.notifyDataSetChanged()
            SpanUtils.with(binding.tvImageCount)
                .append("(")
                .append("${uploadedImgList.size}")
                .setForegroundColor(getColor(R.color.color_ff493c))
                .append("/10)")
                .create()
            binding.rb2.isChecked = true
        }

        fileAdapter.setList(detail.origin_attachment)
        if (fileAdapter.data.size == 5) {
            binding.layoutUploadFile.gone()
        }

        contactsAdapter.setList(detail.contact)
        if (contactsAdapter.data.isNotEmpty()) {
            binding.rvContacts.visible()
            binding.tvContacts.gone()
        }
        if (contactsAdapter.data.size == 5) {
            binding.ivAddContacts.gone()
        }
    }

    private val fileLauncher = registerForActivityResult(ActivityResultContracts.GetMultipleContents()) {
        if (it.isEmpty()) return@registerForActivityResult
        if (fileAdapter.data.size + it.size > 5) {
            toast("最多上传5个文件")
            return@registerForActivityResult
        }
        val files = arrayListOf<File>()
        it.forEach { uri ->
            val path = FileProviderUtils.getFileAbsolutePath(requireContext(), uri)
            if (!TextUtils.isEmpty(path)) {
                files.add(File(path!!))
            }
        }
        if (files.find { file -> file.length() > 5 * 1024 * 1024 } != null) {
            toast("单个文件大小不能超过5M")
            return@registerForActivityResult
        }
        selectedFileList.clear()
        selectedFileList.addAll(files)
        mViewModel.fileList.clear()
        mViewModel.uploadFiles(files)
    }

    private fun selectPhoto() {
        EasyPhotos.createAlbum(this, true, false, GlideEngine.getInstance())
            .setFileProviderAuthority(Constants.AppFilter)
            .setCount(imageAdapter.selectMax - uploadedImgList.size)
            .start(object : SelectCallback() {
                @SuppressLint("NotifyDataSetChanged")
                override fun onResult(photos: ArrayList<Photo>, isOriginal: Boolean) {
                    if (photos.find { it.size > 10 * 1024 * 1024 } != null) {
                        toast("单张图片大小不能超过10M")
                        return
                    }
                    mViewModel.imgList.clear()
                    mViewModel.uploadImages(requireContext(), photos)
                }

                override fun onCancel() {
                }
            })
    }

    override fun onDestroyView() {
        binding.etInfo.removeTextChangedListener(textWatcher)
        super.onDestroyView()
    }
}