<template>
  <tf-dialog v-bind="$attrs" v-on="listeners" @submit="onSubmit" width="476px" top="7vh">
    <el-row :gutter="15">
      <el-col>
        <el-form
          class="form"
          ref="form"
          v-bind="{ labelWidth: 'auto', size: 'medium' }"
          :model="formData"
          :rules="rules"
        >
          <el-form-item
            v-for="{ name, label, type, required, options, disabled, ...rest } of formItems"
            :key="name"
            :required="required"
            :label="label"
            :prop="name"
          >
            <el-date-picker
              v-if="type === 'date'"
              v-model="formData[name]"
              value-format="yyyy-MM-dd HH:mm:ss"
              format="yyyy-MM-dd"
              :disabled="disabled"
              :placeholder="`请选择${label}`"
              clearable
              size="small"
              v-bind="rest"
            />
            <el-select
              v-else-if="type === 'select'"
              v-model="formData[name]"
              filterable
              :placeholder="`请选择${label}`"
              size="small"
              clearable
              v-bind="rest"
              style="width: 100%"
            >
              <el-option v-for="item in options" :key="item.id" :label="item.notes" :value="item.notes" />
            </el-select>
            <el-input
              v-else
              v-model="formData[name]"
              :type="type || 'text'"
              :disabled="disabled"
              :placeholder="name === 'no' ? '系统自动添加' : `请输入${label}`"
              size="medium"
              clearable
              v-bind="rest"
            />
          </el-form-item>
          <el-row :gutter="15">
            <el-form-item :key="'l&t'" :label="'经纬度'" :prop="'l&t'">
              <el-col :span="8">
                <el-input
                  v-model="formData['longitude']"
                  :type="'text'"
                  :placeholder="`请输入经度`"
                  size="medium"
                  clearable
              /></el-col>
              <el-col :span="8">
                <el-input
                  v-model="formData['latitude']"
                  :type="'text'"
                  :placeholder="`请输入纬度`"
                  size="medium"
                  clearable
              /></el-col>
              <el-col :span="8">
                <el-button type="primary" @click="selectCoord()">图上选择</el-button>
              </el-col>
              <el-col :span="8">
                <el-checkbox v-model="formData['positionShow']">是否显示</el-checkbox>
              </el-col>
            </el-form-item>
          </el-row>
          <el-row :gutter="15">
            <el-form-item :key="'area'" :label="'工程面积(km²)'" :prop="'area'">
              <el-col :span="16">
                <el-input
                  v-model="formData['area']"
                  :type="'text'"
                  :placeholder="`请绘制`"
                  readonly
                  size="medium"
                  clearable
                />
              </el-col>
              <el-col :span="8">
                <el-button type="primary" @click="drawInMap()">图上绘制</el-button>
              </el-col>
              <el-col :span="8">
                <el-checkbox v-model="formData['rangeShow']">是否显示</el-checkbox>
              </el-col>
            </el-form-item>
          </el-row>
        </el-form>
      </el-col>
    </el-row>
  </tf-dialog>
</template>

<script lang="ts">
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
import { ElForm } from 'element-ui/types/form'
import { IProject, IKeyCode } from '../commonAPI/common'
import { getByKeys } from '../commonAPI/request'
import * as turf from '@turf/turf'
//地图变量
const Cesium = (window as any).Cesium
let handler = null
let DrawHandler = null

const getDefaultValue = (): Partial<IProject> => ({
  code: undefined,
  name: undefined,
  planBeginDate: undefined,
  planEndDate: undefined,
  levelname: undefined,
  longitude: undefined,
  latitude: undefined,
  range: undefined,
  area: undefined
})

@Component({ name: 'ProjectForm' })
export default class ProjectForm extends Vue {
  @Prop({ type: Object, default: () => ({}) }) data!: object
  $refs!: { form: ElForm }
  formData: Partial<IProject> = {
    ...getDefaultValue()
  }

  polygonDraw

  types: IKeyCode[] = []

  status: IKeyCode[] = []

  created() {
    this.getDictionaryValue()
  }

  get listeners() {
    const { submit, ...rest } = this.$listeners
    return rest
  }

  get formItems() {
    return [
      { label: '工程编号', name: 'code', disabled: true },
      { label: '工程名称', name: 'name', disabled: true },
      { label: '工程类型', name: 'projectType', type: 'select', options: this.types },
      {
        label: '工程状态',
        name: 'projectStatus',
        type: 'select',
        options: this.status
      },
      { label: '计划开始时间', name: 'planBeginDate', type: 'date', style: 'width:100%' },
      { label: '计划结束时间', name: 'planEndDate', type: 'date', style: 'width:100%' }
    ]
  }

  rules = {}

  onSubmit() {
    this.$refs.form.validate((valid) => {
      if (valid) {
        const { ...rest } = this.formData
        this.$emit('submit', { ...rest })
      }
    })
  }

  @Watch('data', { immediate: true })
  setDefaultData(val: IProject) {
    for (const key in val) {
      if (val[key] == '/') {
        val[key] = ''
      }
      if (key === 'positionShow' || key === 'rangeShow') {
        val[key] = val[key] === 1 ? true : false
      }
    }
    this.formData = val.id ? { ...val } : { ...getDefaultValue() }
  }

