<template>
  <PageContainer v-if="!detailVisible" :pageHeaderRender="false" style="padding: 0 10px 10px 10px">
    <ProSearch :columns="searchFormSchema" target="device-instance" @search="handleSearch" />
    <FullPage style="min-height: calc(100vh - 186px)">
      <JTable
        ref="instanceRef"
        model="CARD"
        :columns="columns"
        :request="query"
        :defaultParams="{
          column: 'createTime',
          order: 'desc',
          pageSize: 9
        }"
        :rowSelection="
          isCheck
            ? {
                selectedRowKeys: _selectedRowKeys,
                onChange: onSelectChange
              }
            : false
        "
        :params="params"
      >
        <template #headerTitle>
          <Space>
            <PermissionButton type="primary" @click="handleAdd">
              <template #icon><JAIcon type="PlusOutlined" /></template>
              新增
            </PermissionButton>
          </Space>
        </template>
        <template #card="slotProps">
          <CardBox
            :value="slotProps"
            @click="handleClick"
            :actions="getActions(slotProps, 'card')"
            :active="_selectedRowKeys.includes(slotProps.id)"
            :status="slotProps.state?.value"
            :statusText="slotProps.state?.text"
            :statusNames="{
              online: 'processing',
              offline: 'error',
              notActive: 'warning'
            }"
          >
            <template #img>
              <img
                :width="80"
                :height="80"
                :src="slotProps?.photoUrl || getImage('/device/instance/device-card.png')"
                alt="device"
              />
            </template>
            <template #content>
              <Ellipsis style="width: calc(100% - 100px); margin-bottom: 18px">
                <span style="font-size: 16px; font-weight: 600">
                  {{ slotProps.name }}
                </span>
              </Ellipsis>
              <Row>
                <Col :span="12">
                  <div class="card-item-content-text"> 设备类型 </div>
                  <div>{{ slotProps.deviceType?.text }}</div>
                </Col>
                <Col :span="12">
                  <div class="card-item-content-text"> 产品名称 </div>
                  <Ellipsis style="width: 100%">
                    {{ slotProps.productName }}
                  </Ellipsis>
                </Col>
              </Row>
            </template>
            <template #actions="item">
              <PermissionButton
                :disabled="item.disabled"
                :popConfirm="item.popConfirm"
                :tooltip="{
                  ...item.tooltip
                }"
                @click="item.onClick"
              >
                <JAIcon type="DeleteOutlined" v-if="item.key === 'delete'" />
                <template v-else>
                  <JAIcon :type="item.icon" />
                  <span>{{ item?.text }}</span>
                </template>
              </PermissionButton>
            </template>
          </CardBox>
        </template>
        <template #state="slotProps">
          <BadgeStatus
            :status="slotProps.state?.value"
            :text="slotProps.state?.text"
            :statusNames="{
              online: 'processing',
              offline: 'error',
              notActive: 'warning'
            }"
          />
        </template>
        <template #createTime="slotProps">
          <span>{{ slotProps?.createTime ? dayjs(slotProps.createTime).format('YYYY-MM-DD HH:mm:ss') : '' }}</span>
        </template>
        <template #action="slotProps">
          <Space>
            <template v-for="i in getActions(slotProps, 'table')" :key="i.key">
              <PermissionButton
                :disabled="i.disabled"
                :popConfirm="i.popConfirm"
                :tooltip="{
                  ...i.tooltip
                }"
                @click="i.onClick"
                type="link"
                style="padding: 0 5px"
                :danger="i.key === 'delete'"
              >
                <template #icon><JAIcon :type="i.icon" /></template>
              </PermissionButton>
            </template>
          </Space>
        </template>
      </JTable>
    </FullPage>
  </PageContainer>
  <Import v-if="importVisible" @cancel="importVisible = false" @save="onRefresh" />
  <Export v-if="exportVisible" @close="exportVisible = false" :data="params" @save="onRefresh" />
  <Process
    v-if="operationVisible"
    @close="operationVisible = false"
    :api="api"
    :type="type"
    :data="params"
    @save="onRefresh"
  />
  <Save v-if="visible" :data="current" @close="visible = false" @save="saveBtn" />
  <Detail v-if="detailVisible" :id="deviceId" />
</template>

