package com.example.defenseapplication.home

import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.os.Build
import android.graphics.Rect
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.util.Log
import android.util.TypedValue
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.defenseapplication.R
import com.example.defenseapplication.adapter.DeviceAdapter
import com.example.defenseapplication.adapter.DeviceUi
import com.example.defenseapplication.adapter.FamilyAdapter
import com.example.defenseapplication.bean.DeviceBean
import com.example.defenseapplication.bean.FamilyBean
import com.example.defenseapplication.bean.SwitchFamilyRequest
import com.example.defenseapplication.databinding.HomeMenuFragmentBinding
import com.example.defenseapplication.utils.DeviceIdEvent
import com.example.defenseapplication.utils.DeviceUpdateEvent
import com.example.defenseapplication.utils.FamilySwitchEvent
import com.example.defenseapplication.utils.MessageStatusManager
import com.example.defenseapplication.utils.RetrofitNetwork
import com.example.defenseapplication.utils.UserinfoUtil
import com.example.defenseapplication.view.DefenseDialogs
import com.example.defenseapplication.view.showDefenseDialog
import com.gyf.immersionbar.ImmersionBar
import com.maning.mlkitscanner.scan.MNScanManager
import com.maning.mlkitscanner.scan.callback.act.MNScanCallback
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
//主页碎片
class HomeMenuFragment : Fragment() {
    // ViewBinding
    private var _binding: HomeMenuFragmentBinding? = null
    private val binding get() = _binding!!
    private val familyAdapter by lazy { FamilyAdapter(::onFamilySelected) }
    private val deviceAdapter by lazy { DeviceAdapter(::onDeviceClicked) }

    private var isFamilyExpanded = false
    private lateinit var currentFamily: String
    private var currentPage = 1
    private val pageSize = 10
    private var hasMore = true
    private var isLoading = false

    private val requestPermissionsLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        val cameraGranted = permissions[Manifest.permission.CAMERA] ?: false
        
