package com.google.chip.chiptool.clusterclient

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.ArrayAdapter
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipClusters
import chip.devicecontroller.ChipClusters.BasicCluster
import chip.devicecontroller.ChipDeviceController
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.GenericChipDeviceListener
import com.google.chip.chiptool.R
import kotlinx.android.synthetic.main.basic_client_fragment.attributeNameSpinner
import kotlinx.android.synthetic.main.basic_client_fragment.basicClusterCommandStatus
import kotlinx.android.synthetic.main.basic_client_fragment.locationEd
import kotlinx.android.synthetic.main.basic_client_fragment.nodeLabelEd
import kotlinx.android.synthetic.main.basic_client_fragment.view.attributeNameSpinner
import kotlinx.android.synthetic.main.basic_client_fragment.view.readAttributeBtn
import kotlinx.android.synthetic.main.basic_client_fragment.view.writeLocalConfigDisabledSwitch
import kotlinx.android.synthetic.main.basic_client_fragment.view.writeLocationBtn
import kotlinx.android.synthetic.main.basic_client_fragment.view.writeNodeLabelBtn
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

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

  private lateinit var scope: CoroutineScope

  private lateinit var addressUpdateFragment: AddressUpdateFragment

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

    return inflater.inflate(R.layout.basic_client_fragment, container, false).apply {
      deviceController.setCompletionListener(ChipControllerCallback())

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

      writeNodeLabelBtn.setOnClickListener { scope.launch {
        sendWriteNodeLabelAttribute()
        nodeLabelEd.onEditorAction(EditorInfo.IME_ACTION_DONE)
      }}
      writeLocationBtn.setOnClickListener { scope.launch {
        sendWriteLocationAttribute()
        locationEd.onEditorAction(EditorInfo.IME_ACTION_DONE)
      }}
      writeLocalConfigDisabledSwitch.setOnCheckedChangeListener { _, isChecked ->
        scope.launch { sendWriteLocalConfigDisabledAttribute(isChecked) }
      }
      makeAttributeList()
      attributeNameSpinner.adapter = makeAttributeNamesAdapter()
      readAttributeBtn.setOnClickListener { scope.launch { readAttributeButtonClick() }}
    }
  }

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

    override fun onCommissioningComplete(nodeId: Long, errorCode: Int) {
      Log.d(TAG, "onCommissioningComplete for nodeId $nodeId: $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 fun makeAttributeNamesAdapter(): ArrayAdapter<String> {
    return ArrayAdapter(
      requireContext(),
      android.R.layout.simple_spinner_dropdown_item,
      ATTRIBUTES.toList()
    ).apply {
      setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
    }
  }

  private suspend fun readAttributeButtonClick() {
    try {
      readBasicClusters(attributeNameSpinner.selectedItemPosition)
    } catch (ex: Exception) {
      showMessage("readBasicCluster failed: $ex")
    }
  }

  private suspend fun readBasicClusters(itemIndex: Int) {
    when(ATTRIBUTES[itemIndex]) {
      getString(R.string.basic_cluster_data_model_revision_text) -> sendReadDataModelRevisionAttribute()
      getString(R.string.basic_cluster_vendor_name_text) -> sendReadVendorNameAttribute()
      getString(R.string.basic_cluster_vendor_id_text) -> sendReadVendorIDAttribute()
      getString(R.string.basic_cluster_product_name_text) -> sendReadProductNameAttribute()
      getString(R.string.basic_cluster_product_id_text) -> sendReadProductIDAttribute()
      getString(R.string.basic_cluster_node_label_text) -> sendReadNodeLabelAttribute()
      getString(R.string.basic_cluster_location_text) -> sendReadLocationAttribute()
      getString(R.string.basic_cluster_hardware_version_text) -> sendReadHardwareVersionAttribute()
      getString(R.string.basic_cluster_hardware_version_string_text) -> sendReadHardwareVersionStringAttribute()
      getString(R.string.basic_cluster_software_version_text) -> sendReadSoftwareVersionAttribute()
      getString(R.string.basic_cluster_software_version_string_text) -> sendReadSoftwareVersionStringAttribute()
      getString(R.string.basic_cluster_manufacturing_date_text) -> sendReadManufacturingDateAttribute()
      getString(R.string.basic_cluster_part_number_text) -> sendReadPartNumberAttribute()
      getString(R.string.basic_cluster_product_url_text) -> sendReadProductURLAttribute()
      getString(R.string.basic_cluster_product_label_text) -> sendReadProductLabelAttribute()
      getString(R.string.basic_cluster_serial_number_text) -> sendReadSerialNumberAttribute()
      getString(R.string.basic_cluster_local_config_disabled_text) -> sendReadLocalConfigDisabledAttribute()
      getString(R.string.basic_cluster_reachable_text) -> sendReadReachableAttribute()
      getString(R.string.basic_cluster_cluster_revision_text) -> sendReadClusterRevisionAttribute()
    }
  }

  private fun makeAttributeList() {
    ATTRIBUTES.add(getString(R.string.basic_cluster_data_model_revision_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_vendor_name_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_vendor_id_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_product_name_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_product_id_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_node_label_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_location_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_hardware_version_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_hardware_version_string_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_software_version_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_software_version_string_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_manufacturing_date_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_part_number_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_product_url_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_product_label_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_serial_number_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_local_config_disabled_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_reachable_text))
    ATTRIBUTES.add(getString(R.string.basic_cluster_cluster_revision_text))
  }

  private suspend fun sendReadDataModelRevisionAttribute() {
    getBasicClusterForDevice().readDataModelRevisionAttribute(object : ChipClusters.IntegerAttributeCallback {
      override fun onSuccess(value: Int) {
        Log.i(TAG,"[Read Success] DataModelRevision: $value")
        showMessage("[Read Success] DataModelRevision: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read DataModelRevision failure $ex")
        Log.e(TAG, "Read DataModelRevision failure", ex)
      }
    })
  }

  private suspend fun sendReadVendorNameAttribute() {
    getBasicClusterForDevice().readVendorNameAttribute(object : ChipClusters.CharStringAttributeCallback {
      override fun onSuccess(value: String) {
        Log.i(TAG,"[Read Success] VendorName: $value")
        showMessage("[Read Success] VendorName: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read VendorName failure $ex")
        Log.e(TAG, "Read VendorName failure", ex)
      }
    })
  }

  private suspend fun sendReadVendorIDAttribute() {
    getBasicClusterForDevice().readVendorIDAttribute(object : ChipClusters.BasicCluster.VendorIDAttributeCallback {
      override fun onSuccess(value: Int) {
        Log.i(TAG,"[Read Success] VendorID: $value")
        showMessage("[Read Success] VendorID: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read VendorID failure $ex")
        Log.e(TAG, "Read VendorID failure", ex)
      }
    })
  }

  private suspend fun sendReadProductNameAttribute() {
    getBasicClusterForDevice().readProductNameAttribute(object : ChipClusters.CharStringAttributeCallback {
      override fun onSuccess(value: String) {
        Log.i(TAG,"[Read Success] ProductName: $value")
        showMessage("[Read Success] ProductName: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read ProductName failure $ex")
        Log.e(TAG, "Read ProductName failure", ex)
      }
    })
  }

  private suspend fun sendReadProductIDAttribute() {
    getBasicClusterForDevice().readProductIDAttribute(object : ChipClusters.IntegerAttributeCallback {
      override fun onSuccess(value: Int) {
        Log.i(TAG,"[Read Success] ProductID: $value")
        showMessage("[Read Success] ProductID: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read ProductID failure $ex")
        Log.e(TAG, "Read ProductID failure", ex)
      }
    })
  }

  private suspend fun sendReadNodeLabelAttribute() {
    getBasicClusterForDevice().readNodeLabelAttribute(object : ChipClusters.CharStringAttributeCallback {
      override fun onSuccess(value: String) {
        Log.i(TAG,"[Read Success] NodeLabel: $value")
        showMessage("[Read Success] NodeLabel: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read NodeLabel failure $ex")
        Log.e(TAG, "Read NodeLabel failure", ex)
      }
    })
  }

  private suspend fun sendWriteNodeLabelAttribute() {
    getBasicClusterForDevice().writeNodeLabelAttribute(object : ChipClusters.DefaultClusterCallback {
      override fun onSuccess() {
        showMessage("Write NodeLabel success")
      }

      override fun onError(ex: Exception) {
        showMessage("Write NodeLabel failure $ex")
        Log.e(TAG, "Write NodeLabel failure", ex)
      }
    }, nodeLabelEd.text.toString())
  }

  private suspend fun sendReadLocationAttribute() {
    getBasicClusterForDevice().readLocationAttribute(object : ChipClusters.CharStringAttributeCallback {
      override fun onSuccess(value: String) {
        Log.i(TAG,"[Read Success] Location: $value")
        showMessage("[Read Success] Location: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read Location failure $ex")
        Log.e(TAG, "Read Location failure", ex)
      }
    })
  }

  private suspend fun sendWriteLocationAttribute() {
    getBasicClusterForDevice().writeLocationAttribute(object : ChipClusters.DefaultClusterCallback {
      override fun onSuccess() {
        showMessage("Write Location success")
      }

      override fun onError(ex: Exception) {
        showMessage("Write Location failure $ex")
        Log.e(TAG, "Write Location failure", ex)
      }
    }, locationEd.text.toString())
  }

  private suspend fun sendReadHardwareVersionAttribute() {
    getBasicClusterForDevice().readHardwareVersionAttribute(object : ChipClusters.IntegerAttributeCallback {
      override fun onSuccess(value: Int) {
        Log.i(TAG,"[Read Success] HardwareVersion: $value")
        showMessage("[Read Success] HardwareVersion: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read HardwareVersion failure $ex")
        Log.e(TAG, "Read HardwareVersion failure", ex)
      }
    })
  }

  private suspend fun sendReadHardwareVersionStringAttribute() {
    getBasicClusterForDevice().readHardwareVersionStringAttribute(object : ChipClusters.CharStringAttributeCallback {
      override fun onSuccess(value: String) {
        Log.i(TAG,"[Read Success] HardwareVersionString: $value")
        showMessage("[Read Success] HardwareVersionString: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read HardwareVersionString failure $ex")
        Log.e(TAG, "Read HardwareVersionString failure", ex)
      }
    })
  }

  private suspend fun sendReadSoftwareVersionAttribute() {
    getBasicClusterForDevice().readSoftwareVersionAttribute(object : ChipClusters.LongAttributeCallback {
      override fun onSuccess(value: Long) {
        Log.i(TAG,"[Read Success] SoftwareVersion: $value")
        showMessage("[Read Success] SoftwareVersion: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read SoftwareVersion failure $ex")
        Log.e(TAG, "Read SoftwareVersion failure", ex)
      }
    })
  }

  private suspend fun sendReadSoftwareVersionStringAttribute() {
    getBasicClusterForDevice().readSoftwareVersionStringAttribute(object : ChipClusters.CharStringAttributeCallback {
      override fun onSuccess(value: String) {
        Log.i(TAG,"[Read Success] SoftwareVersionString $value")
        showMessage("[Read Success] SoftwareVersionString: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read SoftwareVersionString failure $ex")
        Log.e(TAG, "Read SoftwareVersionString failure", ex)
      }
    })
  }

  private suspend fun sendReadManufacturingDateAttribute() {
    getBasicClusterForDevice().readManufacturingDateAttribute(object : ChipClusters.CharStringAttributeCallback {
      override fun onSuccess(value: String) {
        Log.i(TAG,"[Read Success] ManufacturingDate $value")
        showMessage("[Read Success] ManufacturingDate: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read ManufacturingDate failure $ex")
        Log.e(TAG, "Read ManufacturingDate failure", ex)
      }
    })
  }

  private suspend fun sendReadPartNumberAttribute() {
    getBasicClusterForDevice().readPartNumberAttribute(object : ChipClusters.CharStringAttributeCallback {
      override fun onSuccess(value: String) {
        Log.i(TAG,"[Read Success] PartNumber $value")
        showMessage("[Read Success] PartNumber: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read PartNumber failure $ex")
        Log.e(TAG, "Read PartNumber failure", ex)
      }
    })
  }

  private suspend fun sendReadProductURLAttribute() {
    getBasicClusterForDevice().readProductURLAttribute(object : ChipClusters.CharStringAttributeCallback {
      override fun onSuccess(value: String) {
        Log.i(TAG,"[Read Success] ProductURL $value")
        showMessage("[Read Success] ProductURL: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read ProductURL failure $ex")
        Log.e(TAG, "Read ProductURL failure", ex)
      }
    })
  }

  private suspend fun sendReadProductLabelAttribute() {
    getBasicClusterForDevice().readProductLabelAttribute(object : ChipClusters.CharStringAttributeCallback {
      override fun onSuccess(value: String) {
        Log.i(TAG,"[Read Success] ProductLabel $value")
        showMessage("[Read Success] ProductLabel: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read ProductLabel failure $ex")
        Log.e(TAG, "Read ProductLabel failure", ex)
      }
    })
  }

  private suspend fun sendReadSerialNumberAttribute() {
    getBasicClusterForDevice().readSerialNumberAttribute(object : ChipClusters.CharStringAttributeCallback {
      override fun onSuccess(value: String) {
        Log.i(TAG,"[Read Success] SerialNumber $value")
        showMessage("[Read Success] SerialNumber: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read SerialNumber failure $ex")
        Log.e(TAG, "Read SerialNumber failure", ex)
      }
    })
  }

  private suspend fun sendReadLocalConfigDisabledAttribute() {
    getBasicClusterForDevice().readLocalConfigDisabledAttribute(object : ChipClusters.BooleanAttributeCallback {
      override fun onSuccess(value: Boolean) {
        Log.i(TAG,"[Read Success] LocalConfigDisabled $value")
        showMessage("[Read Success] LocalConfigDisabled: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read LocalConfigDisabled failure $ex")
        Log.e(TAG, "Read LocalConfigDisabled failure", ex)
      }
    })
  }

  private suspend fun sendWriteLocalConfigDisabledAttribute(localConfigDisabled: Boolean) {
    getBasicClusterForDevice().writeLocalConfigDisabledAttribute(object : ChipClusters.DefaultClusterCallback {
      override fun onSuccess() {
        showMessage("Write LocalConfigDisabled success")
      }

      override fun onError(ex: Exception) {
        showMessage("Write LocalConfigDisabled failure $ex")
        Log.e(TAG, "Write LocalConfigDisabled failure", ex)
      }
    }, localConfigDisabled)
  }

  private suspend fun sendReadReachableAttribute() {
    getBasicClusterForDevice().readReachableAttribute(object : ChipClusters.BooleanAttributeCallback {
      override fun onSuccess(value: Boolean) {
        Log.i(TAG,"[Read Success] Reachable $value")
        showMessage("[Read Success] Reachable: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read Reachable failure $ex")
        Log.e(TAG, "Read Reachable failure", ex)
      }
    })
  }

  private suspend fun sendReadClusterRevisionAttribute() {
    getBasicClusterForDevice().readClusterRevisionAttribute(object : ChipClusters.IntegerAttributeCallback {
      override fun onSuccess(value: Int) {
        Log.i(TAG,"[Read Success] ClusterRevision $value")
        showMessage("[Read Success] ClusterRevision: $value")
      }

      override fun onError(ex: Exception) {
        showMessage("Read ClusterRevision failure $ex")
        Log.e(TAG, "Read ClusterRevision failure", ex)
      }
    })
  }

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

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

  companion object {
    private const val TAG = "BasicClientFragment"
    private const val ENDPOINT = 0
    private val ATTRIBUTES: MutableList<String> = mutableListOf()

    fun newInstance(): BasicClientFragment = BasicClientFragment()
  }
}