  async getDictionaryValue() {
    let pType = await getByKeys({ keys: 'PROJECT_TYPE' })
    let pStatus = await getByKeys({ keys: 'PROJECT_STATUS' })
    this.types = pType.result.PROJECT_TYPE
    this.status = pStatus.result.PROJECT_STATUS
  }

  //图上选择坐标
  selectCoord() {
    const viewer = (window as any).viewer
    handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas)
    const that = this
    handler.setInputAction(function (event) {
      let cartesian = viewer.camera.pickEllipsoid(event.position)
      let cartographic = Cesium.Cartographic.fromCartesian(cartesian)
      let lng = Cesium.Math.toDegrees(cartographic.longitude) // 经度
      let lat = Cesium.Math.toDegrees(cartographic.latitude) // 纬度
      let alt = cartographic.height // 高度，椭球面height永远等于0
      let coordinate = {
        longitude: Number(lng.toFixed(10)),
        latitude: Number(lat.toFixed(10))
        // altitude: Number(alt.toFixed(2))
      }
      that.formData.longitude = lng.toFixed(10)
      that.formData.latitude = lat.toFixed(10)
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
  }
  //图上绘制
  drawInMap() {
    this.drawPolygon()
  }
  //绘制工程范围
  drawPolygon() {
    this.clearDrawHandler()
    this.clearDrawPolygon()
    const viewer = (window as any).viewer
    DrawHandler = new Cesium.ScreenSpaceEventHandler(viewer.canvas)
    viewer.enableCursorStyle = false
    viewer._element.style.cursor = ''
    let isDrawing = false
    let positions = []
    let polygon = null
    DrawHandler.setInputAction((e) => {
      const position = viewer.scene.pickPosition(e.position)
      if (!isDrawing) {
        positions.push(position)
        isDrawing = true
      } else {
        positions.push(position)
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    DrawHandler.setInputAction((e) => {
      if (isDrawing) {
        const position = viewer.scene.pickPosition(e.endPosition)
        if (positions.length === 1) {
          positions.push(position)
          polygon = viewer.entities.add({
            polyline: {
              show: new Cesium.CallbackProperty(() => {
                return positions.length >= 2
              }, false),
              positions: new Cesium.CallbackProperty(() => {
                if (positions.length < 3) {
                  return positions
                } else {
                  const line = positions.map((item) => item)
                  line.push(line[0])
                  return line
                }
              }, false),
              followSurface: false,
              clampToGround: true,
              material: Cesium.Color.DODGERBLUE,
              width: 2.0
            },
            polygon: {
              hierarchy: new Cesium.CallbackProperty(() => {
                return new Cesium.PolygonHierarchy(positions)
              }, false),
              material: Cesium.Color.DEEPSKYBLUE.withAlpha(0.3),
              perPositionHeight: false,
              outline: true,
              outlineColor: Cesium.Color.DODGERBLUE,
              heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
              outlineWidth: 1.0
            }
          })
          this.polygonDraw = polygon
        } else {
          positions[positions.length - 1] = position
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
    DrawHandler.setInputAction((e) => {
      if (!isDrawing) {
        this.clearDrawHandler()
        return
      }
      if (positions.length > 2) {
        const position = viewer.scene.pickPosition(e.position)
        if (Cesium.defined(polygon)) {
          positions.push(position)
        }
        this.getArea(polygon)
        isDrawing = false
        this.clearDrawHandler()
        viewer.enableCursorStyle = true
      }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
  }
  /**
   * 获取面积
   */
  getArea(polygon) {
    const positions = polygon.polygon.hierarchy.getValue(Cesium.JulianDate.now())
    const scopePositions = positions.positions.map((position) => {
      const lonlat = Cesium.Cartographic.fromCartesian(position)
      return [Cesium.Math.toDegrees(lonlat.longitude), Cesium.Math.toDegrees(lonlat.latitude)]
    })
    scopePositions.push(scopePositions[0]) //形成闭环
    console.log(scopePositions)
    this.formData.range = JSON.stringify({ coordinates: scopePositions })
    //面积计算
    const newLonlat = scopePositions.map((item) => {
      return item
    })
    newLonlat.push(newLonlat[0])
    const turfpolygon = turf.polygon([newLonlat])
    const area = (turf.area(turfpolygon) / 1000000).toFixed(2)
    this.formData.area = area
  }
  //清除绘制
  clearDrawPolygon() {
    if (this.polygonDraw) {
      ;(window as any).viewer.entities.remove(this.polygonDraw)
      this.polygonDraw = null
    }
  }
  //清除DrawHandler
  clearDrawHandler() {
    if (DrawHandler && !DrawHandler.isDestroyed()) {
      DrawHandler.destroy()
      DrawHandler = null
    }
  }
  //清除handler
  clearHandler() {
    if (handler && !handler.isDestroyed()) {
      handler.destroy()
      handler = null
    }
  }
  //事件清除
  destroy() {
    this.clearHandler()
    this.clearDrawHandler()
    this.clearDrawPolygon()
  }
}
</script>
<style lang="scss" scoped>
.el-dialog__wrapper {
  pointer-events: none;
  overflow: hidden;
  >>> .el-dialog {
    // 弹窗层元素不可穿透点击事件（不影响弹窗层元素的点击事件）
    pointer-events: auto;
  }
}
</style>