<script setup lang="ts">
  import { onMounted } from 'vue';
  import { query, _delete, _deploy, _undeploy, batchUndeployDevice, batchDeleteDevice } from '../../../api/device/instance';
  import { getImage, BASE_API_PATH, accessConfigTypeFilter, TOKEN_KEY, LocalStore, onlyMessage } from '@jdlinker/utils';
  import Import from './Import/modal.vue';
  import Export from './Export/index.vue';
  import Process from './Process/index.vue';
  import Save from './Save/index.vue';
  import { getProviders, queryGatewayList, queryNoPagingPost, queryOrgThree } from '../../../api/device/product';
  import { queryTree } from '../../../api/device/category';
  import type { ActionsType } from './typings';
  import dayjs from 'dayjs';
  import { nextTick, provide, ref } from 'vue';
  import Detail from './Detail/index.vue';
  import JTable from '../../../components/UI/Table/index';
  import { FormSchema, JSearch as ProSearch, FullPage, PermissionButton, CardBox, BadgeStatus } from '@jdlinker/ui';
  import { PageContainer, AIcon as JAIcon, Row, Col, Ellipsis, Space } from 'linker-ui-components';

  const instanceRef = ref<Record<string, any>>({});
  const deviceId = ref('');
  const params = ref<Record<string, any>>({});
  const _selectedRowKeys = ref<string[]>([]);
  const importVisible = ref<boolean>(false);
  const exportVisible = ref<boolean>(false);
  const detailVisible = ref<boolean>(false);
  const visible = ref<boolean>(false);
  const current = ref<Record<string, any>>({});
  const operationVisible = ref<boolean>(false);
  const api = ref<string>('');
  const type = ref<string>('');
  const isCheck = ref<boolean>(false);

  const transformData = (arr: any[]): any[] => {
    if (Array.isArray(arr) && arr.length) {
      return (arr || []).map((item: any) => {
        return {
          ...item,
          id: `classifiedId is ${item.id}`,
          children: transformData(item.children)
        };
      });
    } else {
      return [];
    }
  };
  const searchFormSchema: FormSchema[] = [
    {
      label: '设备名称',
      field: 'name',
      component: 'Input'
    },
    {
      label: '产品名称',
      field: 'productName',
      component: 'Input'
    },
    {
      label: '状态',
      field: 'stateExpand',
      component: 'Select',
      componentProps: {
        options: [
          { label: '禁用', value: 'notActive' },
          { label: '离线', value: 'offline' },
          { label: '在线', value: 'online' }
        ]
      }
    }
  ];
  const columns = [
    {
      title: 'ID',
      dataIndex: 'id',
      key: 'id',
      ellipsis: true,
      align: 'center',
      search: {
        type: 'string',
        defaultTermType: 'eq'
      }
    },
    {
      title: '设备名称',
      dataIndex: 'name',
      key: 'name',
      ellipsis: true,
      align: 'center',
      search: {
        type: 'string',
        first: true
      }
    },
    {
      title: '产品名称',
      dataIndex: 'productName',
      key: 'productName',
      ellipsis: true,
      align: 'center',
      search: {
        type: 'select',
        rename: 'productId',
        options: () =>
          new Promise((resolve) => {
            queryNoPagingPost({ paging: false }).then((resp: any) => {
              resolve(
                resp.result.map((item: any) => ({
                  label: item.name,
                  value: item.id
                }))
              );
            });
          })
      }
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      key: 'createTime',
      scopedSlots: true,
      align: 'center',
      width: 200,
      search: {
        type: 'date'
      }
    },
    {
      title: '状态',
      dataIndex: 'state',
      key: 'state',
      scopedSlots: true,
      align: 'center',
      search: {
        type: 'select',
        options: [
          { label: '禁用', value: 'notActive' },
          { label: '离线', value: 'offline' },
          { label: '在线', value: 'online' }
        ]
      }
    },
    {
      key: 'classifiedId',
      dataIndex: 'classifiedId',
      title: '产品分类',
      hideInTable: true,
      search: {
        type: 'treeSelect',
        // rename: 'productId$product-info',
        options: () =>
          new Promise((resolve) => {
            queryTree({ paging: false }).then((resp: any) => {
              resolve(transformData(resp.result));
            });
          })
      }
    },
    {
      key: 'accessProvider',
      title: '网关类型',
      dataIndex: 'accessProvider',
      valueType: 'select',
      hideInTable: true,
      search: {
        type: 'select',
        // rename: 'productId$product-info',
        options: () =>
          new Promise((resolve) => {
            getProviders().then((resp: any) => {
              const data = resp.result || [];
              resolve(
                accessConfigTypeFilter(data).map((item) => ({
                  ...item,
                  value: `accessProvider is ${item.id}`
                }))
              );
            });
          })
      }
    },
    {
      key: 'accessId',
      dataIndex: 'accessId',
      title: '接入方式',
      hideInTable: true,
      search: {
        type: 'select',
        options: () =>
          new Promise((resolve) => {
            queryGatewayList({}).then((resp: any) => {
              resolve(
                resp.result.map((item: any) => ({
                  label: item.name,
                  value: `accessId is ${item.id}`
                }))
              );
            });
          })
      }
    },
    {
      dataIndex: 'deviceType',
      title: '设备类型',
      valueType: 'select',
      hideInTable: true,
      search: {
        type: 'select',
        options: [
          { label: '直连设备', value: 'device' },
          { label: '网关子设备', value: 'childrenDevice' },
          { label: '网关设备', value: 'gateway' }
        ]
      }
    },
    {
      dataIndex: 'id$dim-assets',
      title: '所属组织',
      hideInTable: true,
      search: {
        type: 'treeSelect',
        options: () =>
          new Promise((resolve) => {
            queryOrgThree({}).then((resp: any) => {
              const formatValue = (list: any[]) => {
                const _list: any[] = [];
                list.forEach((item) => {
                  if (item.children) {
                    item.children = formatValue(item.children);
                  }
                  _list.push({
                    ...item,
                    id: JSON.stringify({
                      assetType: 'device',
                      targets: [
                        {
                          type: 'org',
                          id: item.id
                        }
                      ]
                    })
                  });
                });
                return _list;
              };
              resolve(formatValue(resp.result));
            });
          })
      }
    },
    {
      title: '操作',
      key: 'action',
      align: 'center',
      fixed: 'true',
      width: 200,
      scopedSlots: true
    }
  ];

  const paramsFormat = (config: Record<string, any>, _terms: Record<string, any>, name?: string) => {
    if (config?.terms && Array.isArray(config.terms) && config?.terms.length > 0) {
      (config?.terms || []).map((item: Record<string, any>, index: number) => {
        if (item?.type) {
          _terms[`${name ? `${name}.` : ''}terms[${index}].type`] = item.type;
        }
        paramsFormat(item, _terms, `${name ? `${name}.` : ''}terms[${index}]`);
      });
    } else if (!config?.terms && Object.keys(config).length > 0) {
      Object.keys(config).forEach((key) => {
        if (config[key]) {
          _terms[`${name ? `${name}.` : ''}${key}`] = config[key];
        }
      });
    }
  };

  onMounted(() => {
    // if (routerParams.params.value.type === 'add') {
    //     handleAdd();
    // }
    // if (routerParams.params.value.type === 'import') {
    //     importVisible.value = true;
    // }
  });

  const handleParams = (config: Record<string, any>) => {
    const _terms: Record<string, any> = {};
    paramsFormat(config, _terms);
    if (Object.keys(_terms).length) {
      const url = new URLSearchParams();
      Object.keys(_terms).forEach((key) => {
        console.log(_terms[key]);
        url.append(key, _terms[key]);
      });
      return url.toString();
    } else {
      return '';
    }
  };

  /**
   * 新增
   */
  const handleAdd = () => {
    visible.value = true;
    current.value = {};
  };

  /**
   * 查看
   */
  const handleView = (id: string) => {
    detailVisible.value = true;
    deviceId.value = id;
  };

  const getActions = (data: Partial<Record<string, any>>, type: 'card' | 'table'): ActionsType[] => {
    if (!data) return [];
    const actions = [
      {
        key: 'view',
        text: '查看',
        tooltip: {
          title: '查看'
        },
        icon: 'EyeOutlined',
        onClick: () => {
          handleView(data.id);
        }
      },
      {
        key: 'update',
        text: '编辑',
        tooltip: {
          title: '编辑'
        },
        icon: 'EditOutlined',
        onClick: () => {
          visible.value = true;
          current.value = data;
        }
      },
      {
        key: 'action',
        text: data.state?.value !== 'notActive' ? '禁用' : '启用',
        tooltip: {
          title: data.state?.value !== 'notActive' ? '禁用' : '启用'
        },
        icon: data.state.value !== 'notActive' ? 'StopOutlined' : 'CheckCircleOutlined',
        popConfirm: {
          title: `确认${data.state.value !== 'notActive' ? '禁用' : '启用'}?`,
          onConfirm: async () => {
            let response = undefined;
            if (data.state.value !== 'notActive') {
              response = await _undeploy(data.id);
            } else {
              response = await _deploy(data.id);
            }
            if (response) {
              onlyMessage('操作成功！', 'success');
              instanceRef.value?.reload();
            } else {
              onlyMessage('操作失败！', 'error');
            }
          }
        }
      },
      {
        key: 'delete',
        text: '删除',
        disabled: data.state?.value !== 'notActive',
        tooltip: {
          title: data.state.value !== 'notActive' ? '已启用的设备不能删除' : '删除'
        },
        popConfirm: {
          title: '确认删除?',
          onConfirm: async () => {
            const resp = await _delete(data.id);
            if (resp) {
              onlyMessage('操作成功！', 'success');
              instanceRef.value?.reload();
            } else {
              onlyMessage('操作失败！', 'error');
            }
          }
        },
        icon: 'DeleteOutlined'
      }
    ];
    if (type === 'card') return actions.filter((i: ActionsType) => i.key !== 'view');
    return actions;
  };

  const onSelectChange = (keys: string[]) => {
    _selectedRowKeys.value = [...keys];
  };

  const handleClick = (dt: any) => {
    if (isCheck.value) {
      if (_selectedRowKeys.value.includes(dt.id)) {
        const _index = _selectedRowKeys.value.findIndex((i) => i === dt.id);
        _selectedRowKeys.value.splice(_index, 1);
      } else {
        _selectedRowKeys.value = [..._selectedRowKeys.value, dt.id];
      }
    } else {
      handleView(dt.id);
    }
  };

  const onCheckChange = () => {
    _selectedRowKeys.value = [];
  };

  const handleGetParams = (p: any) => {
    p?.terms.map((a: any) => {
      return a.terms.map((b: any) => {
        if (b.column.includes('$product-info')) {
          b.column = 'productId';
          b.termType = 'product-info';
        }
        return b;
      });
    });
    return p;
  };

  const activeAllDevice = () => {
    type.value = 'active';
    const activeAPI = `${BASE_API_PATH}/device-instance/deploy?:X_Access_Token=${LocalStore.get(
      TOKEN_KEY
    )}&${handleParams(handleGetParams(params.value))}`;
    api.value = activeAPI;
    operationVisible.value = true;
  };

  const syncDeviceStatus = () => {
    type.value = 'sync';
    const syncAPI = `${BASE_API_PATH}/device-instance/state/_sync?:X_Access_Token=${LocalStore.get(
      TOKEN_KEY
    )}&${handleParams(params.value)}`;
    api.value = syncAPI;
    operationVisible.value = true;
  };

  const delSelectedDevice = async () => {
    if (!_selectedRowKeys.value.length) {
      onlyMessage('请选择设备', 'error');
      return;
    }
    const resp = await batchDeleteDevice(_selectedRowKeys.value);
    if (resp.code === 200) {
      onlyMessage('操作成功！', 'success');
      _selectedRowKeys.value = [];
      instanceRef.value?.reload();
    }
  };

  // const activeSelectedDevice = async () => {
  //     if(!_selectedRowKeys.value.length){
  //         message.error('请选择设备')
  //         return
  //     }
  //     const resp = await batchDeployDevice(_selectedRowKeys.value);
  //     if (resp.code === 200) {
  //         message.success('操作成功！');
  //         _selectedRowKeys.value = [];
  //         instanceRef.value?.reload();
  //     }
  // };

  const disabledSelectedDevice = async () => {
    if (!_selectedRowKeys.value.length) {
      onlyMessage('请选择设备', 'error');
      return;
    }
    const resp = await batchUndeployDevice(_selectedRowKeys.value);
    if (resp.code === 200) {
      onlyMessage('操作成功！', 'success');
      _selectedRowKeys.value = [];
      instanceRef.value?.reload();
    }
  };

  const saveBtn = () => {
    visible.value = false;
    instanceRef.value?.reload();
  };

  const handleSearch = (_params: any) => {
    params.value = _params;
    // const newParams = (_params?.terms as any[])?.map((item1) => {
    //     item1.terms = item1.terms.map((item2: any) => {
    //         if (
    //             item2.column &&
    //             ['classifiedId', 'accessId', 'accessProvider'].includes(
    //                 item2.column,
    //             )
    //         ) {
    //             return {
    //                 ...item2,
    //                 column: 'productId$product-info',
    //             };
    //         }
    //         return item2;
    //     });
    //     return item1;
    // });
    // params.value = { terms: newParams || [] };
  };

  const onRefresh = () => {
    instanceRef.value?.reload();
  };

  const goBack = () => {
    detailVisible.value = true;
    nextTick(() => {
      detailVisible.value = false;
    });
  };
  provide('goBack', goBack);
</script>
<style lang="less" scoped>
  .deviceImg {
    width: 80px;
    height: 80px;
  }
  :deep(.card .card-warp .card-content) {
    padding: 24px 12px 24px 30px;
  }
  :deep(.jtable-card) {
    min-height: 597px;
  }
  :deep(.ant-pagination-options) {
    display: none;
  }
</style>
