<template>

  <a-card title="设备统计" >
    <a-row justify="center">
      <a-col
        v-for="item in state.deviceCount"
        :key="item.key"
        :xs="12"  :sm="12"  :md="6"  :lg="8"  :xl="4"
      >
        <div class="statistic" >
          <span class="count" :style="{color: item.color}" >{{item.value}}</span>
          <span>台</span>
        </div>
        <div class="label" >
          {{item.label}}
        </div>
      </a-col>
    </a-row>
  </a-card>

  <a-card style="margin-top: 20px;">
    <a-row justify="space-between" >
      <a-col :span="20"  >
        <a-form layout="inline" >
          <a-form-item label="设备状态"  >
            <a-select  allowClear style="width: 176px;"  v-model:value="searchState.deviceStatus" placeholder="请输入设备状态">
              <a-select-option
                v-for="item in DeviceContriller.deviceStatus"
                :key="item.key"
                :value="item.key"
              >{{item.name}}</a-select-option>
            </a-select>
            <!-- <a-input v-model:value="searchState.deviceStatus" placeholder="请输入设备状态"/> -->
          </a-form-item>
          <a-form-item style="width: 400px;">
            <a-input-group compact >
              <a-select v-model:value="searchState.searchKey" style="width: 150px;" >
                <a-select-option v-for="item in searchList" :key="item.key" :value="item.key">{{item.name}}</a-select-option>
              </a-select>
              <a-input v-model:value="searchState.searchValue" style="width: 176px" placeholder="请输入查询值"/>
            </a-input-group>
          </a-form-item>
          <a-form-item><a-button @click="resetFields([])">重置</a-button></a-form-item>
          <a-form-item><a-button type="primary" @click="getDevicePage">搜索</a-button> </a-form-item>
        </a-form>
      </a-col>
      <a-col :span="2" >
        <a-button type="primary" @click="openModal('add', {})"> + 新增设备</a-button>
      </a-col>
    </a-row>

    <a-table
      style="margin-top: 10px;"
      :columns="columns"
      :data-source="state.dataSource"
      :loading="state.loading"
      :pagination="searchState"
      @change="changePage"
    >
      <template #bodyCell="{column, record}">
        <template v-if="column.key === 'id'" >
          <a @click="goDetailPage(record.id)">{{record.id}}</a>
        </template>
        <template v-if="column.key === 'deviceStatus'" >
          <a-tag :color="record.deviceStatus.color" >{{record.deviceStatus.name}}</a-tag>
        </template>
        <template v-if="column.key === 'deviceNodeType'" >
          <a-tag>{{record.deviceNodeType == 'GATEWAY'?'直连类型':'非直连类型'}}</a-tag>
        </template>
        <template v-if="column.key === 'action'">
            <a-space>
              <a @click="goDetailPage(record.id)">查看</a>
              <a @click="goDebugPage(record.id)" >调试</a>
              <a-popconfirm
                  title="确实要删除吗？"
                  ok-text="确定"
                  cancel-text="取消"
                  @confirm="delDevice(record.id)"
                >
                  <a href="#">删除</a>
              </a-popconfirm>
              <a-dropdown>
                <a class="ant-dropdown-link" @click.prevent>分析 <DownOutlined /> </a>
                <template #overlay>
                  <a-menu>
                    <a-menu-item
                      v-for="item in analysisList"
                      :key="item.key"
                      @click="openAnalysisModal(item.key, record.id)"
                    >
                      <a href="javascript:;">{{item.label}}</a>
                    </a-menu-item>
                  </a-menu>
                </template>
              </a-dropdown>
            </a-space>
        </template>
      </template>
    </a-table>
  </a-card>

  <a-modal
    title="单设备注册"
    :open="state.visible"
    @cancel="state.visible = false"
    @ok="ok"
  >
    <a-form  :labelCol="{span: 6}" :wrapperCol="{span: 14}" >
      <a-form-item label="所属产品" v-bind="validateInfosDeviceState.modelId" >
        <a-select v-model:value="deviceState.modelId" >
          <a-select-option
            v-for="item in state.modelList"
            :key="item.id"
            :value="item.id"
          >
            {{item.modelLabel}}
          </a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item label="设备标识码" v-bind="validateInfosDeviceState.deviceCode"  >
        <a-input v-model:value="deviceState.deviceCode" />
      </a-form-item>
      <a-form-item label="设备名称" >
        <a-input v-model:value="deviceState.deviceLabel" />
      </a-form-item>
      <a-form-item label="设备认证类型" >
        <a-radio-group v-model:value="deviceState.deviceAuthType">
          <a-radio value="SECRET">密钥认证</a-radio>
          <a-radio value="X509CERT">x509证书</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item label="密匙" v-if="deviceState.deviceAuthType === DeviceAuthTypeEnum.SECRET " >
        <a-input-password v-model:value="deviceState.deviceSecret" />
      </a-form-item>
      <a-form-item label="确认密匙"  v-if="deviceState.deviceAuthType === DeviceAuthTypeEnum.SECRET ">
        <a-input-password v-model:value="deviceState.confirmSecret" />
      </a-form-item>
    </a-form>
  </a-modal>

  <modal-pro
    :label="analysisTitle"
    :open="state.analysisVisible"
    @cancel="state.analysisVisible = false"
    @ok="state.analysisVisible = false"
    style="width: 700px;"
  >
    <a-row :gutter="[8, 8]" style="margin-top: 20px;" >
      <a-col :span="24" >
        <a-range-picker @change="changeRangePicker" format="YYYY/MM/DD"  />
      </a-col>
      <a-spin :spinning="analysisState.loading" >
      <a-col :span="24" v-if="state.analysisType === 'session'">
        <div id="device-session" style="width: 600px;height: 400px;" ></div>
        <div id="device-session-scatter" style="width: 600px;height: 400px;" ></div>
      </a-col>
      <a-col :span="24" v-else>
        <div id="device-attr" style="width: 600px;height: 400px;" ></div>
      </a-col>
    </a-spin>
    </a-row>
  </modal-pro>

