<template>
 <a-row :gutter="[8, 8]" >
  <a-col :lg="5" :md="10" :xs="24">
    <a-card style="height: 100%;" >
      <template #title >
        <a-row justify="space-between" align="middle" >
          <a-col><a-button type="primary" @click="addDevicegroup">+ 添加根设备群组</a-button></a-col>
          <a-col><ReloadIconTsx :loading="state.groupLoading" :@reload="getDeviceGroup"/></a-col>
        </a-row>
      </template>
      <a-spin :spinning="state.groupLoading" >
        <a-tree
        v-model:expandedKeys="expandedKeys"
        v-model:selectedKeys="state.treeActiveKey"
        :tree-data="state.groupTreeData"
        defaultExpandAll
        autoExpandParent
        :field-names="{
          key: 'id',
          title: 'groupLabel',
        }"
      >
        <template #title="record">
          <a-space @click="changeTreeActiveKey(record.key)" >
            <div class="group-label" > {{ record.groupLabel }} </div>
            <template v-if="state.treeActiveKey[0] === record.key && record.key" >
              <plus-circle-outlined @click="openGroupModal('add', record)"/>
              <delete-outlined @click="openGroupModal('del', record)"/>
            </template>
          </a-space>
        </template>
      </a-tree>
      </a-spin>
    </a-card>
  </a-col>
  <a-col :lg="19" :md="14" :xs="24">
    <a-card style="height: 100%;" >
      <span v-if="!state.treeActiveKey" >
        <a-row justify="space-between" >
          <a-col>
            <a-space>
              <a-select
              allowClear
                style="width: 170px;"
                v-model:value="state.queryParams.modelId"
              >
                <a-select-option
                  v-for="item in state.modelList"
                  :key="item.id"
                  :value="item.id"
                >
                {{ item.modelLabel }}
                </a-select-option>
              </a-select>
              <a-select
              allowClear
                v-model:value="state.queryParams.searchKey"
                style="width: 170px;"
              >
                <a-select-option
                  v-for="item in searchKeys"
                  :key="item.key"
                  :value="item.key"
                >
                {{ item.name }}
                </a-select-option>
              </a-select>
              <a-input-search placeholder="查询" allowClear     enter-button  @search="getDevicePage" ></a-input-search>
            </a-space>
          </a-col>
          <a-col><ReloadIconTsx  :loading="state.loading" :reload="getDevicePage"/></a-col>
        </a-row>
          <a-table
            style="margin-top: 20px;"
            :loading="state.loading"
            :columns="columns"
            :data-source="state.groupDateSource"
            :pagination="state.queryParams"
            @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>
        </a-table>
      </span>
      <span v-else  :key="selectGroup?.id">
        <a-row  >
        <a-col :span="24" >
          <div style="font-size: 18px;font-weight: 500" >群组名称:{{state.selectGroup?.groupLabel}}</div>
        </a-col>
      </a-row>
      <a-card
        title="绑定设备"
        :bordered="false"
        :headStyle="{border: 'none', padding: '0px'}"
      >
        <a-row justify="end" >
          <a-col>
            <a-space>
              <a-button @click="delBind([])" >批量解绑</a-button>
              <a-button @click="state.drawerVisible = true" >绑定</a-button>
              <a-button @click="getDeviceByGroup" > 刷新</a-button>
            </a-space>
          </a-col>
        </a-row>
        <div style="margin-bottom: 10px;" >已选择 {{state.selectedRowKeys.length}} 个设备， 一次最多可批量解绑100个设备。</div>
        <a-table
          :rowKey="record => record.id"
          :columns="groupDeviceColumns"
          :loading='state.tableLoading'
          :data-source="state.groupDeviceDataSource"
          :row-selection="{
            selectedRowKeys: state.selectedRowKeys,
            onChange: onSelectChange,
          }"
        >
          <template  #bodyCell="{column, record}" >
            <template v-if="column.key === 'id'" >
              <a @click="goDetailPage(record.id)">{{record.id}}</a>
            </template>
            <template v-if="column.key === 'action'" >
              <a-space>
                <a >详情</a>
                <a-popconfirm
                  title="确实要取消绑定吗？"
                  ok-text="确定"
                  cancel-text="取消"
                  @confirm="delBind([record.id])"
                >
                  <a>解绑</a>
                </a-popconfirm>
              </a-space>
            </template>
          </template>
        </a-table>
      </a-card>
      </span>
    </a-card>
  </a-col>
 </a-row>

 <!-- 绑定设备抽屉 -->
 <a-drawer
    v-model:open="state.drawerVisible"
    size="large"
    class="custom-class"
    title="绑定设备"
    placement="right"
    @after-visible-change="afterVisibleChange"
  >
   <a-alert message="一个设备最多可以被添加到10个设备组中。" type="info" show-icon />
   <a-row>
    <a-col>
      <a-space  style="margin-top: 20px;">
        <a-select allowClear style="width: 100px;"  v-model:value="state.queryParams.searchKey">
          <a-select-option v-for="item in searchKeys.concat({name: '产品', key: 'modelId'})" :key="item.key" :value="item.key" >{{item.name}}</a-select-option>
        </a-select>
        <a-input  allowClear v-if="state.queryParams.searchKey !== 'modelId'"  v-model:value="state.queryParams.searchValue"  ></a-input>
        <a-select allowClear v-else style="width: 170px;" v-model:value="state.queryParams.searchValue"   >
                <a-select-option
                  v-for="item in state.modelList"
                  :key="item.id"
                  :value="item.id"
                >
                {{ item.modelLabel }}
                </a-select-option>
        </a-select>
        <a-button @click="getDevicePage" > 搜索</a-button>
      </a-space>
    </a-col>
    <a-col>
      <a-table
          :rowKey="record => record.id"
          style="margin-top: 10px;width: 688px;"
          :loading="state.tableLoading"
          :columns="groupDeviceColumns"
          :data-source="state.groupDateSource"
          :row-selection="{
            selectedRowKeys: state.selectedRowKeys,
            onChange: onSelectChange,
          }"
        >
          <template #bodyCell="{column, record}">
            <template v-if="column.key === 'deviceStatus'" >
            <a-tag :color="record.deviceStatus.color" >{{record.deviceStatus.name}}</a-tag>
          </template>
            <template v-if="column.key === 'deviceNodeType'" >
            {{record.deviceNodeType == 'GATEWAY' ? '直连类型' : '非直连类型' }}
          </template>
        </template>
        </a-table>
    </a-col>
   </a-row>

   <template #footer >
    <a-row justify="end" >
      <a-col>
        <a-space>
          <a-button type="primary" @click="bindDevice"> 绑定</a-button>
          <a-button @click="state.drawerVisible = false" > 取消</a-button>
        </a-space>
      </a-col>
    </a-row>
   </template>
  </a-drawer>

  <!-- 添加根设备群组 -->
  <modal-pro
    :title="state.groupOpra === 'add' ? '添加设备群组' : '删除设备群组'"
    :open="state.groupModalVisible"
    @cancel="state.groupModalVisible = false"
    @ok="ok"
  >

    <a-form v-if="state.groupOpra === 'add'" :label-col="{span: 6}" :wrapper-col="{span: 16}" >
      <a-form-item label="父级群组名称" v-if="groupState.upperGroupId" >
        <a-input allowClear disabled  :value="groupState.upperGroupLabel" ></a-input>
      </a-form-item>
      <a-form-item label="分组名"  v-bind="validateInfos.groupLabel" >
        <a-input allowClear v-model:value="groupState.groupLabel" ></a-input>
      </a-form-item>
    </a-form>
    <a-row v-else >
      <a-col>
        <a-alert style="width: 472px;" v-if="!state.selectTree.hasChildren " message="你确定要删除此群组吗？" type="info" show-icon />
        <a-alert style="width: 472px;" v-else message="此群组下已创建子群组，不能直接被删除。如要继续，请先审视并删除子群组，再重试删除。" type="error" show-icon />
      </a-col>
    </a-row>
  </modal-pro>
