package com.google.chip.chiptool.clusterclient

import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipClusterException
import chip.devicecontroller.ChipClusters
import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.ICDClientInfo
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.databinding.AddressUpdateFragmentBinding
import com.google.chip.chiptool.util.DeviceIdUtil
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

/** Fragment for updating the address of a device given its fabric and node ID. */
class AddressUpdateFragment : ICDCheckInCallback, Fragment() {
  private val deviceController: ChipDeviceController
    get() = ChipClient.getDeviceController(requireContext())

  val deviceId: Long
    get() = binding.deviceIdEd.text.toString().toULong(16).toLong()

  var endpointId: Int
    get() = binding.epIdEd.text.toString().toInt()
    set(value) {
      binding.epIdEd.setText(value.toString())
    }

  private var _binding: AddressUpdateFragmentBinding? = null
  private val binding
    get() = _binding!!

  private lateinit var scope: CoroutineScope

  private var icdDeviceId: Long = 0L
  private var icdTotalRemainStayActiveTimeMs = 0L
  private var icdDeviceRemainStayActiveTimeMs = 0L
  private var isSendingStayActiveCommand = false
  private val icdRequestActiveDurationMs: Long
    get() = binding.icdActiveDurationEd.text.toString().toLong() * 1000

  private val handler = Handler(Looper.getMainLooper())

  private var externalICDCheckInMessageCallback: ICDCheckInMessageCallback? = null

