<template>
  <a-row justify="end">
    <a-col  >
      <a-space>
        <a-button v-if="route.query.type === 'model'" type="primary" @click="openModel('attrVisible', 'add')" >新增属性</a-button>
      </a-space>
    </a-col>
  </a-row>
  <!-- 模型属性 -->
  <a-table
    style="margin-top: 10px;"
    :columns="columns"
    :dataSource="state.dataSource"
    :loading="state.loading"
    :pagination="state.queryParams"
  >
    <template #bodyCell="{column, record}">
      <template v-if="column.key === 'action'">
            <a-space>
                <a @click="openModel('attrVisible', 'update', record)">修改</a>
                <a-popconfirm
                  title="确实要删除吗？"
                  ok-text="确定"
                  cancel-text="取消"
                  @confirm="confirmDel('attr', record.id)"
                >
                  <a>删除</a>
                </a-popconfirm>
            </a-space>
          </template>
    </template>
  </a-table>

  <!-- 模型命令 -->
  <a-row style="margin-top: 20px;"  justify="end" >
    <a-col  >
      <a-space>
        <a-button v-if="route.query.type === 'model'" type="primary" @click="openModel('cmdVisible', 'add')" >新增命令</a-button>
      </a-space>
    </a-col>
  </a-row>
  <a-table
        style="margin-top: 10px;"
        :columns="columnsCmd"
        :dataSource="state.dataSourceCmd"
        :loading="state.loadingCmd"
        :pagination="state.queryParamsCmd"
      >
        <template #bodyCell="{column, record}">
          <template v-if="column.key === 'cmdParams'">
            <span>{{ record.cmdParams.map(item => item.paramLabel).join(',')}}</span>
          </template>
          <template v-if="column.key === 'cmdResponses'">
            <span>{{record.cmdResponses.map(item => item.paramLabel).join(',')}}</span>
          </template>
          <template v-if="column.key === 'action'">
                <a-space>
                    <a @click="openModel('cmdVisible', 'update', record)" >修改</a>
                    <a-popconfirm
                      v-if="record.canRemove"
                      title="确实要删除吗？"
                      ok-text="确定"
                      cancel-text="取消"
                      @confirm="confirmDel('cmd', record.id)"
                    >
                      <a>删除</a>
                </a-popconfirm>
              </a-space>
          </template>
        </template>
  </a-table>
  <a-modal
    :title="modalTitle"
    :open="state.attrVisible"
    @cancel="state.attrVisible = false"
    @ok="ok('attr')"
    ok-text="确定"
    cancel-text="取消"
  >
    <a-form :label-col="{span: 4}" :wrapper-col="{span: 14}" >
      <a-row>
        <a-col :span="12" >
          <a-form-item label="属性名称" :label-col="{span: 8}"  v-bind="validateInfos.attributeLabel" >
            <a-input allowClear v-model:value="attrRef.attributeLabel"  />
          </a-form-item>
        </a-col>
        <a-col :span="12" >
          <a-form-item label="属性key" :label-col="{span: 8}" v-bind="validateInfos.attributeKey" >
            <a-input  allowClear v-model:value="attrRef.attributeKey"  />
          </a-form-item>
        </a-col>
      </a-row>

      <a-form-item label="数据类型" v-bind="validateInfos.dataType" >
        <a-select allowClear v-model:value="attrRef.dataType" >
          <a-select-option :value="item" v-for="item in dataTypes" :key="item" >{{item}}</a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item label="访问权限" v-bind="validateInfos.scope" >
        <a-checkbox-group v-model:value="attrRef.scope" name="checkboxgroup" :options="[{label: '读', value: 'R'}, {label: '写', value: 'W'}]" />
      </a-form-item>
      <a-form-item label="单位" >
        <a-input allowClear v-model:value="attrRef.dataUnit"  />
      </a-form-item>
      <a-form-item label="计算表达式" >
        <a-input  allowClear v-model:value="attrRef.expr"  />
      </a-form-item>
    </a-form>
  </a-modal>

  <a-modal
    width="50%"
    :title="modalTitle"
    :open="state.cmdVisible"
    @cancel="state.cmdVisible = false"
    @ok="ok('cmd')"
    ok-text="确定"
    cancel-text="取消"
  >
    <a-form :label-col="{span: 4}" :wrapper-col="{span: 18}" >
      <a-form-item label="命令名称" v-bind="validateInfosCmd.attributeLabel" >
        <a-input allowClear v-model:value="cmdRef.cmdLabel"  />
      </a-form-item>
      <a-form-item label="下发参数">
        <a-row style="width: 100%;">
          <a-col :span="24" ><a-button type="link" @click="openModalCmdp('request', 'add')" >+ 新增输入参数</a-button></a-col>
          <a-col :span="24">
            <a-table
              :columns="columnsCmdParams"
              :dataSource="state.dataCmdParams.requestData"
            >
            <template #bodyCell="{column, record}">
              <template v-if="column.key === 'action'">
                    <a-space>
                        <a @click="openModalCmdp('request', 'update', record)">修改</a>
                        <a-popconfirm
                          title="确实要删除吗？"
                          ok-text="确定"
                          cancel-text="取消"
                          @confirm="delCmdParams('request', record.id)"
                        >
                          <a >删除</a>
                    </a-popconfirm>
                  </a-space>
              </template>
            </template>
          </a-table>
          </a-col>
        </a-row>
      </a-form-item>
      <a-form-item label="响应参数">
        <a-row style="width: 100%;">
          <a-col :span="24" ><a-button type="link" @click="openModalCmdp('response', 'add')" >+ 新增响应参数</a-button></a-col>
          <a-col :span="24">
            <a-table
              :columns="columnsCmdParams"
              :dataSource="state.dataCmdParams.responseData"
            >
            <template #bodyCell="{column, record}">
              <template v-if="column.key === 'action'">
                    <a-space>
                        <a @click="openModalCmdp('response', 'update', record)">修改</a>
                        <a-popconfirm
                          title="确实要删除吗？"
                          ok-text="确定"
                          cancel-text="取消"
                          @confirm="delCmdParams('response', record.id)"
                        >
                          <a >删除</a>
                    </a-popconfirm>
                  </a-space>
              </template>
            </template>
          </a-table>
          </a-col>
        </a-row>
      </a-form-item>
    </a-form>
  </a-modal>

  <a-modal
    title="新增参数"
    :open="state.cmdParamsvisible"
    @cancel="state.cmdParamsvisible = false"
    @ok="okCmdParams"
    ok-text="确定"
    cancel-text="取消"
  >
  <a-form :label-col="{span: 4}" :wrapper-col="{span: 18}" >
      <a-form-item label="参数名称" v-bind="validateInfosCmdP.paramLabel" >
        <a-input placeholder="请填写参数名称" v-model:value="cmdParamsRef.paramLabel"  />
      </a-form-item>
      <a-form-item label="数据类型" v-bind="validateInfosCmdP.dataType" >
        <a-select allowClear v-model:value="cmdParamsRef.dataType" >
          <a-select-option :value="item" v-for="item in dataTypes" :key="item" >{{item}}</a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item label="参数描述" v-bind="validateInfosCmdP.paramLabel" >
        <a-textarea placeholder="请填写参数描述" v-model:value="cmdParamsRef.description"  />
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<script lang="ts" setup >
import { ModelAttrController, ModelCmdController } from '@/controller/iot/index'
import { computed } from '@vue/reactivity'
import { nextTick, onMounted, reactive } from 'vue'
import { Form } from 'ant-design-vue'
import { useRoute } from 'vue-router'
import { useId } from '@/hooks'

