package com.adealink.weparty.order.refund

import android.annotation.SuppressLint
import android.text.Editable
import android.text.TextWatcher
import androidx.activity.viewModels
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.doOnPreDraw
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.GridLayoutManager
import com.adealink.frame.aab.util.getCompatDimension
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.Rlt
import com.adealink.frame.base.fastLazy
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.frame.router.Router
import com.adealink.frame.router.annotation.BindExtra
import com.adealink.frame.router.annotation.RouterUri
import com.adealink.frame.util.formatTime
import com.adealink.frame.util.onClick
import com.adealink.weparty.commonui.BaseActivity
import com.adealink.weparty.commonui.ext.dp
import com.adealink.weparty.commonui.ext.fitSystemWindows
import com.adealink.weparty.commonui.ext.onWindowInsets
import com.adealink.weparty.commonui.ext.sp
import com.adealink.weparty.commonui.mediapicker.imageselect.comp.TakeFromAlbumComp
import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
import com.adealink.weparty.commonui.recycleview.itemdecoration.GridSpacingItemDecoration
import com.adealink.weparty.commonui.text.setMaxLength
import com.adealink.weparty.commonui.toast.util.showFailedToast
import com.adealink.weparty.commonui.widget.CommonDialog
import com.adealink.weparty.constant.REFUND_REASON_MAX_LENGTH
import com.adealink.weparty.module.image.data.PhotoData
import com.adealink.weparty.module.order.Order
import com.adealink.weparty.module.order.data.OrderDetailData
import com.adealink.weparty.module.order.data.OrderDetailInfo
import com.adealink.weparty.order.databinding.ActivityOrderRefundBinding
import com.adealink.weparty.order.refund.adapter.AddPhotoItemViewBinder
import com.adealink.weparty.order.refund.adapter.PhotoItemViewBinder
import com.adealink.weparty.order.refund.data.AddPhotoItemData
import com.adealink.weparty.order.refund.data.BasePhotoItemData
import com.adealink.weparty.order.util.getOrderAllCost
import com.adealink.weparty.order.viewmodel.OrderViewModel
import com.adealink.weparty.order.viewmodel.OrderViewModelFactory
import com.adealink.weparty.order.viewmodel.RefundViewModel
import com.adealink.weparty.util.QMUIKeyboardHelper
import com.adealink.weparty.util.TIME_FORMAT_DMY_HMS
import com.adealink.weparty.util.applyImmersive
import com.adealink.weparty.util.goImagePreviewActivity
import com.adealink.weparty.R as APP_R

@RouterUri(path = [Order.Refund.PATH], desc = "申请退款")
class RefundActivity : BaseActivity() {

    companion object {
        private const val PICTURE_SPAN = 3
    }


    @BindExtra(Order.Refund.EXTRA_ORDER_ID)
    var orderId: String? = null

    @BindExtra(Order.Refund.EXTRA_ORDER_DETAIL)
    var orderInfo: OrderDetailInfo? = null

    private var orderDetail: OrderDetailData? = null

    private val binding by viewBinding(ActivityOrderRefundBinding::inflate)
    private val orderViewModel by viewModels<OrderViewModel> { OrderViewModelFactory() }
    private val refundViewModel by viewModels<RefundViewModel> { OrderViewModelFactory() }

    private val pictureAdapter by fastLazy { MultiTypeListAdapter<BasePhotoItemData>() }

    private lateinit var takeFromAlbumComp: TakeFromAlbumComp
    override fun onBeforeCreate() {
        super.onBeforeCreate()
        Router.bind(this)
    }

