<template>
  <tf-dialog
    v-bind="$attrs"
    v-on="listeners"
    @submit="onSubmit"
    @closed="onClosed"
    @open="onOpen"
    :loading="loading"
    width="896px"
  >
    <tf-title>监测站点基本信息</tf-title>
    <BasisForm ref="basis" v-model="formData.basis" :enable="enable" :labelWidth="labelWidth" @mapClick="mapClick" />
    <tf-title>关联排水设施信息</tf-title>
    <ConnectForm ref="connect" v-model="formData.connect" :labelWidth="labelWidth" @click="mapSelect" />
    <tf-title>设备安装信息</tf-title>
    <DeviceForm ref="device" v-model="formData.device" :types="types" :labelWidth="labelWidth" />
    <tf-title>设备监测指标</tf-title>
    <ThresholdForm
      ref="threshold"
      v-model="formData.threshold"
      :standards="standards"
      :labelWidth="labelWidth"
      :typeId="typeId"
      :levels="levels"
      :disabled="data && !!data.id"
    />
  </tf-dialog>
</template>

<script lang="ts">
  import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
  import BasisForm from './BasisForm.vue'
  import ConnectForm from './ConnectForm.vue'
  import DeviceForm from './DeviceForm.vue'
  import ThresholdForm from './ThresholdForm.vue'
  import { IDeviceType, IPointDetail, IStandard, IPoint, IPointDetailResult } from '../../api/common'
  import { standardPage } from '../../api/standard'
  import { getDetail } from '../../api/point'
  import { IOriginalDictionary } from '@/api/common'
  import moment from 'moment'
  import PipeQueryHelper from '@/utils/mapCommon/PipeQueryHelper'
  import { CesiumToSuperMap } from '@/utils/mapCommon/tools'
  import pipeConfig from '@/views/widgets/PipeUnitInfo/config.json'
  import { ElUploadInternalFileDetail } from 'element-ui/types/upload'
  import { getRemoteFile } from '@/api/ftp'

  interface IFormData {
    basis: {
      siteCode: string
      siteName: string
      sectionId: number
      siteAddress: string
      latitude: string
      longitude: string
      [x: string]: any
    }
    connect: {
      drainageId: number
      drainageName: string
      drainageRoadName: string
      drainageType: string
      longitude2: number
      latitude2: number
      layerName: string
    }
    device: {
      typeId: number
      install: Partial<IPointDetailResult['installVo']>
      fileList: Partial<ElUploadInternalFileDetail>[]
    }
    threshold: {
      standardId: number
      items: Partial<IPointDetailResult['targetVos']>
    }
  }

  const getDefaultFormData = () => ({
    basis: {
      /** 站点编号 */
      siteCode: undefined,
      /** 站点名称 */
      siteName: undefined,
      /** 断面Id */
      sectionId: undefined,
      /** 站点地址 */
      siteAddress: undefined,
      /** 纬度 */
      latitude: undefined,
      /** 经度 */
      longitude: undefined
    },

    connect: {
      /** 排水设施ID */
      drainageId: undefined,
      /** 排水设施名称 */
      drainageName: undefined,
      /** 排水设施所在道路名称 */
      drainageRoadName: undefined,
      /** 排水类型 */
      drainageType: undefined,
      /** 排水设施经度 */
      longitude2: undefined,
      /** 排水设施纬度 */
      latitude2: undefined,
      /** 排水设施所在图层名称 */
      layerName: undefined
    },

    // project: {
    //   /** 项目编码 */
    //   projectCode: undefined,
    //   /** 项目ID */
    //   projectId: undefined,
    //   /** 项目名称 */
    //   projectName: undefined
    // },

    device: {
      /** 设备类型ID */
      typeId: undefined,
      /** 设备安装信息 */
      install: {
        /** 设备ID */
        deviceId: undefined,
        /** 文件所属项目类型 */
        fileTypeID: 123,
        /** 安装人 */
        installPeople: undefined,
        /** 安装时间 */
        installTime: undefined,
        /** 联系人电话 */
        liaisonPhone: undefined,
        /** 关联状态0未启用,1启用（启用后不允许修改） */
        relevancyState: undefined,
        /** 站点ID */
        siteId: undefined
      },
      fileList: []
    },
    /** 指标阈值列表 */
    threshold: {
      standardId: undefined,
      items: []
    }
  })
  const getDefaultEnableValue = () => ({ coordinate: false, device: false })

  @Component({
    name: 'PointForm',
    components: { BasisForm, ConnectForm, DeviceForm, ThresholdForm }
  })
  export default class PointForm extends Vue {
    @Prop({ type: Object, default: () => ({}) }) data!: IPoint
    @Prop({ type: Boolean, default: false }) loading!: boolean
    @Prop({ type: Array, default: () => [] }) types!: IDeviceType[]
    @Prop({ type: Array, default: () => ({}) }) levels!: IOriginalDictionary[]

    $refs!: {
      basis: BasisForm
      connect: ConnectForm
      device: DeviceForm
      threshold: ThresholdForm
    }

    formData: Partial<IFormData> = getDefaultFormData()

    enable = getDefaultEnableValue()
    standards: IStandard[] = []
    labelWidth = 'auto'
    keys = ['basis', 'connect', 'device', 'threshold']
    get listeners() {
      const { submit, open, closed, ...rest } = this.$listeners
      return rest
    }

    get AppX() {
      return this.$store.getters.AppX
    }

    get typeId() {
      const { device: { typeId } = {} } = this.formData
      return typeId
    }

    async onSubmit() {
      const valid = !(await Promise.all(this.keys.map((key) => this.$refs[key].validate()))).some((item) => !item)
      if (valid) {
        console.log(this.formData)
        const {
          basis,
          connect,
          device: { fileList, ...device },
          threshold
        } = this.formData
        const data: IPointDetail = {
          ...basis,
          ...connect,
          ...device,
          ...this.$store.getters['project/info'],
          targets: threshold.items,
          fileList: (fileList || []).map((item) => item.raw).filter((item) => !!item)
        }
        this.$emit('submit', data)
      }
    }

    onClosed() {
      this.formData = getDefaultFormData()
      this.keys.forEach((key) => this.$refs[key].resetFields())
      this.$emit('closed')
    }

    onOpen() {
      setTimeout(() => this.keys.forEach((key) => this.$refs[key].clearValidate()), 0)
      this.$emit('open')
      this.$nextTick(() => {
        // 更打开弹窗更新地图
        this.$refs.basis.$refs.minMap.initMap().then(() => {
          const { longitude, latitude, longitude2, latitude2 } = this.data
          this.echoPoint(longitude, latitude, 2) // 回显站点
          this.echoPoint(longitude2, latitude2, 1) // 回显排水设施
        })
      })
    }

    async getDetail(id: number) {
      const { result } = await getDetail(id)
      const {
        drainageId,
        drainageName,
        drainageRoadName,
        drainageType,
        longitude2,
        latitude2,
        layerName,
        targetVos,
        installVo,
        statuses,
        ...rest
      } = result || {}
      const { uploadFiles, deviceType, ...install } = installVo || {}
      const typeId = deviceType
      this.formData = {
        connect: { drainageId, drainageName, drainageRoadName, drainageType, longitude2, latitude2, layerName },
        device: {
          typeId,
          install,
          fileList: (uploadFiles || []).map(({ filePath: url, fileName: name, id: uid }) => ({
            url: getRemoteFile(url),
            name: name || url,
            uid
          }))
        },
        threshold: {
          standardId: undefined,
          items: (targetVos || []).map((item) => {
            const { biginTime, endTime, sid } = item
            return Object.defineProperty({ ...item, id: sid }, 'timeRange', {
              writable: true,
              value: [moment(biginTime || '00:00', 'HH:mm').toDate(), moment(endTime || '23:59', 'HH:mm').toDate()]
            })
          })
        },
        basis: rest as IFormData['basis']
      }
    }

    @Watch('typeId')
    async getAllStandards(typeId) {
      try {
        const {
          result: { records }
        } = await standardPage({ typeId, current: 1, size: 9999 })
        this.standards = records || []
      } catch (error) {
        console.log(error)
      }
    }

    @Watch('data', { immediate: true })
    setDefaultData(val: IPoint) {
      if (val.id) {
        this.getDetail(val.id)
      } else {
        this.formData = getDefaultFormData()
      }
    }

    mapSelect() {
      this.$refs.basis.initMapClick()
    }

    mapClick(event) {
      const viewer = this.$refs.basis.$refs.minMap._viewer
      const Cesium = (window as any).Cesium
      const radius = 2
      const position = viewer.scene.pickPosition(event.position)
      const ellpise = new Cesium.Entity({
        position: position,
        ellipse: {
          semiMajorAxis: radius,
          semiMinorAxis: radius,
          material: Cesium.Color.ORANGERED,
          classificationType: Cesium.ClassificationType.TERRAIN
        }
      })
      const positions = PipeQueryHelper.converCesiumToSuperMapEllipse(ellpise)
      // 查询数据
      this.queryFacilities(positions.positions)
    }

    /**
     * 空间查询数据服务
     * @param {Cesium.Cartesian3[]} positions 多边形顶点
     */
    queryFacilities(positions) {
      const viewer = this.$refs.basis.$refs.minMap._viewer
      const Cesium = (window as any).Cesium
      const SuperMap = (window as any).SuperMap
      const geometry = CesiumToSuperMap.convertPolygon(Cesium, SuperMap, { positions: positions })
      // console.log('appX',this.AppX.appConfig.gisResource.theme.config.pcdtps.url);

      // 查询url
      const URL = this.AppX.appConfig.gisResource.tiplayers.config.geoquery.url
      // const URL = this.AppX.appConfig.gisResource.theme.config.pcdtps.url
      // const layerList = pipeConfig.pipe
      const layerList = PipeQueryHelper.pipe
      let datasetNames = []
      layerList.forEach((item) => {
        if (item.geometryType == 'point' && item.pipeType == 'PC')
          datasetNames.push(`${item.origindataset}@${item.datasource}`)
      })
      // console.log('数据集sss',datasetNames);

      if (datasetNames.length == 0) return
      PipeQueryHelper.queryMapByGeometry({
        url: URL,
        datasetNames: datasetNames,
        geometry: geometry,
        completed: (response) => {
          if (response.result.currentCount == 0) {
            this.$message.info('未查询到相关设施！')
            return
          }
          // console.log('查询结果', response)

          const facilities = response.result.recordsets.find((item) => {
            return item.features.length > 0
          })
          // console.log('有数据的图层', facilities)
          // 图层名称
          const dataSetName = facilities.datasetName.split('@')[0]
          // 设施点
          const feature = facilities.features[0].data
          const { SMX: longitude, SMY: latitude, SMZ: altitude } = feature
          // console.log('关联的点', feature)
          // 标记选择的设施点
          viewer.entities.removeById('correlation_facility')
          viewer.entities.add({
            id: 'correlation_facility',
            position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
            billboard: {
              image: require('@/views/spectrum/common/images/location2.png'),
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //贴地属性
              heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
              eyeOffset: Cesium.Cartesian3.ZERO
            }
          })
          const {
            SMID: drainageId,
            MANHOLE_TYPE: drainageName,
            ROAD_NAME: drainageRoadName,
            PIPE_CATEGORY: drainageType
          } = feature
          this.formData.connect = {
            drainageId: Number(drainageId),
            drainageName: drainageName,
            drainageRoadName: drainageRoadName,
            drainageType: drainageType,
            longitude2: longitude,
            latitude2: latitude,
            layerName: dataSetName
          }
          // console.log('jk', this.formData.connect)
        },
        failed: function (err) {
          console.error(err)
          // this.$message.error('部件设施获取失败')
        }
      })
    }

    /**
     * 站点及设施回显
     */
    echoPoint(longitude: number, latitude: number, type: number) {
      if (!longitude || !latitude) return
      const viewer = this.$refs.basis.$refs.minMap._viewer
      const Cesium = (window as any).Cesium
      // 标记选择的设施点
      viewer.entities.removeById(type == 1 ? 'correlation_facility' : 'site_point')
      const entity = {
        id: type == 1 ? 'correlation_facility' : 'site_point',
        position: Cesium.Cartesian3.fromDegrees(longitude, latitude, 0),
        billboard: {
          image:
            type == 1
              ? require('@/views/spectrum/common/images/location2.png')
              : require('@/views/spectrum/common/images/location.png'),
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //贴地属性
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
          eyeOffset: Cesium.Cartesian3.ZERO
        }
      }
      setTimeout(() => {
        viewer.entities.add(entity)
      }, 200)
      viewer.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, 0)
      })
    }
  }
</script>