const columns = [
  {
    title: '属性名称',
    key: 'attributeLabel',
    dataIndex: 'attributeLabel'
  },
  {
    title: '属性key',
    key: 'attributeKey',
    dataIndex: 'attributeKey'
  },
  {
    title: '数据类型',
    key: 'dataType',
    dataIndex: 'dataType'
  },
  {
    title: '数据单位',
    key: 'dataUnit',
    dataIndex: 'dataUnit'
  },
  {
    title: '权限',
    key: 'scope',
    dataIndex: 'scope'
  },
  {
    title: '表达式',
    key: 'expr',
    dataIndex: 'expr'
  },
  {
    title: '操作',
    key: 'action'
  }
]

const columnsCmd = [
  {
    title: '命令名称',
    key: 'cmdLabel',
    dataIndex: 'cmdLabel'
  },
  {
    title: '下发参数',
    key: 'cmdParams',
    dataIndex: 'cmdParams'
  },
  {
    title: '响应参数',
    key: 'cmdResponses',
    dataIndex: 'cmdResponses'
  },
  {
    title: '操作',
    key: 'action'
  }
]

const columnsCmdParams = [
  {
    title: '参数名称',
    key: 'paramLabel',
    dataIndex: 'paramLabel'
  },
  {
    title: '数据类型',
    key: 'dataType',
    dataIndex: 'dataType'
  },
  {
    title: '参数描述',
    key: 'description',
    dataIndex: 'description'
  },
  {
    title: '操作',
    key: 'action'
  }
]