</template>

<script lang="ts" setup >
import { ReloadIconTsx } from '@/components/MicroComponents/index'
import { DeviceContriller, ModelController } from '@/controller'
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { PlusCircleOutlined, DeleteOutlined } from '@ant-design/icons-vue'
import { Form, Tag } from 'ant-design-vue'
import { useRouter } from 'vue-router'

const router = useRouter()

const useForm = Form.useForm

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

const columns = [

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

const groupDeviceColumns = [
  {
    title: '设备ID',
    dataIndex: 'id',
    key: 'id'
  },
  {
    title: '设备名称',
    dataIndex: 'deviceLabel'
  },
  {
    title: '设备标识码',
    dataIndex: 'deviceCode'
  },
  {
    title: '所属产品',
    dataIndex: 'modelLabel'
  },
  {
    title: '操作',
    dataIndex: 'action',
    key: 'action'
  }
]

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

interface TreeNode {
    id: string;
    createAt: number;
    updateAt: number | null;
    deleted: boolean;
    groupLabel: string;
    upperGroupId: string;
    tenantId: string;
    children?: TreeNode[];
}

function findParentNodeById (id: number, tree: any[]): any {
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i]
    if (node.id === id) {
      return node
    } else if (node.children) {
      const parentNode = findParentNodeById(id, node.children)
      if (parentNode) {
        return parentNode
      }
    }
  }
  return null
}

function buildTree (data: TreeNode[], upperGroupId: string): TreeNode[] {
  const tree: TreeNode[] = []
  for (const node of data) {
    if (node.upperGroupId === upperGroupId) {
      const children = buildTree(data, node.id)
      if (children.length) {
        node.children = children
      }
      tree.push({
        ...node,
        key: node.id,
        hasChildren: !!node.children?.length
      })
    }
  }
  return tree
}

const expandedKeys = ref<string[]>([])
const selectedKeys = ref<string[]>([''])

const selectGroup = computed(() => state.groupData.find(item => item.id === state.treeActiveKey))

const deviceState = reactive({
  dataSource: [],
  qeuryParams: {
    searchKey: 'deviceLabel',
    searchValue: '',
    modelId: '',
    page: 1,
    pageSize: 10,
    total: 0
  }
})

