package com.casic.electric.detector.view

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.app.DatePickerDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.media.AudioAttributes
import android.media.SoundPool
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.provider.Settings
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.view.WindowManager
import android.widget.AdapterView
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.amap.api.location.AMapLocation
import com.casic.electric.detector.R
import com.casic.electric.detector.adapter.EditableImageAdapter
import com.casic.electric.detector.base.SerialPortActivity
import com.casic.electric.detector.callback.ILocationListener
import com.casic.electric.detector.callback.OnImageCompressListener
import com.casic.electric.detector.extensions.*
import com.casic.electric.detector.utils.*
import com.casic.electric.detector.vm.TaskViewModel
import com.gyf.immersionbar.ImmersionBar
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.pengxh.kt.lite.extensions.*
import com.pengxh.kt.lite.utils.SaveKeyValues
import com.pengxh.kt.lite.utils.WeakReferenceHandler
import com.pengxh.kt.lite.vm.LoadState
import com.pengxh.kt.lite.widget.dialog.NoNetworkDialog
import kotlinx.android.synthetic.main.activity_install_label.*
import kotlinx.android.synthetic.main.include_base_title.*
import kotlinx.android.synthetic.main.include_label_marker_attribute.*
import kotlinx.android.synthetic.main.include_label_object_attribute.*
import kotlinx.android.synthetic.main.include_open_camera.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.io.IOException
import java.util.*

@SuppressLint("SetTextI18n")
class InstallLabelActivity : SerialPortActivity(), Handler.Callback {

    private val kTag = "LabelActivity"
    private val context: Context = this@InstallLabelActivity
    private val gpioManager by lazy { GpioManager() }
    private val calendar by lazy { Calendar.getInstance() }
    private val realPaths: ArrayList<String> = ArrayList() //真实图片路径
    private var soundResId = 0
    private lateinit var weakReferenceHandler: WeakReferenceHandler
    private lateinit var soundPool: SoundPool
    private lateinit var imageAdapter: EditableImageAdapter
    private lateinit var taskViewModel: TaskViewModel

    override fun initLayoutView(): Int = R.layout.activity_install_label

    override fun setupTopBarLayout() {
        titleView.text = "安装新标识器"
        titleView.setTextColor(R.color.themeColor.convertColor(this))

        ImmersionBar.with(this)
            .statusBarDarkFont(true)
            .statusBarColor(R.color.mainBackground)
            .init()
        initLayoutImmersionBar(rootView)
    }

    override fun initData(savedInstanceState: Bundle?) {
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN or WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)

        weakReferenceHandler = WeakReferenceHandler(this)

        val audioAttributes = AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .build()
        soundPool = SoundPool.Builder()
            .setMaxStreams(16)
            .setAudioAttributes(audioAttributes)
            .build()

        //设置上次填写过的值
        objectCodeView.setText("objectCodeView".getDefaultValue())
        objectNameView.setText("objectNameView".getDefaultValue())
        inlineNameView.setText("inlineNameView".getDefaultValue())
        capacityView.setText("capacityView".getDefaultValue())
        transformerSpecView.setText("transformerSpecView".getDefaultValue())
        sLengthView.setText("sLengthView".getDefaultValue())
        sWidthView.setText("sWidthView".getDefaultValue())
        sHeightView.setText("sHeightView".getDefaultValue())
        inlineCountView.setText("inlineCountView".getDefaultValue())
        outlineCountView.setText("outlineCountView".getDefaultValue())
        bottomDepthView.setText("bottomDepthView".getDefaultValue())
        rowCountView.setText("rowCountView".getDefaultValue())
        rowHoleCountView.setText("rowHoleCountView".getDefaultValue())
        coverDepthView.setText("coverDepthView".getDefaultValue())
        remainingChannelsView.setText("remainingChannelsView".getDefaultValue())
        tieCableView1.setText("tieCableView1".getDefaultValue())
        tieCableView2.setText("tieCableView2".getDefaultValue())
        jointCountView.setText("jointCountView".getDefaultValue())
        casingHoleCountView.setText("casingHoleCountView".getDefaultValue())
        casingHoleDiameterView.setText("casingHoleDiameterView".getDefaultValue())
        heightView.setText("heightView".getDefaultValue())
        lineNumberView.setText("lineNumberView".getDefaultValue())
        inspectionUnitView.setText("inspectionUnitView".getDefaultValue())
        areaView.setText("areaView".getDefaultValue())
        roadView.setText("roadView".getDefaultValue())
        objectRemarkView1.setText("objectRemarkView1".getDefaultValue())
        objectRemarkView2.setText("objectRemarkView2".getDefaultValue())
        objectRemarkView3.setText("objectRemarkView3".getDefaultValue())
        ownerView.setText("ownerView".getDefaultValue())
        markerDepthView.setText("markerDepthView".getDefaultValue())
        markerCountView.setText("markerCountView".getDefaultValue())
        remarkView1.setText("remarkView1".getDefaultValue())
        remarkView2.setText("remarkView2".getDefaultValue())
        remarkView3.setText("remarkView3".getDefaultValue())