  override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
  ): View {
    _binding = AddressUpdateFragmentBinding.inflate(inflater, container, false)
    scope = viewLifecycleOwner.lifecycleScope
    return binding.root
  }

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

    ChipClient.setICDCheckInCallback(this)

    val compressedFabricId = deviceController.compressedFabricId
    binding.fabricIdEd.setText(compressedFabricId.toULong().toString(16).padStart(16, '0'))
    binding.deviceIdEd.setText(DeviceIdUtil.getLastDeviceId(requireContext()).toString(16))
    binding.epIdEd.setText(endpointId.toString())
    binding.icdActiveDurationEd.setText((ICD_STAY_ACTIVE_DURATION / 1000).toString())

    binding.icdInteractionSwitch.setOnClickListener {
      val isChecked = binding.icdInteractionSwitch.isChecked
      if (updateUIForICDInteractionSwitch(isChecked)) {
        icdInteractionSwitchClick(isChecked)
      }
    }

    updateDeviceIdSpinner()
  }

  fun updateDeviceIdSpinner() {
    val deviceIdList = DeviceIdUtil.getCommissionedNodeId(requireContext())
    binding.deviceIdSpinner.adapter =
      ArrayAdapter(requireContext(), android.R.layout.simple_spinner_dropdown_item, deviceIdList)
    binding.deviceIdSpinner.onItemSelectedListener =
      object : AdapterView.OnItemSelectedListener {
        override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
          binding.deviceIdEd.setText(deviceIdList[position].toULong(16).toString())
        }

        override fun onNothingSelected(parent: AdapterView<*>?) {
          Log.d(TAG, "onNothingSelected")
        }
      }
  }

  private fun icdInteractionSwitchClick(isEnabled: Boolean) {
    if (isEnabled) {
      icdDeviceId = deviceId
    } else {
      icdDeviceId = 0
      if (icdDeviceRemainStayActiveTimeMs != 0L || icdTotalRemainStayActiveTimeMs != 0L) {
        scope.launch {
          icdDeviceRemainStayActiveTimeMs = sendStayActive(0L)
          icdTotalRemainStayActiveTimeMs = icdDeviceRemainStayActiveTimeMs
        }
      }
    }
  }

  private suspend fun sendStayActive(duration: Long): Long {
    isSendingStayActiveCommand = true
    val devicePtr =
      try {
        ChipClient.getConnectedDevicePointer(requireContext(), deviceId)
      } catch (e: IllegalStateException) {
        Log.d(TAG, "getConnectedDevicePointer exception", e)
        showToastMessage("Get DevicePointer fail!")
        throw e
      }

    val cluster = ChipClusters.IcdManagementCluster(devicePtr, 0)
    val retDuration = suspendCoroutine { cont ->
      cluster.stayActiveRequest(
        object : ChipClusters.IcdManagementCluster.StayActiveResponseCallback {
          override fun onError(error: Exception) {
            Log.d(TAG, "onError", error)
            cont.resume(0L)
          }

          override fun onSuccess(promisedActiveDuration: Long) {
            cont.resume(promisedActiveDuration)
          }
        },
        duration
      )
    }
    isSendingStayActiveCommand = false
    return retDuration
  }

  private fun updateUIForICDInteractionSwitch(isEnabled: Boolean): Boolean {
    val isICD = isICDDevice()
    if (isEnabled && !isICD) {
      binding.icdInteractionSwitch.isChecked = false
      return false
    }

    return true
  }

  override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
  }

  suspend fun getDevicePointer(context: Context): Long {
    return if (isGroupId()) {
      deviceController.getGroupDevicePointer(getGroupId().toInt())
    } else {
      ChipClient.getConnectedDevicePointer(context, getNodeId().toLong())
    }
  }

  private fun showToastMessage(msg: String) {
    requireActivity().runOnUiThread {
      Toast.makeText(requireActivity(), msg, Toast.LENGTH_SHORT).show()
    }
  }

  fun isGroupId(): Boolean {
    return isGroupNodeId(getNodeId())
  }

  fun getGroupId(): UInt {
    return getGroupIdFromNodeId(getNodeId())
  }

  fun getNodeId(): ULong {
    return binding.deviceIdEd.text.toString().toULong(16)
  }

  fun isICDDevice(): Boolean {
    return deviceController.icdClientInfo.firstOrNull { info -> info.peerNodeId == deviceId } !=
      null
  }

  override fun notifyCheckInMessage(info: ICDClientInfo) {
    externalICDCheckInMessageCallback?.notifyCheckInMessage()
    if (info.peerNodeId != icdDeviceId) {
      return
    }

    scope.launch {
      try {
        icdDeviceRemainStayActiveTimeMs = sendStayActive(icdRequestActiveDurationMs)
        icdTotalRemainStayActiveTimeMs = icdRequestActiveDurationMs
        turnOnActiveMode()
      } catch (e: IllegalStateException) {
        Log.d(TAG, "IlligalStateException", e)
      } catch (e: ChipClusterException) {
        Log.d(TAG, "ChipClusterException", e)
      }
    }
  }

  fun setNotifyCheckInMessageCallback(callback: ICDCheckInMessageCallback?) {
    externalICDCheckInMessageCallback = callback
  }

  interface ICDCheckInMessageCallback {
    fun notifyCheckInMessage()
  }

  private fun turnOnActiveMode() {
    requireActivity().runOnUiThread {
      binding.icdProgressBar.max = (icdTotalRemainStayActiveTimeMs / 1000).toInt()
      binding.icdProgressBar.progress = (icdTotalRemainStayActiveTimeMs / 1000).toInt()
    }

    val runnable =
      object : Runnable {
        override fun run() {
          if (icdTotalRemainStayActiveTimeMs >= ICD_PROGRESS_STEP) {
            icdDeviceRemainStayActiveTimeMs -= ICD_PROGRESS_STEP
            icdTotalRemainStayActiveTimeMs -= ICD_PROGRESS_STEP
            handler.postDelayed(this, ICD_PROGRESS_STEP)
            requireActivity().runOnUiThread {
              binding.icdProgressBar.progress = (icdTotalRemainStayActiveTimeMs / 1000).toInt()
            }

            if (
              !isSendingStayActiveCommand &&
                (ICD_RESEND_STAY_ACTIVE_TIME > icdDeviceRemainStayActiveTimeMs) &&
                (ICD_RESEND_STAY_ACTIVE_TIME < icdTotalRemainStayActiveTimeMs)
            )
              scope.launch {
                icdDeviceRemainStayActiveTimeMs = sendStayActive(icdTotalRemainStayActiveTimeMs)
              }
          } else {
            requireActivity().runOnUiThread { binding.icdProgressBar.progress = 0 }
          }
        }
      }
    handler.post(runnable)
  }

  companion object {
    private const val TAG = "AddressUpdateFragment"
    // Refer from NodeId.h (src/lib/core/NodeId.h)
    private const val MIN_GROUP_NODE_ID = 0xFFFF_FFFF_FFFF_0000UL
    private const val MASK_GROUP_ID = 0x0000_0000_0000_FFFFUL

    private const val ICD_STAY_ACTIVE_DURATION = 30000L // 30 secs.
    private const val ICD_PROGRESS_STEP = 1000L // 1 sec.
    private const val ICD_RESEND_STAY_ACTIVE_TIME = 2000L // 2 secs.

    fun isGroupNodeId(nodeId: ULong): Boolean {
      return nodeId >= MIN_GROUP_NODE_ID
    }

    fun getNodeIdFromGroupId(groupId: UInt): ULong {
      return groupId.toULong() or MIN_GROUP_NODE_ID
    }

    fun getGroupIdFromNodeId(nodeId: ULong): UInt {
      return (nodeId and MASK_GROUP_ID).toUInt()
    }
  }
}

interface ICDCheckInCallback {
  fun notifyCheckInMessage(info: ICDClientInfo)
}
