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.Button
import android.widget.EditText
import android.widget.SeekBar
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.InvokeCallback
import chip.devicecontroller.ReportCallback
import chip.devicecontroller.ResubscriptionAttemptCallback
import chip.devicecontroller.SubscriptionEstablishedCallback
import chip.devicecontroller.model.ChipAttributePath
import chip.devicecontroller.model.ChipEventPath
import chip.devicecontroller.model.InvokeElement
import chip.devicecontroller.model.NodeState
import chip.tlv.TlvWriter
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.GenericChipDeviceListener
import com.google.chip.chiptool.R
import com.google.chip.chiptool.databinding.OnOffClientFragmentBinding
import com.google.chip.chiptool.util.TlvParseUtil
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

import chip.devicecontroller.ClusterIDMapping.*
import chip.tlv.AnonymousTag
import chip.tlv.ContextSpecificTag

class OnOffClientFragment : Fragment() {
  private val deviceController: ChipDeviceController
    get() = ChipClient.getDeviceController(requireContext())

  private lateinit var scope: CoroutineScope

  private lateinit var addressUpdateFragment: AddressUpdateFragment

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

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

    deviceController.setCompletionListener(ChipControllerCallback())

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

    binding.onBtn.setOnClickListener { scope.launch { sendOnOffClusterCommand(OnOff.Command.On) } }
    binding.offBtn.setOnClickListener { scope.launch { sendOnOffClusterCommand(OnOff.Command.Off) } }
    binding.toggleBtn.setOnClickListener { scope.launch { sendOnOffClusterCommand(OnOff.Command.Toggle) } }
    binding.readBtn.setOnClickListener { scope.launch { sendReadOnOffClick() } }
    binding.showSubscribeDialogBtn.setOnClickListener { showSubscribeDialog() }

