package com.kaixed.kchat.ui.fragment

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.os.IBinder
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity.BIND_AUTO_CREATE
import androidx.recyclerview.widget.LinearLayoutManager
import com.kaixed.kchat.R
import com.kaixed.kchat.data.objectbox.ObjectBox.get
import com.kaixed.kchat.data.objectbox.entity.ChatLists
import com.kaixed.kchat.data.objectbox.entity.ChatLists_
import com.kaixed.kchat.data.objectbox.entity.Messages
import com.kaixed.kchat.databinding.FragmentHomeBinding
import com.kaixed.kchat.model.HomeItem
import com.kaixed.kchat.service.WebSocketService
import com.kaixed.kchat.service.WebSocketService.LocalBinder
import com.kaixed.kchat.ui.activity.AddFriendsActivity
import com.kaixed.kchat.ui.activity.ContactUpdatesActivity
import com.kaixed.kchat.ui.activity.FriendListActivity
import com.kaixed.kchat.ui.activity.MessageActivity
import com.kaixed.kchat.ui.activity.ProfileActivity
import com.kaixed.kchat.ui.activity.SearchActivity
import com.kaixed.kchat.ui.adapter.ChatListAdapter
import com.kaixed.kchat.ui.adapter.MyGridAdapter
import com.kaixed.kchat.ui.base.BaseFragment
import com.kaixed.kchat.ui.i.OnChatListItemClickListener
import com.kaixed.kchat.utils.Constants.MMKV_COMMON_DATA
import com.tencent.mmkv.MMKV
import io.objectbox.Box

class HomeFragment : BaseFragment<FragmentHomeBinding>(), OnChatListItemClickListener {

    private var chatLists: MutableList<ChatLists> = ArrayList()

    private var chatListAdapter: ChatListAdapter? = null

    private var chatListsBox: Box<ChatLists>? = null

    private var messagesBox: Box<Messages>? = null

    private var updateUsername: String? = null

    private val items: MutableList<HomeItem> = ArrayList()

    private var webSocketService: WebSocketService? = null

    private var flipped = false

    private var bound = false

    private lateinit var context: Context

    override fun inflateBinding(
        inflater: LayoutInflater,
        container: ViewGroup?
    ): FragmentHomeBinding {
        return FragmentHomeBinding.inflate(inflater, container, false)
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        context = requireContext()
        chatListsBox = get().boxFor(ChatLists::class.java)
        messagesBox = get().boxFor(Messages::class.java)
        initView()
        startService()
        setOnClick()
    }

    private fun setOnClick() {
        binding.ivMessage.setOnClickListener {
            val intent = Intent(
                context,
                MessageActivity::class.java
            )
            startActivity(intent)
        }
        binding.ivSearch.setOnClickListener {
            val intent =
                Intent(context, SearchActivity::class.java)
            startActivity(intent)
        }

        binding.ifvAvatar.setOnClickListener {
            val intent =
                Intent(context, ProfileActivity::class.java)
            startActivity(intent)
        }
    }

    private fun flipImage(v: View) {
        val flipAnimation = if (flipped) {
            ObjectAnimator.ofFloat(v, "rotationX", 180f, 0f)
        } else {
            ObjectAnimator.ofFloat(v, "rotationX", 0f, 180f)
        }
        flipAnimation.setDuration(0)
        flipAnimation.start()
        flipped = !flipped
    }

    @SuppressLint("NotifyDataSetChanged")
    fun notifyData() {
        chatListAdapter!!.notifyDataSetChanged()
    }

    private fun startService() {
        val intent = Intent(
            context,
            WebSocketService::class.java
        )
        context.startService(intent)
    }

    private fun observeLiveData() {
        if (webSocketService == null) {
            return
        }
        webSocketService!!.liveData.observe(
            this
        ) { messages: Messages ->
            if ("0" == messages.type) {
                processMessage(messages)
            }
        }
    }

    private fun processMessage(messages: Messages) {
        val talkerId = messages.takerId
        val content = messages.content
        val timestamp = messages.timestamp

        val chatList = createChatList(talkerId, content, timestamp)

        val index = findChatListIndex(talkerId)
        if (index == -1) {
            chatLists.add(chatList)
        } else {
            updateChatList(chatLists[index], content, timestamp)
        }

        notifyData()
        requireActivity().runOnUiThread { this.notifyData() }
        isInDb(chatList)
    }

    private fun createChatList(talkerId: String, content: String, timestamp: Long): ChatLists {
        return ChatLists(
            0L,
            talkerId,
            talkerId,
            "1",
            content,
            timestamp,
            1
        )
    }

    private fun findChatListIndex(talkerId: String): Int {
        for (i in chatLists.indices) {
            if (chatLists[i].talkerId == talkerId) {
                return i
            }
        }
        return -1
    }

    private fun updateChatList(chatList: ChatLists, content: String, timestamp: Long) {
        chatList.lastContent = content
        chatList.timestamp = timestamp
    }

