package com.gh.gamecenter.forum.home.follow.fragment

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.view.View
import androidx.core.view.children
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ItemDecoration
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.LazyFragment
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.databinding.FragmentAllFollowedBinding
import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.forum.home.follow.AllFollowedNoTopItem
import com.gh.gamecenter.forum.home.follow.AllFollowedNormalItem
import com.gh.gamecenter.forum.home.follow.adapter.AllFollowedAdapter
import com.gh.gamecenter.forum.home.follow.viewmodel.AllFollowedViewModel
import com.gh.gamecenter.livedata.EventObserver
import com.lightgame.listeners.OnBackPressedListener
import com.lightgame.utils.toast.ToastHelper
import splitties.resources.color
import java.util.*
import kotlin.math.abs

class AllFollowedFragment : LazyFragment(), OnBackPressedListener {

    private lateinit var binding: FragmentAllFollowedBinding

    private val viewModel by viewModels<AllFollowedViewModel>()

    private val itemTouchHelper = ItemTouchHelper(MyItemTouchCallback())

    private var originalTopList = listOf<AllFollowedNormalItem>()

    private val paint by lazy {
        Paint().apply {
            color = com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext())
            textSize = 14F.dip2px().toFloat()
        }
    }

    private val overPaint by lazy {
        Paint().apply {
            color = com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext())
        }
    }

    private val adapter by lazy(LazyThreadSafetyMode.NONE) {
        AllFollowedAdapter(viewModel) {
            startDrag(it)
        }
    }

    override fun getRealLayoutId(): Int = R.layout.fragment_all_followed

    override fun onRealLayoutInflated(inflatedView: View) {
        binding = FragmentAllFollowedBinding.bind(inflatedView)
    }

    override fun onFragmentFirstVisible() {
        super.onFragmentFirstVisible()
        binding.rvFollowed.layoutManager = LinearLayoutManager(requireContext())
        binding.rvFollowed.adapter = adapter
        binding.rvFollowed.addItemDecoration(MyItemDecoration(requireContext(), paint, overPaint))
        itemTouchHelper.attachToRecyclerView(binding.rvFollowed)

        with(viewModel) {
            dataList.observe(viewLifecycleOwner) {
                originalTopList = it.filter(AllFollowedNormalItem::isTop)
                adapter.setData(it)
            }

            operateTopSuccessfully.observe(viewLifecycleOwner, EventObserver {
                // 提交成功
                ToastHelper.showToast(requireContext(), getString(R.string.save_successfully))
                finish(true)
            })

            detailDestination.observe(viewLifecycleOwner, EventObserver {
                if (it.isUser) {
                    DirectUtils.directToHomeActivity(requireContext(), it.user.id)
                } else {
                    startActivity(ForumDetailActivity.getIntent(requireContext(), it.bbs.id, ""))
                }
            })

            loadFirst()
        }



        binding.tvRight.setOnClickListener {
            if (adapter.isEdit && isDataChanged()) {
                viewModel.operateTop(adapter.getTopItem())
            } else {
                adapter.changeToEditable()
                binding.tvRight.text = if (adapter.isEdit) "保存" else "完成"
                val textResId = if (adapter.isEdit) R.string.finish else R.string.manager
                binding.tvRight.setText(textResId)
            }
        }
        binding.ivBack.setOnClickListener {
            if (adapter.isEdit && isDataChanged()) {
                showSaveTipsDialog()
            } else {
                finish()
            }
        }

    }

    private fun showSaveTipsDialog() {
        DialogHelper.showDialog(
            requireContext(),
            getString(R.string.archive_dialog_title),
            getString(R.string.whether_to_save_changes),
            cancelText = getString(R.string.dialog_nickname_cancel),
            confirmText = getString(R.string.servers_subscribed_game_unsubscribe_dialog_confirm),
            confirmClickCallback = {
                viewModel.operateTop(adapter.getTopItem())
            },
            cancelClickCallback = {
                 finish()
            },
            extraConfig = DialogHelper.Config(showCloseIcon = false, centerTitle = true, centerContent = true)
        )
    }

    private fun isDataChanged(): Boolean = originalTopList != adapter.dataList.filter(AllFollowedNormalItem::isTop)

    private fun startDrag(viewHolder: RecyclerView.ViewHolder) {
        itemTouchHelper.startDrag(viewHolder)
    }

    override fun onHandleBackPressed(): Boolean {
        if (adapter.isEdit && isDataChanged()) {
            showSaveTipsDialog()
            return true
        }
        finish()
        return true
    }

    private fun finish(isSorted: Boolean = false) {
        if (viewModel.hasReadSetIds.isNotEmpty() || isSorted) {
            val intent = Intent()
            // 如果顺序发生变化，则直接通知外部重新加载列表，无需局部更新阅读状态
            if (!isSorted) {
                intent.putStringArrayListExtra(KEY_HAS_READ_ID, viewModel.hasReadSetIds.toList().toArrayList())
            }
            activity?.setResult(Activity.RESULT_OK, intent)
        }
        activity?.finish()
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()

        paint.color = com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext())
        overPaint.color = com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext())

        binding.rvFollowed.tryToClearRecycler()
        binding.rvFollowed.recycledViewPool.clear()
        adapter.notifyItemRangeChanged(0, adapter.itemCount)
    }

    companion object {
        const val KEY_HAS_READ_ID = "key_has_read_id"
    }

    private class MyItemDecoration(
        private val context: Context,
        private val paint: Paint,
        private val overPaint: Paint
    ) : ItemDecoration() {

        private val headerHeight by lazy(LazyThreadSafetyMode.NONE) {
            HEADER_HEIGHT.dip2px()
        }

        private val screenWidth by lazy(LazyThreadSafetyMode.NONE) {
            context.resources.displayMetrics.widthPixels
        }

        override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
            // 是否需要绘制 置顶 悬浮头部
            val adapter = parent.adapter
            if (adapter is AllFollowedAdapter) {
                // 寻找最后一个 置顶 的itemView
                val lastTopView = parent.children.lastOrNull {
                    val position = parent.getChildAdapterPosition(it)
                    val item = if (position != -1) {
                        adapter.getItem(position)
                    } else {
                        null
                    }

                    (item is AllFollowedNormalItem && item.isTop) || item is AllFollowedNoTopItem
                }
                if (lastTopView != null) {
                    // 绘制 置顶 悬浮条
                    val bottom = if (lastTopView.bottom >= headerHeight) {
                        headerHeight
                    } else {
                        lastTopView.bottom
                    }
                    c.drawRect(
                        Rect(0, 0, screenWidth, bottom),
                        overPaint
                    )
                    val text = "置顶(${adapter.topItemCount}/${adapter.followedCount})"
                    drawFollowedHeader(text, c, bottom)
                } else {
                    // 绘制 “我的关注” 悬浮条
                    c.drawRect(
                        Rect(0, 0, screenWidth, headerHeight),
                        overPaint
                    )
                    drawFollowedHeader("我的关注", c, headerHeight)
                }
            }

        }

        private fun drawFollowedHeader(text: String, c: Canvas, bottom: Int) {
            val fontMetrics = paint.fontMetrics
            val centerYDistanceToBaseline =
                (abs(fontMetrics.descent) + abs(fontMetrics.ascent) + abs(fontMetrics.leading)) / 2 - abs(
                    fontMetrics.descent
                )
            val baselineY = bottom - 25F.dip2px().toFloat() + centerYDistanceToBaseline
            c.drawText(text, 0, text.length, 16F.dip2px().toFloat(), baselineY, paint)

        }

        companion object {
            private const val HEADER_HEIGHT = 50F
        }
    }

    private class MyItemTouchCallback : ItemTouchHelper.Callback() {
        override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
            return makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0)
        }

        override fun onMove(
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder,
            target: RecyclerView.ViewHolder
        ): Boolean {
            val adapter = recyclerView.adapter as? AllFollowedAdapter
            if (adapter != null) {
                val position = viewHolder.bindingAdapterPosition
                val item = adapter.getItem(position)
                if (item is AllFollowedNormalItem && item.isTop) {
                    val targetPosition = target.bindingAdapterPosition
                    val targetItem = adapter.getItem(targetPosition)
                    if (targetItem is AllFollowedNormalItem && targetItem.isTop) {
                        val newList = ArrayList(adapter.dataList)
                        val dataPosition = newList.indexOfFirst { it.data.id == item.data.id }
                        val targetDataPosition = newList.indexOfFirst { it.data.id == targetItem.data.id }
                        Collections.swap(newList, dataPosition, targetDataPosition)
                        adapter.setData(newList)
                        return true
                    }
                }
            }
            return false
        }

        override fun isLongPressDragEnabled(): Boolean = false

        override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) = Unit
    }
}