package com.google.chip.chiptool.clusterclient

import android.app.AlertDialog
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.EditText
import android.widget.Spinner
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.ChipIdLookup
import chip.devicecontroller.InvokeCallback
import chip.devicecontroller.ReportCallback
import chip.devicecontroller.ResubscriptionAttemptCallback
import chip.devicecontroller.SubscriptionEstablishedCallback
import chip.devicecontroller.WriteAttributesCallback
import chip.devicecontroller.model.AttributeWriteRequest
import chip.devicecontroller.model.ChipAttributePath
import chip.devicecontroller.model.ChipEventPath
import chip.devicecontroller.model.ChipPathId
import chip.devicecontroller.model.InvokeElement
import chip.devicecontroller.model.NodeState
import chip.tlv.AnonymousTag
import chip.tlv.ContextSpecificTag
import chip.tlv.TlvReader
import chip.tlv.TlvWriter
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.R
import com.google.chip.chiptool.databinding.WildcardFragmentBinding
import com.google.protobuf.ByteString
import java.lang.StringBuilder
import java.util.Optional
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

class WildcardFragment : Fragment() {
  private var _binding: WildcardFragmentBinding? = null
  private val binding get() = _binding!!

  private val deviceController: ChipDeviceController
    get() = ChipClient.getDeviceController(requireContext())

  private lateinit var scope: CoroutineScope

  private lateinit var addressUpdateFragment: AddressUpdateFragment

  private val attributePath = ArrayList<ChipAttributePath>()
  private val eventPath = ArrayList<ChipEventPath>()
  private val subscribeIdList = ArrayList<ULong>()

  private val reportCallback = object : ReportCallback {
    override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, ex: Exception) {
      if (attributePath != null)
      {
        Log.e(TAG, "Report error for $attributePath: $ex")
      }
      if (eventPath != null)
      {
        Log.e(TAG, "Report error for $eventPath: $ex")
      }
    }

    override fun onReport(nodeState: NodeState) {
      Log.i(TAG, "Received wildcard report")

      val debugString = nodeStateToDebugString(nodeState)
      Log.i(TAG, debugString)
      requireActivity().runOnUiThread { binding.outputTv.text = debugString }
    }