</template>

<script lang="ts" setup >

import { DeviceContriller, ModelController } from '@/controller/index'
import { onMounted, reactive, ref, toRefs, nextTick, computed, watch } from 'vue'
import { Form, message } from 'ant-design-vue'
import { DeviceAuthTypeEnum } from '@/enum/common'
import { useRouter } from 'vue-router'
import { DownOutlined } from '@ant-design/icons-vue'
import * as echarts from 'echarts'
import { sessionEchartsJson, attrEchartsJson, scatterOption, barOption } from './json/echartsJson'

const useForm = Form.useForm
const router = useRouter()

const columns = [
  {
    title: '设备ID',
    dataIndex: 'id',
    key: 'id'
  },
  {
    title: '设备名称',
    dataIndex: 'deviceLabel'
  },
  {
    title: '设备标识码',
    dataIndex: 'deviceCode'
  },
  {
    title: '设备描述',
    dataIndex: 'deviceDescription'
  },
  {
    title: '节点类型',
    dataIndex: 'deviceNodeType',
    key: 'deviceNodeType'
  },
  {
    title: '所属产品',
    dataIndex: 'modelLabel'
  },
  {
    title: '状态',
    dataIndex: 'deviceStatus',
    key: 'deviceStatus'
  },
  {
    title: '操作',
    key: 'action'
  }
]

const searchList = [
  { name: '设备id', key: 'deviceId' },
  { name: '设备名称', key: 'deviceLabel' },
  { name: '设备标识码', key: 'deviceCode' }
]

const analysisList = [
  { label: '上下线分析', key: 'session' },
  { label: '属性分析', key: 'attr' }
]

const analysisTitle = computed(() => state.analysisType === 'session' ? '上下线分析' : '属性分析')

const state = reactive<{
  modelId: string,
  deviceCount: any,
  dataSource: IOT.API.DEVICE.Device[],
  loading: boolean,
  visible: boolean,
  opraState: 'add' | 'update',
  modelList: IOT.API.MODEL.ModelDot[]
  analysisVisible: boolean
  analysisType: 'session' | 'attr' | ''
}>({
  modelId: '',
  deviceCount: [],
  dataSource: [],
  modelList: [],
  loading: false,
  visible: false,
  analysisVisible: false,
  analysisType: '',
  opraState: 'add'
})

const searchState = reactive({
  page: 1,
  pageSize: 10,
  total: 0,
  deviceStatus: '',
  modelId: '',
  searchKey: 'deviceId',
  searchValue: ''
})

const deviceState = reactive({
  id: '',
  modelId: '',
  deviceLabel: '',
  deviceCode: '',
  deviceDescription: '',
  deviceAuthType: DeviceAuthTypeEnum.SECRET,
  modelLabel: '',
  deviceSecret: '',
  confirmSecret: ''
})

const analysisState = reactive({
  deviceId: '',
  start: 0,
  end: '',
  dataSource: [],
  loading: false
})