        //初始化图片九宫格
        imageAdapter = EditableImageAdapter(this, 3, 3f)
        addImageRecyclerView.adapter = imageAdapter

        taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java]
    }

    override fun observeRequestState() {
        taskViewModel.loadState.observe(this) {
            when (it) {
                LoadState.Loading -> LoadingDialogHub.show(this, "标识器安装中，请稍后...")
                LoadState.Success -> {
                    LoadingDialogHub.dismiss()
                    finish()
                }
                else -> LoadingDialogHub.dismiss()
            }
        }
    }

    override fun initEvent() {
        leftBackView.setOnClickListener { finish() }

        /**************************************************************************************/
        objectTypeSpinner.show(this, LocaleConstant.CONTENT_ARRAY, 0)
        objectTypeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(
                parent: AdapterView<*>?, view: View?, position: Int, id: Long
            ) {
                when (position) {
                    0 -> {
                        //选择电缆井
                        objectModeView.text = "类型："
                        wellCoverMaterialView.text = "井盖材质："
                        bottomDepthNameView.text = "井深："
                        setLayoutVisibility(
                            View.VISIBLE, View.GONE, View.VISIBLE, View.GONE, View.VISIBLE,
                            View.GONE, View.GONE, View.VISIBLE, View.GONE, View.VISIBLE,
                            View.GONE
                        )
                        objectModeSpinner.show(
                            this@InstallLabelActivity, LocaleConstant.OBJECT_MODE_ARRAY, 0
                        )
                        wellCoverMaterialSpinner.show(
                            this@InstallLabelActivity, LocaleConstant.WELL_COVER_MATERIAL_ARRAY_1, 0
                        )
                    }
                    1 -> {
                        //选择电缆通道
                        bottomDepthNameView.text = "底部深度："
                        setLayoutVisibility(
                            View.GONE, View.GONE, View.GONE, View.GONE, View.GONE,
                            View.GONE, View.GONE, View.VISIBLE, View.VISIBLE, View.VISIBLE,
                            View.GONE
                        )
                    }
                    2 -> {
                        //选择配电房
                        setLayoutVisibility(
                            View.GONE, View.GONE, View.GONE, View.VISIBLE, View.VISIBLE,
                            View.VISIBLE, View.GONE, View.GONE, View.GONE, View.GONE,
                            View.GONE
                        )
                    }
                    3 -> {
                        //选择开关站
                        setLayoutVisibility(
                            View.GONE, View.GONE, View.GONE, View.GONE, View.VISIBLE,
                            View.VISIBLE, View.VISIBLE, View.GONE, View.GONE, View.GONE,
                            View.GONE
                        )
                    }
                    4 -> {
                        //选择台区
                        objectModeView.text = "变压器型号："
                        setLayoutVisibility(
                            View.VISIBLE, View.VISIBLE, View.GONE, View.GONE, View.GONE,
                            View.GONE, View.GONE, View.GONE, View.GONE, View.GONE,
                            View.GONE
                        )
                        objectModeSpinner.show(
                            this@InstallLabelActivity, arrayOf("变压器 KVA"), 0
                        )
                    }
                    5 -> {
                        //选择杆塔
                        wellCoverMaterialView.text = "对象材质："
                        setLayoutVisibility(
                            View.GONE, View.GONE, View.VISIBLE, View.GONE, View.GONE,
                            View.GONE, View.GONE, View.GONE, View.GONE, View.GONE,
                            View.VISIBLE
                        )
                        wellCoverMaterialSpinner.show(
                            this@InstallLabelActivity, LocaleConstant.WELL_COVER_MATERIAL_ARRAY_2, 0
                        )
                    }
                }
            }

            override fun onNothingSelected(parent: AdapterView<*>?) {

            }
        }

        cabinetTypeSpinner.show(this, LocaleConstant.CABINET_TYPE_ARRAY, 0)
        casingMaterialSpinner.show(this, LocaleConstant.PIPE_MATERIAL_ARRAY, 0)
        markerTypeSpinner.show(this, LocaleConstant.MARKER_TYPE_ARRAY, 0)

        //电压等级-多选
        voltageLevelView.setOnClickListener {
            AlertDialog.Builder(context)
                .setCancelable(false)
                .setIcon(R.mipmap.ic_launcher)
                .setTitle("请选择电压等级")
                .setMultiChoiceItems(
                    LocaleConstant.VOLTAGE_LEVEL_ARRAY, LocaleConstant.VOLTAGE_LEVEL_STATE_ARRAY
                ) { _, which, isChecked ->
                    LocaleConstant.VOLTAGE_LEVEL_STATE_ARRAY[which] = isChecked
                }
                .setNegativeButton("取消") { dialog, _ -> dialog?.dismiss() }
                .setPositiveButton("确定") { _, _ ->
                    val temp = ArrayList<String>()
                    LocaleConstant.VOLTAGE_LEVEL_ARRAY.forEachIndexed { index, s ->
                        if (LocaleConstant.VOLTAGE_LEVEL_STATE_ARRAY[index]) {
                            temp.add(s)
                        }
                    }

                    voltageLevelView.text = temp.reformat()
                }.show()
        }

        //交叉管道类型-多选
        crossPipeLineView.setOnClickListener {
            AlertDialog.Builder(context)
                .setCancelable(false)
                .setIcon(R.mipmap.ic_launcher)
                .setTitle("请选择交叉管道类型")
                .setMultiChoiceItems(
                    LocaleConstant.CROSS_PIPE_ARRAY, LocaleConstant.CROSS_PIPE_STATE_ARRAY
                ) { _, which, isChecked ->
                    LocaleConstant.CROSS_PIPE_STATE_ARRAY[which] = isChecked
                }
                .setNegativeButton("取消") { dialog, _ -> dialog?.dismiss() }
                .setPositiveButton("确定") { _, _ ->
                    val temp = ArrayList<String>()
                    LocaleConstant.CROSS_PIPE_ARRAY.forEachIndexed { index, s ->
                        if (LocaleConstant.CROSS_PIPE_STATE_ARRAY[index]) {
                            temp.add(s)
                        }
                    }

                    crossPipeLineView.text = temp.reformat()
                }.show()
        }

        constructDateView.setOnClickListener {
            val datePicker = DatePickerDialog(
                this,
                null,
                calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH)
            )
            datePicker.show()

            datePicker.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
                val year = datePicker.datePicker.year
                val month = datePicker.datePicker.month + 1
                val day = datePicker.datePicker.dayOfMonth
                val selectedDate = String.format(
                    "%s-%s-%s", year, month.appendZero(), day.appendZero()
                )

                //当前时间
                val current = System.currentTimeMillis().timestampToTime()
                val today = "$selectedDate $current".dateToTimestamp()
                if (Date(today).after(Date())) {
                    "建设年代不能早于当前日期".show(context)
                } else {
                    datePicker.dismiss()
                    constructDateView.text = selectedDate
                }
            }
        }

        installTimeView.text = System.currentTimeMillis().timestampToCompleteDate()
        LocationHub.getCurrentLocation(this, object : ILocationListener {
            override fun onAMapLocationGet(location: AMapLocation?) {
                if (location != null) {
                    lngView.text = location.longitude.toString()
                    latView.text = location.latitude.toString()
                } else {
                    "当前位置信号差，无法获取定位".show(context)
                }
            }
        })

        imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
            override fun onAddImageClick() {
                PictureSelector.create(this@InstallLabelActivity)
                    .openCamera(SelectMimeType.ofImage())
                    .forResult(object : OnResultCallbackListener<LocalMedia> {
                        override fun onResult(result: ArrayList<LocalMedia>?) {
                            if (result == null) {
                                "拍照失败，请重试".show(context)
                                return
                            }
                            analyticalSelectResult(result[0])
                        }

                        override fun onCancel() {

                        }
                    })
            }

            override fun onItemClick(position: Int) {
                if (realPaths[position].isEmpty()) {
                    "图片加载失败，无法查看大图".show(context)
                } else {
                    context.navigatePageTo<BigImageActivity>(position, realPaths)
                }
            }

            override fun onItemLongClick(view: View?, position: Int) {
                imageAdapter.deleteImage(position)
            }
        })

        /**************************************************************************************/
        installButton.setOnClickListener {
            if (isNetworkConnected()) {
                val companyId = SaveKeyValues.getValue(LocaleConstant.USER_COMPANY_ID, "") as String

                val itemPosition = objectTypeSpinner.selectedItemPosition
                val objectTypeCode = itemPosition + 1

                if (markerIdView.text.isNullOrBlank()) {
                    "标识器ID不能为空，请读标识器".show(this)
                    return@setOnClickListener
                }

                if (constructDateView.text.isNullOrBlank()) {
                    "请选择建设时间".show(this)
                    return@setOnClickListener
                }

                if (markerCountView.text.isNullOrBlank()) {
                    "请输入电子标签数量".show(this)
                    return@setOnClickListener
                }

                //保存默认值
                "objectCodeView".setDefaultValue(objectCodeView)
                "objectNameView".setDefaultValue(objectNameView)
                "inlineNameView".setDefaultValue(inlineNameView)
                "capacityView".setDefaultValue(capacityView)
                "transformerSpecView".setDefaultValue(transformerSpecView)
                "sLengthView".setDefaultValue(sLengthView)
                "sWidthView".setDefaultValue(sWidthView)
                "sHeightView".setDefaultValue(sHeightView)
                "inlineCountView".setDefaultValue(inlineCountView)
                "outlineCountView".setDefaultValue(outlineCountView)
                "bottomDepthView".setDefaultValue(bottomDepthView)
                "rowCountView".setDefaultValue(rowCountView)
                "rowHoleCountView".setDefaultValue(rowHoleCountView)
                "coverDepthView".setDefaultValue(coverDepthView)
                "remainingChannelsView".setDefaultValue(remainingChannelsView)
                "tieCableView1".setDefaultValue(tieCableView1)
                "tieCableView2".setDefaultValue(tieCableView2)
                "jointCountView".setDefaultValue(jointCountView)
                "casingHoleCountView".setDefaultValue(casingHoleCountView)
                "casingHoleDiameterView".setDefaultValue(casingHoleDiameterView)
                "heightView".setDefaultValue(heightView)
                "lineNumberView".setDefaultValue(lineNumberView)
                "inspectionUnitView".setDefaultValue(inspectionUnitView)
                "areaView".setDefaultValue(areaView)
                "roadView".setDefaultValue(roadView)
                "objectRemarkView1".setDefaultValue(objectRemarkView1)
                "objectRemarkView2".setDefaultValue(objectRemarkView2)
                "objectRemarkView3".setDefaultValue(objectRemarkView3)
                "ownerView".setDefaultValue(ownerView)
                "markerDepthView".setDefaultValue(markerDepthView)
                "markerCountView".setDefaultValue(markerCountView)
                "remarkView1".setDefaultValue(remarkView1)
                "remarkView2".setDefaultValue(remarkView2)
                "remarkView3".setDefaultValue(remarkView3)

                val labelData = LabelDataClass(
                    companyId,
                    objectTypeCode.toString(),
                    objectCodeView.text.toString(),
                    objectNameView.text.toString(),
                    voltageLevelView.text.toString(),
                    objectModeSpinner.selectedItem.toString(),
                    "进线${inlineNameView.text}",
                    wellCoverMaterialSpinner.selectedItem.toString(),
                    "${capacityView.text}KVA",
                    transformerSpecView.text.toString(),
                    "${sLengthView.text}米长 x ${sWidthView.text}米宽 x ${sHeightView.text}米高",
                    inlineCountView.text.toString(),
                    outlineCountView.text.toString(),
                    cabinetTypeSpinner.selectedItem.toString(),
                    bottomDepthView.text.toString(),
                    "${rowCountView.text}排 x ${rowHoleCountView.text}孔",
                    "${coverDepthView.text}米",
                    crossPipeLineView.text.toString(),
                    remainingChannelsView.text.toString(),
                    tieCableView1.text.toString(),
                    tieCableView2.text.toString(),
                    jointCountView.text.toString(),
                    casingMaterialSpinner.selectedItem.toString(),
                    "${casingHoleCountView.text}孔，直径${casingHoleDiameterView.text}毫米",
                    "${heightView.text.toString()}米",
                    lineNumberView.text.toString(),
                    constructDateView.text.toString(),
                    inspectionUnitView.text.toString(),
                    areaView.text.toString(),
                    roadView.text.toString(),
                    objectRemarkView1.text.toString(),
                    objectRemarkView2.text.toString(),
                    objectRemarkView3.text.toString(),
                    markerIdView.text.toString(),
                    markerTypeSpinner.selectedItem.toString(),
                    ownerView.text.toString(),
                    markerDepthView.text.toString(),
                    installTimeView.text.toString(),
                    lngView.text.toString(),
                    latView.text.toString(),
                    markerCountView.text.toString(),
                    remarkView1.text.toString(),
                    remarkView2.text.toString(),
                    remarkView3.text.toString(),
                    realPaths
                )

                //先存本地
                lifecycleScope.launch {
                    withContext(Dispatchers.IO) {
                        DataBaseManager.get.insertLabel(labelData)
                    }
                }

                //再存服务器
                taskViewModel.installLabel(labelData)
            } else {
                NoNetworkDialog.Builder()
                    .setContext(context)
                    .setOnDialogButtonClickListener(object :
                        NoNetworkDialog.OnDialogButtonClickListener {
                        override fun onButtonClick() {
                            val intent = Intent(Settings.ACTION_SETTINGS)
                            startActivity(intent)
                        }
                    }).build().show()
            }
        }

        readLabelButton.setOnClickListener {
            gpioManager.setGpioHigh("18")

            LoadingDialogHub.show(this, "标识器读取中，请稍后...")

            soundResId = soundPool.load(this, R.raw.ring3, 1)
            soundPool.setOnLoadCompleteListener { soundPool, _, _ ->
                soundPool.play(soundResId, 1f, 1f, 0, -1, 1f)
            }

            // 1000ms后发送读标识器或搜索信号
            weakReferenceHandler.postDelayed({
                try {
                    // 发送读标识器或搜索信号
                    outputStream?.write("2".toByteArray())
                    outputStream?.flush()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }, 1000)
        }
    }

    override fun onDataReceived(buffer: ByteArray?, size: Int) {
        Log.d(kTag, "onDataReceived => " + buffer.contentToString())
        if (buffer != null) {
            val message = weakReferenceHandler.obtainMessage()
            message.what = 2023081701
            message.obj = buffer
            weakReferenceHandler.sendMessage(message)
        }
    }

    override fun handleMessage(msg: Message): Boolean {
        if (msg.what == 2023081701) {
            soundPool.release()

            val buffer = msg.obj as ByteArray
            val hex = buffer.toHex()

            if (hex.length >= 20) {
                val markerId = hex.substring(0, 20).hexToString()

                gpioManager.setGpioLow("18")

                //查本地库
                val result = DataBaseManager.get.queryLabelById(markerId)
                if (result.isEmpty()) {
                    markerIdView.text = markerId
                } else {
                    "此标识器已安装，请更换标识器！".show(this)
                }
                LoadingDialogHub.dismiss()
            }
        }
        return true
    }

    private fun analyticalSelectResult(result: LocalMedia) {
        //压缩图片
        result.realPath.compressImage(this, object : OnImageCompressListener {
            override fun onSuccess(file: File) {
                realPaths.add(file.absolutePath)
                imageAdapter.setupImage(realPaths)
            }

            override fun onError(e: Throwable) {
                e.printStackTrace()
            }
        })
    }

    //根据选择类型控制界面某些区域显隐
    private fun setLayoutVisibility(vararg args: Int) {
        objectModeLayout.visibility = args[0]
        inlineNameLayout.visibility = args[1]
        wellCoverMaterialLayout.visibility = args[2]
        capacityLayout.visibility = args[3]
        sizeLayout.visibility = args[4]
        inlineCountLayout.visibility = args[5]
        outlineCountLayout.visibility = args[6]
        wellDepthLayout.visibility = args[7]
        pipeLineLayout.visibility = args[8]
        jointCountLayout.visibility = args[9]
        heightLayout.visibility = args[10]
    }

    override fun onDestroy() {
        super.onDestroy()
        soundPool.release()
        gpioManager.setGpioLow("18")
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            soundPool.release()
        }
        return super.onKeyDown(keyCode, event)
    }
}