const state = reactive<{
  selectTree: Record<string, any>,
  treeActiveKey: string
  groupData: IOT.API.DEVICE.Group[],
  groupTreeData: any,
  groupLoading: boolean,
  groupDateSource: IOT.API.DEVICE.Device[],
  modelList: IOT.API.MODEL.ModelDot[],
  groupDeviceDataSource: IOT.API.DEVICE.Device[]
  queryParams: any,
  loading: boolean,
  tableLoading: boolean
  drawerVisible: boolean
  selectedRowKeys: string[],
  groupModalVisible: boolean,
  groupOpra: 'add' | 'del',
  selectGroup: Partial<IOT.API.DEVICE.Device>
}>({
  groupTreeData: [],
  groupData: [],
  groupOpra: 'add',
  groupLoading: false,
  groupDateSource: [],
  groupDeviceDataSource: [],
  treeActiveKey: '',
  selectTree: {},
  loading: false,
  tableLoading: false,
  groupModalVisible: false,
  selectGroup: {},
  drawerVisible: false,
  modelList: [],
  selectedRowKeys: [],
  queryParams: {
    page: 1,
    pageSize: 10,
    total: 0,
    modelId: '',
    searchKey: 'deviceLabel',
    searchValue: ''
  }
})

const groupState = reactive({
  groupLabel: '',
  upperGroupLabel: '',
  upperGroupId: ''
})

const { resetFields, validate, validateInfos } = useForm(groupState, reactive({
  groupLabel: [{ required: true, message: '请填写分组名称' }]
}))

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

const delBind = async (ids: []) => {
  const params = (ids.length ? ids : state.selectedRowKeys).map(item => {
    return {
      deviceGroupId: state.treeActiveKey[0],
      deviceId: item
    }
  })
  await DeviceContriller.delGroupBindDevice(params)
  state.selectedRowKeys = []
  getDeviceByGroup()
}

const bindDevice = async () => {
  const params = state.selectedRowKeys.map(item => {
    return {
      deviceId: item,
      deviceGroupId: state.treeActiveKey[0]
    }
  })
  console.log('params:', params)

  await DeviceContriller.postGroupBindDevice(params)
  state.drawerVisible = false
  state.selectedRowKeys = []
  getDeviceByGroup()
}

const ok = () => {
  if (state.groupOpra === 'add') {
    validate().then(async () => {
      await DeviceContriller.postDeviceGroup(groupState)
      state.groupModalVisible = false
      getDeviceGroup()
    })
  } else {
    if (state.selectTree.hasChildren) {
      state.groupModalVisible = false
    } else {
      console.log('删除设备群组')
      state.groupModalVisible = false
      // await DeviceContriller.dle
    }
  }
}

const onSelectChange = (rowKeys: string[]) => {
  console.log('rowKeys:', rowKeys)
  state.selectedRowKeys = rowKeys
}

const openGroupModal = (opra: 'add' | 'del', record: any = {}) => {
  groupState.upperGroupLabel = ''
  groupState.upperGroupId = ''
  groupState.groupLabel = ''

  state.selectTree = record

  state.groupModalVisible = true
  state.groupOpra = opra

  groupState.upperGroupLabel = record.groupLabel
  groupState.upperGroupId = record.id

  console.log(findParentNodeById(record.upperGroupId, state.groupTreeData))
}

const changeTreeActiveKey = (id: string, e?: TouchEvent) => {
  e && e.stopPropagation && e.stopPropagation()
  state.treeActiveKey = id
  console.log(state.treeActiveKey)
  getDeviceByGroup()
  state.selectGroup = state.groupData.find(item => item.id === state.treeActiveKey)
}

const addDevicegroup = (e: TouchEvent) => {
  e.stopPropagation()
  state.groupModalVisible = true
}

const getDeviceByGroup = async () => {
  state.tableLoading = true
  console.log('state.treeActiveKey:', state.treeActiveKey)

  const { data, sum } = await DeviceContriller.getDeviceByGroup({
    page: 1,
    pageSize: 200,
    deviceGroupId: typeof state.treeActiveKey === 'object' ? state.treeActiveKey[0] : state.treeActiveKey
  })
  state.tableLoading = false
  state.groupDeviceDataSource = data
}

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

const getModelList = async () => {
  const { data } = await ModelController.list()
  state.modelList = data.concat({ modelLabel: '所有产品', id: '' })
}

const getDeviceGroup = async () => {
  state.groupLoading = true
  const { data } = await DeviceContriller.listDeviceGroup({ upperGroupId: '' })

  state.groupTreeData = [
    {
      groupLabel: '所有分组',
      key: '',
      id: '',
      children: buildTree(data, '0')
    }
  ]
  state.groupData = data
  state.groupLoading = false
  console.log('expand:', state.groupTreeData[0].children.map(item => item.id))

  expandedKeys.value = state.groupTreeData[0].children.map(item => item.id)
}

onMounted(() => {
  getModelList()
  getDeviceGroup()
  getDevicePage()
})

</script>

<style lang="less" scoped >
.group-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