    override fun initViews() {
        super.initViews()
        setContentView(binding.root)
        applyImmersive { top ->
            binding.topBar.setPadding(0, top, 0, 0)
            binding.topBar.updateLayoutParams<ConstraintLayout.LayoutParams> {
                height = top + getCompatDimension(APP_R.dimen.common_top_bar_height).toInt()
            }
        }
        binding.btnRefund.updateLayoutParams<ConstraintLayout.LayoutParams> {
            bottomMargin = getCompatDimension(APP_R.dimen.main_bottom_bar_margin_bottom).toInt()
        }
        binding.clContent.setPadding(
            0, 0, 0,
            getCompatDimension(APP_R.dimen.common_button_height).toInt() + getCompatDimension(APP_R.dimen.main_bottom_bar_margin_bottom).toInt() + 24.dp()
        )
        fitWindow()

        binding.etInput.setMaxLength(REFUND_REASON_MAX_LENGTH)
        binding.etInput.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(
                s: CharSequence?,
                start: Int,
                count: Int,
                after: Int
            ) {
            }

            override fun onTextChanged(
                s: CharSequence?,
                start: Int,
                before: Int,
                count: Int
            ) {
            }

            @SuppressLint("SetTextI18n")
            override fun afterTextChanged(s: Editable?) {
                val input = s?.trim()?.toString()
                if (input.isNullOrEmpty()) {
                    binding.btnRefund.isEnabled = false
                    binding.tvInputCount.text = "0/${REFUND_REASON_MAX_LENGTH}"
                } else {
                    binding.btnRefund.isEnabled = true
                    binding.tvInputCount.text = "${input.length}/${REFUND_REASON_MAX_LENGTH}"
                }
            }
        })
        binding.btnRefund.isEnabled = false

        pictureAdapter.register(
            AddPhotoItemViewBinder() {
                addPicture()
            }
        )
        pictureAdapter.register(
            PhotoItemViewBinder(
                onItemClick = {
                    previewPicture(it.data)
                },
                onDeleteClick = {
                    deletePicture(it.data)
                }
            ))
        binding.rvPicture.adapter = pictureAdapter
        binding.rvPicture.layoutManager = GridLayoutManager(this, PICTURE_SPAN)
        binding.rvPicture.addItemDecoration(
            GridSpacingItemDecoration(PICTURE_SPAN, 4.dp(), 4.dp(), false)
        )

        binding.btnRefund.onClick {
            refundApply()
        }
    }

    private fun fitWindow() {
        // 关键：只在需要的时候设置
        window?.fitSystemWindows(false)
        // 内容布局处理键盘
        val nsvContent = binding.nsvContent
        binding.nsvContent.onWindowInsets { view, insets ->
            val ime = insets.getInsets(WindowInsetsCompat.Type.ime())
            val nav = insets.getInsets(WindowInsetsCompat.Type.navigationBars())

            // 键盘显示时使用键盘高度，否则使用导航栏高度
            val bottomInset = if (ime.bottom > 0) ime.bottom else nav.bottom
            view.updatePadding(bottom = bottomInset)
            nsvContent.doOnPreDraw {
                nsvContent.smoothScrollTo(0, bottomInset)
            }
            insets
        }
    }

    override fun loadData() {
        super.loadData()
        val orderInfo = this@RefundActivity.orderInfo
        if (orderInfo != null) {
            updateOrderDetail(OrderDetailData(orderInfo, null, null, null, null))
        }
        val orderId = orderInfo?.orderId ?: this@RefundActivity.orderId
        if (!orderId.isNullOrEmpty()) {
            orderViewModel.loadOrderDetail(orderId).observe(this) { rlt ->
                when (rlt) {
                    is Rlt.Failed -> {
                        showFailedToast(rlt)
                    }

                    is Rlt.Success -> {
                        updateOrderDetail(rlt.data)
                    }
                }
            }
        }
        pictureAdapter.submitList(
            listOf(AddPhotoItemData)
        )
    }

    @SuppressLint("SetTextI18n")
    private fun updateOrderDetail(data: OrderDetailData?) {
        this.orderDetail = data

        binding.ivOrderAvatar.setImageUrl(data?.order?.avatar)
        binding.tvOrderName.text = data?.order?.nickname

        binding.tvProductTypeDetail.text = data?.order?.categoryName
        binding.tvOrderCountDetail.text = "${data?.order?.purchaseQty} x ${data?.order?.unit}"
        binding.tvOrderIdDetail.text = data?.order?.orderId
        binding.tvOrderTimeDetail.text =
            formatTime(data?.order?.createTime ?: 0, TIME_FORMAT_DMY_HMS)
        binding.tvOrderCostDetail.text =
            getOrderAllCost(
                data?.order?.price ?: 0f,
                data?.order?.purchaseQty ?: 0,
                data?.order?.totalAmount,
                12.sp(),
                12.dp()
            )
    }

    override fun initComponents() {
        super.initComponents()
        TakeFromAlbumComp(
            this,
            clipParamData = null,
            onSelect = { path, uri ->
                refundViewModel.addPicture(path, uri)
            }
        ).also {
            takeFromAlbumComp = it
        }.attach()
    }

    override fun observeViewModel() {
        super.observeViewModel()
        refundViewModel.pictureItemListLD.observe(this) {
            pictureAdapter.submitList(it)
        }
    }

    private fun addPicture() {
        takeFromAlbumComp.takeFromAlbum()
    }

    private fun previewPicture(data: PhotoData) {
        val uri = data.uri
        if (uri.isNullOrEmpty()) {
            return
        }
        goImagePreviewActivity(
            this,
            arrayListOf(uri)
        )
    }

    private fun deletePicture(data: PhotoData) {
        refundViewModel.removePicture(data)
    }

    private fun refundApply() {
        fun refund() {
            val orderData = orderDetail?.order ?: return
            showLoading()
            refundViewModel.refundApply(orderData, binding.etInput.text?.toString())
                .observe(this) { rlt ->
                    dismissLoading()
                    when (rlt) {
                        is Rlt.Failed -> {
                            showFailedToast(rlt)
                        }

                        is Rlt.Success -> {
                            finish()
                        }
                    }
                }
        }
        CommonDialog.Builder()
            .title(getCompatString(APP_R.string.common_user_refund_order_tips))
            .positiveText(getCompatString(APP_R.string.commonui_confirm))
            .setShowDefaultCancel(true)
            .onPositive {
                refund()
            }
            .show(supportFragmentManager)
    }

    override fun onDestroy() {
        binding.etInput.clearFocus()
        QMUIKeyboardHelper.hideKeyboard(binding.etInput)
        super.onDestroy()
    }

}