        val storageGranted = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            permissions[Manifest.permission.READ_MEDIA_IMAGES] ?: false
        } else {
            permissions[Manifest.permission.READ_EXTERNAL_STORAGE] ?: false
        }
        
        if (cameraGranted && storageGranted) {
            startScan()
        } else {
            Toast.makeText(requireContext(), R.string.permission_denied, Toast.LENGTH_SHORT).show()
        }
    }

    private fun checkPermissionsAndScan() {
        val cameraPermission = ContextCompat.checkSelfPermission(
            requireContext(),
            Manifest.permission.CAMERA
        )
        
        val storagePermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            ContextCompat.checkSelfPermission(
                requireContext(),
                Manifest.permission.READ_MEDIA_IMAGES
            )
        } else {
            ContextCompat.checkSelfPermission(
                requireContext(),
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            )
        }

        if (cameraPermission == PackageManager.PERMISSION_GRANTED && 
            storagePermission == PackageManager.PERMISSION_GRANTED) {
            startScan()
        } else {
            val permissionsToRequest = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                arrayOf(
                    Manifest.permission.CAMERA,
                    Manifest.permission.READ_MEDIA_IMAGES
                )
            } else {
                arrayOf(
                    Manifest.permission.CAMERA,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
                )
            }
            requestPermissionsLauncher.launch(permissionsToRequest)
        }
    }

    private fun startScan() {
        MNScanManager.startScan(requireContext() as Activity, object: MNScanCallback {
            override fun onActivityResult(resultCode: Int, data: Intent?) {
                when (resultCode) {
                    MNScanManager.RESULT_SUCCESS -> {
                        val result = data?.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
                        if (!result.isNullOrEmpty()) {
                            ToastUtils.showToast(requireContext(), "扫码成功: $result")
                        } else {
                            ToastUtils.showToast(requireContext(), "扫码结果为空")
                        }
                    }
                    MNScanManager.RESULT_FAIL -> {
                        val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
                        ToastUtils.showToast(requireContext(), "扫码失败: $error")
                    }
                    MNScanManager.RESULT_CANCLE -> {
                        ToastUtils.showToast(requireContext(), "扫码取消")
                    }
                }
            }
        })
    }

    private val unreadCountChangeListener = object : MessageStatusManager.UnreadCountChangeListener {
        override fun onUnreadCountChanged(count: Int) {
            updateUnreadCountUI(count)
        }
    }

    private val familySwitchListener = object : FamilySwitchEvent.FamilySwitchListener {
        override fun onFamilySwitched(familyName: String) {
            if (familyName != currentFamily) {
                currentFamily = familyName
                updateFamilyDisplayText(familyName)
                familyAdapter.submitList(familyBeanList, currentFamily)
                switchToFamily(familyName)
            }
        }
    }

    private val deviceUpdateListener = object : DeviceUpdateEvent.DeviceUpdateListener {
        override fun onDeviceUpdated(deviceId: String) {
            refreshDeviceList()
        }
    }

    private fun updateFamilyDisplayText(familyName: String) {
        val familyBean = familyBeanList.find { it.parentName == familyName }
        val isAdmin = familyBean?.role == "appadmin"
        binding.tvCurrentFamily.text = if (isAdmin) {
            getString(R.string.my_family)
        } else {
            "${familyName}${getString(R.string.family_with_normal)}"
        }
    }

    private var familyList: List<String> = emptyList()
    private var familyBeanList: List<FamilyBean> = emptyList()
    private var deviceBeanList: List<DeviceBean> = emptyList()
    private var canViewDevice = false

    private val currentFamilyBean: FamilyBean?
        get() = familyBeanList.find { it.parentName == currentFamily }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = HomeMenuFragmentBinding.inflate(inflater, container, false)
        ImmersionBar.with(this)
            .statusBarDarkFont(true)
            .titleBar(binding.main)
            .init()
        initView()
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // 为 LinearLayout 设置渐变背景
        setGradientBackground(
            view = binding.gradientLayout,
            startColor = Color.parseColor("#EBDCED"),
            endColor = Color.parseColor("#CAF4FF")
        )
        binding.message.setOnClickListener { 
            val intent = Intent(requireContext(), MessageActivity::class.java)
            startActivity(intent)
        }
        binding.add.setOnClickListener {
            val intent = Intent(requireContext(), AddDeviceActivity::class.java)
            startActivity(intent)
        }
        binding.addFamily.setOnClickListener {
            checkPermissionsAndScan()
        }

        fetchFamilyList()
        fetchUnreadMessageCount()

        MessageStatusManager.addListener(unreadCountChangeListener)
        FamilySwitchEvent.addListener(familySwitchListener)
        DeviceUpdateEvent.addListener(deviceUpdateListener)
        updateUnreadCountUI(MessageStatusManager.getUnreadCount())
    }

    private fun initView() {
        binding.rvFamilyList.layoutManager = LinearLayoutManager(requireContext())
        binding.rvFamilyList.adapter = familyAdapter

        binding.rvDeviceList.layoutManager = GridLayoutManager(requireContext(), 2)
        binding.rvDeviceList.adapter = deviceAdapter
        if (binding.rvDeviceList.itemDecorationCount == 0) {
            binding.rvDeviceList.addItemDecoration(
                GridHorizontalSpaceItemDecoration(horizontalSpace = dpToPx(8))
            )
        }

        binding.swipeRefreshLayout.setOnRefreshListener {
            refreshDeviceList()
        }

        binding.rvDeviceList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                val layoutManager = recyclerView.layoutManager as GridLayoutManager
                val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
                val totalItemCount = layoutManager.itemCount

                if (!isLoading && hasMore && lastVisibleItemPosition >= totalItemCount - 1 && dy > 0) {
                    loadMoreDevices()
                }
            }
        })

        binding.familyHeaderLayout.setOnClickListener {
            toggleFamilyList()
        }
        binding.familyPopupMask.setOnClickListener {
            if (isFamilyExpanded) {
                toggleFamilyList()
            }
        }
    }

    private fun fetchUnreadMessageCount() {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val response = RetrofitNetwork.getNetworkService().getMessage()
                withContext(Dispatchers.Main) {
                    if (response.code == 200 && response.data != null) {
                        val messageGroups = response.data as List<*>
                        var unreadCount = 0
                        messageGroups.forEach { group ->
                            if (group is Map<*, *>) {
                                val list = group["list"] as? List<*>
                                list?.let { unreadCount += it.size }
                            }
                        }
                        MessageStatusManager.setUnreadCount(unreadCount)
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    private fun updateUnreadCountUI(count: Int) {
        if (count > 0) {
            binding.tvUnreadCount.visibility = View.VISIBLE
            binding.tvUnreadCount.text = if (count > 99) "99+" else count.toString()
        } else {
            binding.tvUnreadCount.visibility = View.GONE
        }
    }

    private fun fetchFamilyList() {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val response = RetrofitNetwork.getNetworkService().getFamilyList()
                withContext(Dispatchers.Main) {
                    if (response.code == 200 && response.data != null) {
                        familyBeanList = response.data.reversed()
                        familyList = response.data.map { it.parentName }.reversed()
                        if (familyList.isNotEmpty()) {
                            currentFamily = familyList.first()
                            updateFamilyDisplayText(currentFamily)
                            familyAdapter.submitList(familyBeanList, currentFamily)

                            val userInfo = UserinfoUtil.getUserInfo()
                            val currentFamilyData = familyBeanList.firstOrNull()
                            canViewDevice = userInfo?.role == "appadmin" && currentFamilyData?.role != "member"
                            updateAdminUI()

                            switchToFamily(currentFamily)
                        }
                    } else {
                        Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(requireContext(), R.string.network_error, Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun updateAdminUI() {
        Log.d("HomeMenuFragment", "canViewDevice = $canViewDevice")
        if (canViewDevice) {
            binding.tvDeviceTitle.visibility = View.VISIBLE
            binding.rvDeviceList.visibility = View.VISIBLE
            binding.message.visibility = View.VISIBLE
            binding.addFamily.visibility = View.VISIBLE
            binding.add.visibility = View.VISIBLE
            binding.layoutNoPermission.visibility = View.GONE
        } else {
            binding.tvDeviceTitle.visibility = View.GONE
            binding.rvDeviceList.visibility = View.GONE
            binding.message.visibility = View.GONE
            binding.addFamily.visibility = View.GONE
            binding.add.visibility = View.GONE
            binding.layoutNoPermission.visibility = View.VISIBLE
        }
    }

    private fun switchToFamily(familyName: String) {
        val familyBean = familyBeanList.find { it.parentName == familyName } ?: return

        CoroutineScope(Dispatchers.IO).launch {
            try {
                val userInfo = UserinfoUtil.getUserInfo()
                val request = SwitchFamilyRequest(
                    clientId = "428a8310cd442757ae699df5d894f051",
                    grantType = "switch",
                    id = familyBean.id,
                    userType = "app_user",
                    role = userInfo?.role ?: ""
                )
                val response = RetrofitNetwork.getNetworkService().switchFamily(request)
                withContext(Dispatchers.Main) {
                    if (response.code == 200) {
                        val userInfo = UserinfoUtil.getUserInfo()
                        canViewDevice = userInfo?.role == "appadmin" && familyBean.role != "member"
                        updateAdminUI()
                        updateFamilyDisplayText(familyName)
                        fetchDeviceList()
                        FamilySwitchEvent.notifyFamilySwitched(familyName)
                    } else {
                        Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(requireContext(), R.string.network_error, Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun fetchDeviceList(page: Int = 1, isLoadMore: Boolean = false) {
        if (!canViewDevice || isLoading) return

        isLoading = true

        CoroutineScope(Dispatchers.IO).launch {
            try {
                val response = RetrofitNetwork.getNetworkService().getDeviceList()
                withContext(Dispatchers.Main) {
                    Log.d("DeviceList", "code = ${response.code}, data = ${response.data}")
                    if (response.code == 200 && response.data != null) {
                        val newDevices = response.data
                        if (isLoadMore) {
                            deviceBeanList = deviceBeanList + newDevices
                            hasMore = newDevices.size >= pageSize
                        } else {
                            deviceBeanList = newDevices
                            hasMore = newDevices.size >= pageSize
                        }
                        Log.d("DeviceList", "deviceBeanList size = ${deviceBeanList.size}")
                        updateDeviceList()
                    } else {
                        Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
                        if (isLoadMore) {
                            hasMore = false
                        }
                    }
                    isLoading = false
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(requireContext(), R.string.network_error, Toast.LENGTH_SHORT).show()
                    isLoading = false
                    if (isLoadMore) {
                        hasMore = false
                    }
                }
            }
        }
    }

    private fun refreshDeviceList() {
        currentPage = 1
        hasMore = true
        fetchDeviceList(currentPage, false)
        binding.swipeRefreshLayout.isRefreshing = false
    }

    private fun loadMoreDevices() {
        if (isLoading || !hasMore) return
        currentPage++
        fetchDeviceList(currentPage, true)
    }

    private fun toggleFamilyList() {
        isFamilyExpanded = !isFamilyExpanded
        val visibility = if (isFamilyExpanded) View.VISIBLE else View.GONE
        binding.familyPopupMask.visibility = visibility
        binding.familyPopupCard.visibility = visibility
        binding.ivFamilyArrow.animate()
            .rotation(if (isFamilyExpanded) 180f else 0f)
            .setDuration(200L)
            .start()
    }

    private fun onFamilySelected(familyName: String) {
        currentFamily = familyName
        binding.tvCurrentFamily.text = familyName
        familyAdapter.submitList(familyBeanList, currentFamily)
        switchToFamily(familyName)
        if (isFamilyExpanded) {
            toggleFamilyList()
        }
    }

    private fun updateDeviceList() {
        val deviceUiList = deviceBeanList.map {
            DeviceUi(it.deviceName ?: "", it.status ?: "", it.id ?: "")
        }

        if (deviceUiList.isEmpty()) {
            deviceAdapter.submitList(listOf(
                DeviceUi(getString(R.string.no_device), "0")
            ))
        } else {
            deviceAdapter.submitList(deviceUiList)
        }
    }

    private fun onDeviceClicked(device: DeviceUi) {
        if (device.isOnline) {
            DeviceIdEvent.setDeviceId(device.deviceId)
            val intent = Intent(requireContext(), com.example.defenseapplication.liveVideo.LiveVideoActivity::class.java)
            intent.putExtra("device_name", device.name)
            startActivity(intent)
        } else {
            showDefenseDialog(
                config = DefenseDialogs.deviceOfflineConfig(requireContext())
            )
        }
    }

    private fun dpToPx(dp: Int): Int {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            dp.toFloat(),
            resources.displayMetrics
        ).toInt()
    }

    private class GridHorizontalSpaceItemDecoration(
        private val horizontalSpace: Int
    ) : RecyclerView.ItemDecoration() {
        override fun getItemOffsets(
            outRect: Rect,
            view: View,
            parent: RecyclerView,
            state: RecyclerView.State
        ) {
            val position = parent.getChildAdapterPosition(view)
            if (position == RecyclerView.NO_POSITION) return

            if (position % 2 == 0) {
                outRect.right = horizontalSpace / 2
            } else {
                outRect.left = horizontalSpace / 2
            }
        }
    }

    private fun setGradientBackground(
        view: View,
        startColor: Int,
        endColor: Int,
        orientation: GradientDrawable.Orientation = GradientDrawable.Orientation.TL_BR
    ) {
        val gradientDrawable = GradientDrawable(orientation, intArrayOf(startColor, endColor))
        gradientDrawable.gradientType = GradientDrawable.LINEAR_GRADIENT
        view.background = gradientDrawable
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding.rvFamilyList.adapter = null
        binding.rvDeviceList.adapter = null
        MessageStatusManager.removeListener(unreadCountChangeListener)
        FamilySwitchEvent.removeListener(familySwitchListener)
        DeviceUpdateEvent.removeListener(deviceUpdateListener)
        _binding = null // 避免内存泄漏
    }
}