watch(
  () => analysisState.dataSource,
  () => {
    if (state.analysisType === 'session') {
      const chartDom = document.getElementById('device-session')
      const chartDomScatter = document.getElementById('device-session-scatter')
      const myChart = echarts.init(chartDom!)
      const chartDomScatterChart = echarts.init(chartDomScatter!)
      sessionEchartsJson.xAxis.data = analysisState.dataSource.map(item => item.createAt) as never[]
      sessionEchartsJson.series[0].data = analysisState.dataSource.map(item => item.sessionType === 'CONNECT' ? '上线' : '下线')

      let currentOption = scatterOption

      setInterval(function () {
        currentOption = currentOption === scatterOption ? barOption : scatterOption
        chartDomScatterChart.setOption(currentOption, true)
      }, 2000)

      chartDomScatterChart.setOption(currentOption)
      myChart.setOption(sessionEchartsJson)

      analysisState.loading = false
    } else {
      const chartDom = document.getElementById('device-attr')
      const myChart = echarts.init(chartDom!)

      attrEchartsJson.xAxis.data = analysisState.dataSource.map(item => item.keyLabel) || []
      attrEchartsJson.series[0].data = analysisState.dataSource.map(item => item.longValue) || []

      myChart.setOption(attrEchartsJson)
      analysisState.loading = false
    }
  }
)

const { resetFields, validate, validateInfos } = useForm(searchState, {})

const { resetFields: resetFieldsDevice, validate: validateDevice, validateInfos: validateInfosDeviceState } = useForm(deviceState, reactive({
  modelId: [{ required: true, message: '请选择所属产品' }],
  deviceCode: [{ required: true, message: '请填写设备码' }]
}))

const changeRangePicker = (time) => {
  const [startTime, endTime] = time
  console.log(startTime, endTime)

  analysisState.start = new Date(startTime).getTime()
  analysisState.end = new Date(endTime).getTime()
  state.analysisType === 'session' ? getDeviceSession() : getDeviceAttr()
}

const openAnalysisModal = (key: 'session' | 'attr', id: string) => {
  state.analysisVisible = true
  state.analysisType = key
  analysisState.deviceId = id
  key === 'session' ? getDeviceSession() : getDeviceAttr()
}

const changePage = ({ current }) => {
  searchState.page = current
  getDevicePage()
}

const goDebugPage = (id: string) => {
  router.push({ path: '/devOps/onlineTest', query: { id } })
}

const goDetailPage = (id: string) => {
  router.push({ path: '/device/detail', query: { id } })
}

const getDeviceSession = async () => {
  analysisState.loading = true
  const { data } = await DeviceContriller.getSession({ deviceId: analysisState.deviceId, start: analysisState.start, end: analysisState.end })
  analysisState.dataSource = data
}

const getDeviceAttr = async () => {
  analysisState.loading = true
  const { data } = await DeviceContriller.getAttr({ deviceId: analysisState.deviceId, start: analysisState.start, end: analysisState.end })
  analysisState.dataSource = data.hum
}

const delDevice = async (id: string) => {
  await DeviceContriller.del(id)
  getDevicePage()
}

const ok = () => {
  if (deviceState.deviceAuthType === DeviceAuthTypeEnum.SECRET && deviceState.deviceSecret !== deviceState.confirmSecret) {
    message.warn('两次密匙输入不同')
    return
  }
  validateDevice().then(async (r) => {
    await DeviceContriller.post(deviceState)
    state.visible = false
    getDevicePage()
  })
}

const getModelList = async () => {
  const { data } = await ModelController.list()
  state.modelList = data
}

const openModal = (opraState: 'add' | 'update', record:Partial<IOT.API.DEVICE.Device> = {}) => {
  state.visible = true
  state.opraState = opraState
  getModelList()
}

const getDevicePage = async () => {
  state.loading = true
  const { data, sum } = await DeviceContriller.page(searchState)
  state.loading = false
  state.dataSource = data
  searchState.total = sum
}

const getDeviceStatistics = async () => {
  const data = await DeviceContriller.statistics({ modelId: state.modelId })
  state.deviceCount = data as any
}

onMounted(() => {
  getDeviceStatistics()
  getDevicePage()
})

</script>

<style lang="less" scoped >
@import '~@/styles/theme.less';
.statistic {
  color: @sublabel-color;
  .count {
    font-size: 48px;
    margin-right: 10px;
  }
}
.label {
  font-size: 18px;
  color: @sublabel-color;
}
</style>