const route = useRoute()

const modelId = route.query.id! as string

const useForm = Form.useForm

const dataTypes = ['STRING', 'LONG', 'BOOLEAN', 'DOUBLE', 'JSON']

const state = reactive<{
  dataSource: IOT.API.MODELATTR.ModelAttr[],
  dataSourceCmd: IOT.API.CMD.CMD[]
  [key: string]: any
}>({
  dataSource: [],
  loading: false,
  opraState: 'add',
  queryParams: {
    page: 1,
    pageSize: 10,
    modelId: '',
    total: 0
  },
  queryParamsCmd: {
    page: 1,
    pageSize: 10,
    modelId: '',
    total: 0
  },
  attrVisible: false,
  cmdVisible: false,
  cmdParamsvisible: false,
  cmdParamsOpraState: 'request',
  loadingCmd: false,
  dataSourceCmd: [],
  dataCmdParams: {
    requestData: [],
    responseData: []
  }
})

const attrRef = reactive({
  attributeLabel: '',
  dataType: '',
  dataUnit: '',
  scope: [],
  key: 'tem',
  expr: '',
  attributeKey: '',
  modelId: ''
})

const cmdRef = reactive({
  cmdLabel: '',
  cmdParams: [],
  cmdResponses: [],
  modelId: '',
  canRemove: false
})

const cmdParamsRef = reactive({
  id: '',
  paramLabel: '',
  description: '',
  dataType: ''
})

const { resetFields, validate: validateAttr, validateInfos } = useForm(attrRef, reactive({
  attributeLabel: [{ required: true, message: '请填写属性名称' }],
  attributeKey: [{ required: true, message: '请填写属性值' }],
  dataType: [{ required: true, message: '请选择数据类型' }],
  dataUnit: [{ required: true, message: '请填写数据单位' }]
}))

const { resetFields: resetFieldsCmd, validate: validateCmd, validateInfos: validateInfosCmd } = useForm(cmdRef, {
  cmdLabel: [{ require: true, message: '请填写模型命令' }]
})

const { resetFields: resetFieldsCmdP, validate: validateCmdP, validateInfos: validateInfosCmdP } = useForm(cmdParamsRef, {
  paramLabel: [{ require: true, message: '请填写参数名称' }],
  dataType: [{ require: true, message: '请选择数据类型' }]
})

const delCmdParams = (type: 'request' | 'response', id: string) => {
  const key = type === 'request' ? 'requestData' : 'responseData'
  const index = state.dataCmdParams[key].indexOf(id)
  state.dataCmdParams[key].splice(index, 1)
}

const openModalCmdp = (type: 'request' | 'response', opraState: 'add' | 'update', record: any = {}) => {
  state.cmdParamsOpraState = type
  state.cmdParamsvisible = true

  resetFieldsCmdP(record)
}