    binding.levelBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
      override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) {

      }

      override fun onStartTrackingTouch(seekBar: SeekBar?) {
      }

      override fun onStopTrackingTouch(seekBar: SeekBar?) {
        Toast.makeText(
          requireContext(),
          "Level is: " + binding.levelBar.progress,
          Toast.LENGTH_SHORT
        ).show()
        scope.launch { sendLevelCommandClick() }
      }
    })

    return binding.root
  }

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

  private suspend fun sendReadOnOffClick() {
    val endpointId = addressUpdateFragment.endpointId
    val clusterId = OnOff.ID
    val attributeId = OnOff.Attribute.OnOff.id

    val attributePath = ChipAttributePath.newInstance(endpointId.toLong(), clusterId, attributeId)

    ChipClient.getDeviceController(requireContext()).readPath(object: ReportCallback {
      override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, ex: java.lang.Exception) {
        Log.e(TAG, "Error reading onOff attribute", ex)
      }

      override fun onReport(nodeState: NodeState?) {
        val value = nodeState?.getEndpointState(endpointId)?.getClusterState(clusterId)?.getAttributeState(attributeId)?.value ?: "null"
        Log.v(TAG, "On/Off attribute value: $value")
        showMessage("On/Off attribute value: $value")
      }

    }, getConnectedDevicePointer(), listOf(attributePath), null, false, 0 /* imTimeoutMs */)
  }

  private fun showSubscribeDialog() {
    val dialogView = requireActivity().layoutInflater.inflate(R.layout.subscribe_dialog, null)
    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)
    dialogView.findViewById<Button>(R.id.subscribeBtn).setOnClickListener {
      scope.launch {
        sendSubscribeOnOffClick(
          minIntervalEd.text.toString().toInt(),
          maxIntervalEd.text.toString().toInt()
        )
        requireActivity().runOnUiThread {
          dialog.dismiss()
        }
      }
    }
    dialog.show()
  }
  private suspend fun sendSubscribeOnOffClick(minInterval: Int, maxInterval: Int) {
    val endpointId = addressUpdateFragment.endpointId
    val clusterId = OnOff.ID
    val attributeId = OnOff.Attribute.OnOff.id

    val attributePath = ChipAttributePath.newInstance(endpointId.toLong(), clusterId, attributeId)

    val subscriptionEstablishedCallback =
            SubscriptionEstablishedCallback {
              subscriptionId ->
              Log.i(TAG, "Subscription to device established : ${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,
            object: ReportCallback {
              override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, ex: Exception) {
                Log.e(TAG, "Error configuring on/off attribute", ex)
              }

              override fun onReport(nodeState: NodeState?) {
                val tlv = nodeState?.getEndpointState(endpointId)?.getClusterState(clusterId)?.getAttributeState(attributeId)?.tlv ?: return
                // TODO : Need to be implement poj-to-tlv
                val value = TlvParseUtil.decodeBoolean(tlv)
                val formatter = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
                val time = formatter.format(Calendar.getInstance(Locale.getDefault()).time)
                val message = "Subscribed on/off value at $time: ${if (value) "ON" else "OFF"}"

                Log.v(TAG, message)
                showReportMessage(message)
              }
            },
            getConnectedDevicePointer(),
            listOf(attributePath),
            null,
            minInterval,
            maxInterval,
            false,
            false,
            /* imTimeoutMs= */ 0)
  }

  inner class ChipControllerCallback : GenericChipDeviceListener() {
    override fun onConnectDeviceComplete() {}

    override fun onCommissioningComplete(nodeId: Long, errorCode: Int) {
      Log.d(TAG, "onCommissioningComplete for nodeId $nodeId: $errorCode")
      showMessage("Address update complete for nodeId $nodeId with code $errorCode")
    }

    override fun onNotifyChipConnectionClosed() {
      Log.d(TAG, "onNotifyChipConnectionClosed")
    }

    override fun onCloseBleComplete() {
      Log.d(TAG, "onCloseBleComplete")
    }

    override fun onError(error: Throwable?) {
      Log.d(TAG, "onError: $error")
    }
  }

  private suspend fun sendLevelCommandClick() {
    // TODO : Need to be implement poj-to-tlv
    val tlvWriter = TlvWriter()
    tlvWriter.startStructure(AnonymousTag)
    tlvWriter.put(ContextSpecificTag(0), binding.levelBar.progress.toUInt())
    tlvWriter.put(ContextSpecificTag(1), 0u)
    tlvWriter.put(ContextSpecificTag(2), 0u)
    tlvWriter.put(ContextSpecificTag(3), 0u)
    tlvWriter.endStructure()

    val invokeElement = InvokeElement.newInstance(addressUpdateFragment.endpointId.toLong()
            , LevelControl.ID
            , LevelControl.Command.MoveToLevel.id
            , tlvWriter.getEncoded(), null)

    deviceController.invoke(object: InvokeCallback {
      override fun onError(ex: Exception?) {
        showMessage("MoveToLevel command failure $ex")
        Log.e(TAG, "MoveToLevel command failure", ex)
      }

      override fun onResponse(invokeElement: InvokeElement?, successCode: Long) {
        Log.e(TAG, "onResponse : $invokeElement, Code : $successCode")
        showMessage("MoveToLevel command success")
      }

    }, getConnectedDevicePointer(), invokeElement, 0, 0)
  }

  private suspend fun sendOnOffClusterCommand(commandId: OnOff.Command) {
    // TODO : Need to be implement poj-to-tlv
    val tlvWriter = TlvWriter()
    tlvWriter.startStructure(AnonymousTag)
    tlvWriter.endStructure()
    val invokeElement = InvokeElement.newInstance(addressUpdateFragment.endpointId.toLong()
            , OnOff.ID
            , commandId.id
            , tlvWriter.getEncoded(), null)

    deviceController.invoke(object: InvokeCallback {
      override fun onError(ex: Exception?) {
        showMessage("${commandId.name} command failure $ex")
        Log.e(TAG, "${commandId.name} command failure", ex)
      }

      override fun onResponse(invokeElement: InvokeElement?, successCode: Long) {
        Log.e(TAG, "onResponse : $invokeElement, Code : $successCode")
        showMessage("${commandId.name} command success")
      }

    }, getConnectedDevicePointer(), invokeElement, 0, 0)
  }

  private suspend fun getConnectedDevicePointer(): Long {
    return ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId)
  }

  private fun showMessage(msg: String) {
    requireActivity().runOnUiThread {
      binding.commandStatusTv.text = msg
    }
  }

  private fun showReportMessage(msg: String) {
    requireActivity().runOnUiThread {
      binding.reportStatusTv.text = msg
    }
  }

  override fun onResume() {
    super.onResume()
    addressUpdateFragment.endpointId = ON_OFF_CLUSTER_ENDPOINT

  }

  companion object {
    private const val TAG = "OnOffClientFragment"

    private const val ON_OFF_CLUSTER_ENDPOINT = 1
    private const val LEVEL_CONTROL_CLUSTER_ENDPOINT = 1

    fun newInstance(): OnOffClientFragment = OnOffClientFragment()
  }
}