    override fun onDone() {
      Log.i(TAG, "wildcard report Done")
    }
  }

  private val writeAttributeCallback = object : WriteAttributesCallback {
    override fun onError(attributePath: ChipAttributePath?, ex: Exception?) {
      Log.e(TAG, "Report error for $attributePath: $ex")
    }

    override fun onResponse(attributePath: ChipAttributePath?) {
      val text = "$attributePath : Write Success"
      requireActivity().runOnUiThread { binding.outputTv.text = text }
    }

    override fun onDone() {
      Log.i(TAG, "write attribute Done")
    }
  }

  private val invokeCallback = object : InvokeCallback {
    override fun onError(e: java.lang.Exception?) {
      Log.e(TAG, "Report error", e)
    }

    override fun onResponse(invokeElement: InvokeElement?, successCode: Long) {
      val text = "Invoke Response : $invokeElement, $successCode"
      requireActivity().runOnUiThread { binding.outputTv.text = text }
    }

  }

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

    binding.selectTypeRadioGroup.setOnCheckedChangeListener { _, i ->
      val readBtnOn = (i == R.id.readRadioBtn)
      val subscribeBtnOn = (i == R.id.subscribeRadioBtn)
      val writeBtnOn = (i == R.id.writeRadioBtn)
      val invokeBtnOn = (i == R.id.invokeRadioBtn)

      binding.addLayout.visibility = getVisibility(readBtnOn || subscribeBtnOn)
      binding.attributeIdLabel.visibility = getVisibility(readBtnOn || subscribeBtnOn || writeBtnOn)
      binding.attributeIdEd.visibility = getVisibility(readBtnOn || subscribeBtnOn || writeBtnOn)
      binding.eventIdLabel.visibility = getVisibility(readBtnOn || subscribeBtnOn)
      binding.eventIdEd.visibility = getVisibility(readBtnOn || subscribeBtnOn)
      binding.commandIdLabel.visibility = getVisibility(invokeBtnOn)
      binding.commandIdEd.visibility = getVisibility(invokeBtnOn)
      binding.isUrgentLabel.visibility = getVisibility(subscribeBtnOn)
      binding.isUrgentSp.visibility = getVisibility(subscribeBtnOn)
      binding.shutdownSubscriptionBtn.visibility = getVisibility(subscribeBtnOn)
    }

    binding.sendBtn.setOnClickListener {
      if (binding.readRadioBtn.isChecked) {
        showReadDialog()
      } else if (binding.subscribeRadioBtn.isChecked) {
        showSubscribeDialog()
      } else if (binding.writeRadioBtn.isChecked) {
        showWriteDialog()
      } else if (binding.invokeRadioBtn.isChecked) {
        showInvokeDialog()
      }
    }

    binding.shutdownSubscriptionBtn.setOnClickListener { showShutdownSubscriptionDialog() }

    binding.addAttributeBtn.setOnClickListener { addPathList(ATTRIBUTE) }
    binding.addEventBtn.setOnClickListener { addPathList(EVENT) }
    binding.resetBtn.setOnClickListener { resetPath() }

    addressUpdateFragment =
      childFragmentManager.findFragmentById(R.id.addressUpdateFragment) as AddressUpdateFragment

    return binding.root
  }

  private fun getVisibility(isShowing: Boolean) : Int {
    return if (isShowing) { View.VISIBLE } else { View.GONE }
  }

  private fun addPathList(type: Int) {
    val endpointId = getChipPathIdForText(binding.endpointIdEd.text.toString())
    val clusterId = getChipPathIdForText(binding.clusterIdEd.text.toString())
    val attributeId = getChipPathIdForText(binding.attributeIdEd.text.toString())
    val eventId = getChipPathIdForText(binding.eventIdEd.text.toString())
    // Only Subscribe used
    val isUrgent = (binding.subscribeRadioBtn.isChecked) && (binding.isUrgentSp.selectedItem.toString().toBoolean())

    if (type == ATTRIBUTE) {
      attributePath.add(ChipAttributePath.newInstance(endpointId, clusterId, attributeId))
    } else if (type == EVENT) {
      eventPath.add(ChipEventPath.newInstance(endpointId, clusterId, eventId, isUrgent))
    }
    updateAddListView()
  }

  private fun resetPath() {
    attributePath.clear()
    eventPath.clear()
    updateAddListView()
  }

  private fun updateAddListView() {
    val builder = StringBuilder()
    for (attribute in attributePath) {
      builder.append("attribute($attribute)\n")
    }
    for (event in eventPath) {
      builder.append("event($event)\n")
    }
    binding.sendListView.text = builder.toString()
  }

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

  private fun nodeStateToDebugString(nodeState: NodeState): String {
    val stringBuilder = StringBuilder()
    nodeState.endpointStates.forEach { (endpointId, endpointState) ->
      stringBuilder.append("Endpoint $endpointId: {\n")
      endpointState.clusterStates.forEach { (clusterId, clusterState) ->
        stringBuilder.append("\t${ChipIdLookup.clusterIdToName(clusterId)}Cluster: {\n")
        clusterState.attributeStates.forEach { (attributeId, attributeState) ->
          val attributeName = ChipIdLookup.attributeIdToName(clusterId, attributeId)
          stringBuilder.append("\t\t$attributeName: ${attributeState.value}\n")
        }
        clusterState.eventStates.forEach { (eventId, events) ->
          for (event in events)
          {
            stringBuilder.append("\t\teventNumber: ${event.eventNumber}\n")
            stringBuilder.append("\t\tpriorityLevel: ${event.priorityLevel}\n")
            stringBuilder.append("\t\tsystemTimeStamp: ${event.systemTimeStamp}\n")

            val eventName = ChipIdLookup.eventIdToName(clusterId, eventId)
            stringBuilder.append("\t\t$eventName: ${event.value}\n")
          }
        }
        stringBuilder.append("\t}\n")
      }
      stringBuilder.append("}\n")
    }
    return stringBuilder.toString()
  }

  private suspend fun subscribe(minInterval: Int, maxInterval: Int, keepSubscriptions: Boolean, isFabricFiltered: Boolean, eventMin: Long?) {
    val subscriptionEstablishedCallback =
      SubscriptionEstablishedCallback {
        subscriptionId ->
        Log.i(TAG, "Subscription to device established : ${subscriptionId.toULong()}")
        subscribeIdList.add(subscriptionId.toULong())
        requireActivity().runOnUiThread {
          Toast.makeText(requireActivity(), "${getString(R.string.wildcard_subscribe_established_toast_message)} : $subscriptionId", Toast.LENGTH_SHORT).show()
        }
      }

    val resubscriptionAttemptCallback =
      ResubscriptionAttemptCallback { terminationCause, nextResubscribeIntervalMsec
                                     -> Log.i(TAG, "ResubscriptionAttempt terminationCause:$terminationCause, nextResubscribeIntervalMsec:$nextResubscribeIntervalMsec") }

    deviceController.subscribeToPath(subscriptionEstablishedCallback,
            resubscriptionAttemptCallback,
            reportCallback,
            ChipClient.getConnectedDevicePointer(requireContext(),
                    addressUpdateFragment.deviceId),
            attributePath.ifEmpty { null },
            eventPath.ifEmpty { null },
            minInterval,
            maxInterval,
            keepSubscriptions,
            isFabricFiltered,
            /* imTimeoutMs= */ 0,
            eventMin)
  }

  private suspend fun read(isFabricFiltered: Boolean, eventMin: Long?) {
    deviceController.readPath(reportCallback,
            ChipClient.getConnectedDevicePointer(requireContext(),
                    addressUpdateFragment.deviceId),
            attributePath.ifEmpty { null },
            eventPath.ifEmpty { null },
            isFabricFiltered,
            /* imTimeoutMs= */ 0,
            eventMin)
  }

  private suspend fun write(writeValueType: String, writeValue: String, dataVersion: Int?, timedRequestTimeoutMs: Int, imTimeoutMs: Int) {
    val endpointId = getChipPathIdForText(binding.endpointIdEd.text.toString())
    val clusterId = getChipPathIdForText(binding.clusterIdEd.text.toString())
    val attributeId = getChipPathIdForText(binding.attributeIdEd.text.toString())
    val tlvWriter = TlvWriter()
    val values = writeValue.split(",")

    if (values.size > 1) tlvWriter.startArray(AnonymousTag)
    for (value in values) {
      try {
        TLV_MAP[writeValueType]?.generate(tlvWriter, value.trim())
      } catch (ex: Exception) {
        Log.e(TAG, "Invalid Data Type", ex)
        return
      }
    }
    if (values.size > 1) tlvWriter.endArray()

    val version = if (dataVersion == null) { Optional.empty() } else { Optional.of(dataVersion) }

    val writeRequest = AttributeWriteRequest.newInstance(endpointId, clusterId, attributeId, tlvWriter.getEncoded(), version)
    deviceController.write(writeAttributeCallback,
                      ChipClient.getConnectedDevicePointer(requireContext(),
                      addressUpdateFragment.deviceId),
                      listOf(writeRequest),
                      timedRequestTimeoutMs,
                      imTimeoutMs)
  }

  private suspend fun invoke(invokeField: String, timedRequestTimeoutMs: Int, imTimeoutMs: Int) {
    val endpointId = getChipPathIdForText(binding.endpointIdEd.text.toString())
    val clusterId = getChipPathIdForText(binding.clusterIdEd.text.toString())
    val commandId = getChipPathIdForText(binding.commandIdEd.text.toString())

    val tlvWriter = TlvWriter()
    val fields = if (invokeField.isEmpty()) { listOf() } else { invokeField.split(",") }
    var count = 0
    tlvWriter.startStructure(AnonymousTag)
    for (field in fields) {
      try {
        val type = field.split(":")[0]
        val value = field.split(":")[1]

        Log.d(TAG, "value : $type - $value")
        TLV_MAP[type]?.generate(tlvWriter, value.trim(), ContextSpecificTag(count++))
      } catch (ex: Exception) {
        Log.e(TAG, "Invalid value", ex)
        return
      }
    }
    tlvWriter.endStructure()
    val invokeElement = InvokeElement.newInstance(endpointId, clusterId, commandId, tlvWriter.getEncoded(), null)
    deviceController.invoke(invokeCallback,
            ChipClient.getConnectedDevicePointer(requireContext(),
                    addressUpdateFragment.deviceId),
            invokeElement,
            timedRequestTimeoutMs,
            imTimeoutMs)
  }

  private fun showReadDialog() {
    if (attributePath.isEmpty() && eventPath.isEmpty()) {
      requireActivity().runOnUiThread {
        Toast.makeText(requireActivity(), R.string.wildcard_empty_error_toast_message, Toast.LENGTH_SHORT).show()
      }
      return
    }
    val dialogView = requireActivity().layoutInflater.inflate(R.layout.read_dialog, null)
    val eventMinEd = dialogView.findViewById<EditText>(R.id.eventMinEd)
    eventMinEd.visibility = if (eventPath.isNotEmpty()) { View.VISIBLE } else { View.GONE }
    val dialog = AlertDialog.Builder(requireContext()).apply {
      setView(dialogView)
    }.create()

    val isFabricFilteredEd = dialogView.findViewById<Spinner>(R.id.isFabricFilteredSp)
    dialogView.findViewById<Button>(R.id.readBtn).setOnClickListener {
      scope.launch {
        var eventMin : Long? = null
        if (eventPath.isNotEmpty() && eventMinEd.text.isNotBlank()) {
          eventMin = eventMinEd.text.toString().toULong().toLong()
        }
        read(isFabricFilteredEd.selectedItem.toString().toBoolean(), eventMin)
        requireActivity().runOnUiThread { dialog.dismiss() }
      }
    }
    dialog.show()
  }

  private fun showWriteDialog() {
    binding.outputTv.text = ""
    val dialogView = requireActivity().layoutInflater.inflate(R.layout.write_dialog, null)
    val writeValueTypeSp = dialogView.findViewById<Spinner>(R.id.writeValueTypeSp)
    val spinnerAdapter = ArrayAdapter(requireActivity(), android.R.layout.simple_spinner_dropdown_item, TLV_MAP.keys.toList())
    writeValueTypeSp.adapter = spinnerAdapter
    val dialog = AlertDialog.Builder(requireContext()).apply {
      setView(dialogView)
    }.create()

    dialogView.findViewById<Button>(R.id.writeBtn).setOnClickListener {
      val writeValue = dialogView.findViewById<EditText>(R.id.writeValueEd).text.toString()
      val dataVersion = dialogView.findViewById<EditText>(R.id.dataVersionEd).text.toString()
      val timedRequestTimeoutMs = dialogView.findViewById<EditText>(R.id.timedRequestTimeoutEd).text.toString()
      val imTimeout = dialogView.findViewById<EditText>(R.id.imTimeoutEd).text.toString()
      scope.launch {
        write(  writeValueTypeSp.selectedItem.toString(),
                writeValue,
                if (dataVersion.isEmpty()) { null } else { dataVersion.toInt() },
                if (timedRequestTimeoutMs.isEmpty()) { 0 } else { timedRequestTimeoutMs.toInt() },
                if (imTimeout.isEmpty()) { 0 } else { imTimeout.toInt() } )
        requireActivity().runOnUiThread { dialog.dismiss() }
      }
    }
    dialog.show()
  }

  private fun showSubscribeDialog() {
    if (attributePath.isEmpty() && eventPath.isEmpty()) {
      requireActivity().runOnUiThread {
        Toast.makeText(requireActivity(), R.string.wildcard_empty_error_toast_message, Toast.LENGTH_SHORT).show()
      }
      return
    }
    val dialogView = requireActivity().layoutInflater.inflate(R.layout.subscribe_dialog, null)
    val eventMinEd = dialogView.findViewById<EditText>(R.id.eventMinEd)
    eventMinEd.visibility = if (eventPath.isNotEmpty()) { View.VISIBLE } else { View.GONE }
    val dialog = AlertDialog.Builder(requireContext()).apply {
      setView(dialogView)
    }.create()

    val minIntervalEd = dialogView.findViewById<EditText>(R.id.minIntervalEd)
    val maxIntervalEd = dialogView.findViewById<EditText>(R.id.maxIntervalEd)
    val keepSubscriptionsSp = dialogView.findViewById<Spinner>(R.id.keepSubscriptionsSp)
    val isFabricFilteredSp = dialogView.findViewById<Spinner>(R.id.isFabricFilteredSp)
    dialogView.findViewById<Button>(R.id.subscribeBtn).setOnClickListener {
      scope.launch {
        if(minIntervalEd.text.isNotBlank() && maxIntervalEd.text.isNotBlank()) {
          var eventMin : Long? = null
          if (eventPath.isNotEmpty() && eventMinEd.text.isNotBlank()) {
            eventMin = eventMinEd.text.toString().toULong().toLong()
          }
          subscribe(
            minIntervalEd.text.toString().toInt(),
            maxIntervalEd.text.toString().toInt(),
            keepSubscriptionsSp.selectedItem.toString().toBoolean(),
            isFabricFilteredSp.selectedItem.toString().toBoolean(),
            eventMin,
          )
        } else {
          Log.e(TAG, "minInterval or maxInterval is empty!" )
        }
        requireActivity().runOnUiThread { dialog.dismiss() }
      }
    }
    dialog.show()
  }

  private fun showInvokeDialog() {
    binding.outputTv.text = ""
    val dialogView = requireActivity().layoutInflater.inflate(R.layout.invoke_dialog, null)
    val invokeValueEd = dialogView.findViewById<EditText>(R.id.invokeValueEd)
    val dialog = AlertDialog.Builder(requireContext()).apply {
      setView(dialogView)
    }.create()

    dialogView.findViewById<Button>(R.id.invokeBtn).setOnClickListener {
      val invokeValue = invokeValueEd.text.toString()
      val timedRequestTimeoutMs = dialogView.findViewById<EditText>(R.id.timedRequestTimeoutEd).text.toString()
      val imTimeout = dialogView.findViewById<EditText>(R.id.imTimeoutEd).text.toString()
      scope.launch {
        invoke(invokeValue,
                if (timedRequestTimeoutMs.isEmpty()) { 0 } else { timedRequestTimeoutMs.toInt() },
                if (imTimeout.isEmpty()) { 0 } else { imTimeout.toInt() } )
        requireActivity().runOnUiThread { dialog.dismiss() }
      }
    }
    dialog.show()
  }

  private suspend fun readCurrentFabricIndex() : UInt {
    val context = requireContext()
    val endpointId = 0
    val clusterId = 62L // OperationalCredentials
    val attributeId = 5L // CurrentFabricIndex
    val deviceId = addressUpdateFragment.deviceId
    val devicePointer = ChipClient.getConnectedDevicePointer(context, deviceId)
    return suspendCoroutine { cont ->
      deviceController.readAttributePath(object : ReportCallback {
        override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, e: java.lang.Exception) {
          cont.resume(0u)
        }

        override fun onReport(nodeState: NodeState?) {
          val state = nodeState?.getEndpointState(endpointId.toInt())?.
                                  getClusterState(clusterId)?.
                                  getAttributeState(attributeId)
          if (state == null) {
            cont.resume(0u)
            return
          }
          val ret = TlvReader(state.tlv).getUInt(AnonymousTag)
          cont.resume(ret)
        }
      }, devicePointer,
         listOf(ChipAttributePath.newInstance(endpointId, clusterId, attributeId)),
         0 /* imTimeoutMs */
      )
    }
  }

  private fun shutdownSubscription(fabricIndex: UInt, subscribeId: ULong? = null) {
    val deviceId = addressUpdateFragment.deviceId
    if (subscribeId != null) {
      deviceController.shutdownSubscriptions(fabricIndex.toInt(), deviceId, subscribeId.toLong())
      subscribeIdList.remove(subscribeId)
    } else {
      deviceController.shutdownSubscriptions(fabricIndex.toInt(), deviceId)
    }
  }

  private fun showShutdownSubscriptionDialog() {
    val dialogView = requireActivity().layoutInflater.inflate(R.layout.shutdown_subscribe_dialog, null)
    val subscriptionIdSp = dialogView.findViewById<Spinner>(R.id.subscribeIdSp)
    val fabricIndexTv = dialogView.findViewById<TextView>(R.id.fabricIndexValue)
    val shutdownBtn = dialogView.findViewById<Button>(R.id.shutdownBtn)
    val shutdownAllBtn = dialogView.findViewById<Button>(R.id.shutdownAllBtn)
    val spinnerAdapter = ArrayAdapter(requireActivity(), android.R.layout.simple_spinner_dropdown_item, subscribeIdList)
    subscriptionIdSp.adapter = spinnerAdapter
    val dialog = AlertDialog.Builder(requireContext()).apply {
      setView(dialogView)
    }.create()

    shutdownBtn.setOnClickListener {
      val fabricIndex = fabricIndexTv.text.toString().toUInt()
      val subscribeId = subscriptionIdSp.selectedItem.toString().toULong()
      scope.launch {
        shutdownSubscription(fabricIndex, subscribeId)
        requireActivity().runOnUiThread { dialog.dismiss() }
      }
    }

    shutdownAllBtn.setOnClickListener {
      scope.launch {
        val fabricIndex = fabricIndexTv.text.toString().toUInt()
        shutdownSubscription(fabricIndex)
        requireActivity().runOnUiThread { dialog.dismiss() }
      }
    }
    dialog.show()

    scope.launch {
      val fabricIndex = readCurrentFabricIndex()
      requireActivity().runOnUiThread {
        fabricIndexTv.text = fabricIndex.toString()
        shutdownBtn.isEnabled = true
        shutdownAllBtn.isEnabled = true
      }
    }
  }

  private fun getChipPathIdForText(text: String): ChipPathId {
    return if (text.isEmpty()) ChipPathId.forWildcard() else ChipPathId.forId(text.toLong())
  }

  interface TlvWriterInterface {
    fun generate(writer : TlvWriter, value: String, tag: chip.tlv.Tag = AnonymousTag)
  }

  companion object {
    private const val TAG = "WildcardFragment"
    private const val ATTRIBUTE = 1
    private const val EVENT = 2
    fun newInstance(): WildcardFragment = WildcardFragment()

    private val TLV_MAP = mapOf(
            "UnsignedInt" to object:TlvWriterInterface {
              override fun generate(writer : TlvWriter, value: String, tag: chip.tlv.Tag) {
                writer.put(tag, value.toULong())
              }
            },
            "Int" to object:TlvWriterInterface {
              override fun generate(writer : TlvWriter, value: String, tag: chip.tlv.Tag) {
                writer.put(tag, value.toLong())
              }
            },
            "Boolean" to object:TlvWriterInterface {
              override fun generate(writer : TlvWriter, value: String, tag: chip.tlv.Tag) {
                writer.put(tag, value.toBoolean())
              }
            },
            "Float" to object:TlvWriterInterface {
              override fun generate(writer : TlvWriter, value: String, tag: chip.tlv.Tag) {
                writer.put(tag, value.toFloat())
              }
            },
            "Double" to object:TlvWriterInterface {
              override fun generate(writer : TlvWriter, value: String, tag: chip.tlv.Tag) {
                writer.put(tag, value.toDouble())
              }
            },
            "String" to object:TlvWriterInterface {
              override fun generate(writer : TlvWriter, value: String, tag: chip.tlv.Tag) {
                writer.put(tag, value)
              }
            },
            "ByteArray(Hex)" to object:TlvWriterInterface {
              override fun generate(writer : TlvWriter, value: String, tag: chip.tlv.Tag) {
                writer.put(tag, value.chunked(2).map { it.toInt(16) and 0xFF }.map { it.toByte() }.toByteArray())
              }
            },
    )
  }
}