const okCmdParams = () => {
  validateCmdP().then(() => {
    console.log(cmdParamsRef)
    const key = state.cmdParamsOpraState === 'request' ? 'requestData' : 'responseData'
    console.log(state.dataCmdParams, key)

    const index = state.dataCmdParams[key].map(item => item.id).indexOf(cmdParamsRef.id)
    if (index >= 0) {
      state.dataCmdParams[key].splice(index, 1, { ...cmdParamsRef })
    } else {
      state.dataCmdParams[key].push({ ...cmdParamsRef, id: useId() })
    }

    nextTick(() => {
      resetFieldsCmdP({
        paramLabel: '',
        description: '',
        dataType: ''
      })
    })

    state.cmdParamsvisible = false
  })
}

const confirmDel = async (modalName: 'attr' | 'cmd', id: string) => {
  modalName === 'attr' ? await ModelAttrController.del(id) : await ModelCmdController.del(id)
  modalName === 'attr' ? getModelAttr() : getModelCmd()
}

const ok = (modalName: 'attr' | 'cmd') => {
  if (modalName === 'attr') {
    validateAttr().then(async () => {
      state.opraState === 'add'
        ? await ModelAttrController.post({ ...attrRef, scope: typeof attrRef.scope === 'string' ? attrRef.scope : attrRef.scope.join(''), modelId })
        : await ModelAttrController.update({ ...attrRef, scope: typeof attrRef.scope === 'string' ? attrRef.scope : attrRef.scope.join(''), modelId })
      state.cmdVisible = false
      state.attrVisible = false
      getModelAttr()
    })
  } else {
    validateCmd().then(async () => {
      cmdRef.cmdParams = state.dataCmdParams.requestData
      cmdRef.cmdResponses = state.dataCmdParams.responseData
      cmdRef.modelId = modelId
      state.opraState === 'add'
        ? await ModelCmdController.post(cmdRef)
        : await ModelCmdController.update(cmdRef)
      state.cmdVisible = false
      state.attrVisible = false
      getModelCmd()
    })
  }
}

const openModel = (key: string, opraState: 'add' | 'update', record: any = {}) => {
  state[key] = true
  state.opraState = opraState
  if (key === 'attrVisible') {
    resetFields(record)
  } else {
    resetFieldsCmd(record)
    if (!record.cmdParams) return
    state.dataCmdParams.requestData = record.cmdParams.map(item => {
      return {
        ...item,
        id: item.id ? item.id : useId()
      }
    }) || []
    state.dataCmdParams.responseData = record.cmdResponses.map(item => {
      return {
        ...item,
        id: item.id ? item.id : useId()
      }
    }) || []
  }
}

const getModelCmd = async () => {
  state.loadingCmd = true
  state.dataSourceCmd = []
  const { data, sum } = await ModelCmdController.page(state.queryParamsCmd)
  state.loadingCmd = false
  state.dataSourceCmd = data.map(item => {
    return {
      ...item,
      id: item.id ? item.id : useId()
    }
  })
  console.log('state.dataSourceCmd:', state.dataSourceCmd)

  state.queryParamsCmd.total = sum
}

const getModelAttr = async () => {
  state.loading = true
  state.dataSource = []
  const { data, sum } = await ModelAttrController.page(state.queryParams)
  console.log(data)

  state.loading = false
  state.dataSource = data.map(item => {
    return {
      ...item,
      id: item.attributeKey ? item.attributeKey : useId()
    }
  })
  state.queryParams.total = sum
}

onMounted(() => {
  state.queryParams.modelId = route.query.id
  state.queryParamsCmd.modelId = route.query.id
  getModelAttr()
  getModelCmd()
})

const modalTitle = computed(() => {
  const t1 = state.opraState === 'add' ? '新增' : '编辑'
  const t2 = state.attrVisible ? '属性' : '命令'
  return t1 + t2
})
</script>

<style>
</style>