    private fun isInDb(chatList: ChatLists) {
        // 查询数据库中是否已经存在该talkerId的记录
        val existingChatList = chatListsBox
            ?.query(ChatLists_.talkerId.equal(chatList.talkerId))
            ?.build()
            ?.findFirst()

        if (existingChatList != null) {
            // 如果存在，更新内容和时间戳
            existingChatList.lastContent = chatList.lastContent
            existingChatList.timestamp = chatList.timestamp
            chatListsBox!!.put(existingChatList)
        } else {
            // 如果不存在，添加新的记录
            chatListsBox!!.put(chatList)
        }
    }

    private fun updateChatLists() {
        val kv = MMKV.mmkvWithID(MMKV_COMMON_DATA)
        val msgLocalId = kv.getLong("msgLocalId", -1L)
        if (msgLocalId != -1L) {
            val messages = messagesBox!![msgLocalId]
            processMessage(messages)
            kv.remove("msgLocalId")
        }
    }

    private var connection: ServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(className: ComponentName, service: IBinder) {
            val binder = service as LocalBinder
            webSocketService = binder.getService()
            bound = true
            observeLiveData()
        }

        override fun onServiceDisconnected(arg0: ComponentName) {
            bound = false
        }
    }

    private fun initView() {
        setupGridView()
        setupRecycleView()
        setupMoreOptionsToggle()
    }

    private fun setupMoreOptionsToggle() {
        binding.ivMore.setOnClickListener { v ->
            flipImage(v)
            val gridViewHeight = binding.gridView.height
            val startAt: Int
            val endAt: Int
            if (flipped) {
                binding.gridView.visibility = View.VISIBLE
                startAt = 0
                endAt = gridViewHeight
            } else {
                startAt = gridViewHeight
                endAt = 0
            }
            createAnimator(startAt, endAt).start()
        }
    }

    private fun createAnimator(start: Int, end: Int): ObjectAnimator {
        val animator = ObjectAnimator.ofInt(binding!!.linearlayout, "top", start, end)
        val duration: Long = 500
        animator.setDuration(duration)

        animator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationStart(animation: Animator) {
                super.onAnimationStart(animation)
                binding.ivMore.isEnabled = false
            }

            override fun onAnimationEnd(animation: Animator) {
                super.onAnimationEnd(animation)
                if (!flipped) {
                    binding.gridView.visibility = View.INVISIBLE
                }
                binding.ivMore.isEnabled = true
            }
        })
        return animator
    }

    private fun setupRecycleView() {
        chatListsBox!!.all?.let {
            chatLists = chatListsBox!!.all
        }
        chatListAdapter = ChatListAdapter(chatLists, context)
        binding.recycleChatList.layoutManager =
            LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
        binding.recycleChatList.adapter = chatListAdapter
        chatListAdapter!!.setItemListener(this)
    }

    private fun setupGridView() {
        initMenuData()
        val myGridAdapter = MyGridAdapter(context, items)
        binding.gridView.adapter = myGridAdapter

        binding.gridView.selector = ColorDrawable(Color.TRANSPARENT)

        binding.gridView.setOnItemClickListener { _, _, position, _ ->
            when (position) {
                0 -> {}
                2 -> {
                    val intent =
                        Intent(
                            context,
                            AddFriendsActivity::class.java
                        )
                    startActivity(intent)
                }

                4 -> {
                    val intent2 =
                        Intent(
                            context,
                            ContactUpdatesActivity::class.java
                        )
                    startActivity(intent2)
                }

                6 -> {
                    val intent1 =
                        Intent(
                            context,
                            FriendListActivity::class.java
                        )
                    startActivity(intent1)
                }
            }
        }
    }

    private fun initMenuData() {
        items.add(HomeItem("更换背景", true, R.drawable.ic_switch))
        items.add(HomeItem("创建群聊", false, R.drawable.ic_troop))
        items.add(HomeItem("新朋友", true, R.drawable.ic_friend))
        items.add(HomeItem("夜间模式", true, R.drawable.ic_night))
        items.add(HomeItem("好友动态", false, R.drawable.ic_qzone))
        items.add(HomeItem("扫一扫", false, R.drawable.ic_discovery_scan))
        items.add(HomeItem("通讯录", true, R.drawable.ic_clock_in))
        items.add(HomeItem("关闭应用", false, R.drawable.ic_exit))
    }


    override fun onResume() {
        super.onResume()
        updateChatLists()
    }

    override fun onStart() {
        super.onStart()
        val intent = Intent(
            context,
            WebSocketService::class.java
        )
        requireActivity().bindService(intent, connection, BIND_AUTO_CREATE)
    }

    override fun onStop() {
        super.onStop()
        if (bound) {
            context.unbindService(connection)
            bound = false
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        val intent = Intent(
            context,
            WebSocketService::class.java
        )
        context.stopService(intent)
    }

    override fun onItemClick(username: String?) {
        this.updateUsername = username
    }

}
