<template>
  <el-dialog v-model="showDialog" :title="title" width="800px" destroy-on-close>
    <div class="form-wrapper">
      <div class="base-container">
        <el-form class="base-info" :model="form" ref="formRef" :label-width="labelWidth">
          <el-form-item label="样式名称" prop="styleName">
            <el-input v-model="form.styleName" placeholder="请输入样式名称" clearable></el-input>
          </el-form-item>
          <el-form-item label="样式类型" prop="styleType">
            <el-select clearable v-model="form.styleType" placeholder="请选择样式类型" @change="handleTypeChange">
              <el-option v-for="type in styleTypeList" :key="type.value" :label="type.label" :value="type.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="描述" prop="description">
            <el-input v-model="form.description" type="textarea" :autosize="{ minRows: 4, maxRows: 4 }" resize="none"
              placeholder="请输入描述信息"></el-input>
          </el-form-item>
          <el-row :gutter="20">
            <el-col :span="12" v-if="form.styleType === 'point'">
              <el-form-item label="显示图标" prop="showBillboard">
                <el-switch v-model="showBillboard" @change="refreshMap" />
              </el-form-item>
            </el-col>
            <el-col :span="12" v-if="['point', 'polyline', 'polygon', 'billboard'].includes(form.styleType)">
              <el-form-item label="显示标签" prop="showLabel">
                <el-switch v-model="showLabel" @change="refreshMap" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <div class="map-preview">
          <cesium-map :options="mapOptions" @init="initMap" />
        </div>
      </div>
      <div class="sub-container">
        <!-- 点样式 -->
        <el-form v-if="showPoint" :model="formPoint" ref="formPointRef" :label-width="labelWidth">
          <el-divider content-position="left" class="style-title">点样式配置</el-divider>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="像素大小" prop="pixelSize">
                <!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
                <el-input-number v-model="formPoint.pixelSize" :min="1" style="width: 100%;" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="颜色" prop="color">
                <el-color-picker v-model="formPoint.color" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label="轮廓线" prop="showOutline">
            <el-switch v-model="formPoint.showOutline" />
          </el-form-item>
          <el-row v-if="formPoint.showOutline" :gutter="20">
            <el-col :span="12">
              <el-form-item label="宽度" prop="outlineWidth">
                <!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
                <el-input-number v-model="formPoint.outlineWidth" :min="1" style="width: 100%;" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="颜色" prop="outlineColor">
                <el-color-picker v-model="formPoint.outlineColor" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <!-- 线样式 -->
        <el-form v-if="showPolyline" :model="formPolyline" ref="formPolylineRef" :label-width="labelWidth">
          <el-divider content-position="left" class="style-title">线样式配置</el-divider>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="宽度" prop="width">
                <!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
                <el-input-number v-model="formPolyline.width" :min="1" style="width: 100%;" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="颜色" prop="color">
                <el-color-picker v-model="formPolyline.color" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label="闭合" prop="closed">
            <el-switch v-model="formPolyline.closed" />
          </el-form-item>
        </el-form>
        <!-- 面样式 -->
        <el-form v-if="showPolygon" :model="formPolygon" ref="formPolygonRef" :label-width="labelWidth">
          <el-divider content-position="left" class="style-title">面样式配置</el-divider>
          <el-form-item label="填充颜色" prop="color">
            <el-color-picker v-model="formPolygon.color" />
          </el-form-item>
          <el-form-item label="轮廓线" prop="showOutline">
            <el-switch v-model="formPolygon.showOutline" />
          </el-form-item>
          <el-row v-if="formPolygon.showOutline" :gutter="20">
            <el-col :span="12">
              <el-form-item label="宽度" prop="outlineWidth">
                <!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
                <el-input-number v-model="formPolygon.outlineWidth" :min="1" style="width: 100%;" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="颜色" prop="outlineColor">
                <el-color-picker v-model="formPolygon.outlineColor" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <!-- 图标样式 -->
        <el-form v-if="showBillboard" :model="formBillboard" ref="formBillboardRef" :label-width="labelWidth">
          <el-divider content-position="left" class="style-title">图标样式配置</el-divider>
          <el-form-item label="图片" prop="image">
            <el-image class="style-billboard-image" :src="formBillboard.image" fit="contain"
              @click="handleIconSelect" />
          </el-form-item>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="缩放" prop="scale">
                <el-slider v-model="formBillboard.scale" :max="5" :min="0.1" :step="0.1" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="旋转" prop="rotation">
                <el-input-number v-model="formBillboard.rotation" :min="0" :max="360" style="width: 100%;" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="横向定位" prop="horizontalOrigin">
                <el-select v-model="formBillboard.horizontalOrigin" placeholder="请选择横向定位">
                  <el-option v-for="item in horizontalOriginTypeList" :key="item.value" :label="item.label"
                    :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="纵向定位" prop="verticalOrigin">
                <el-select v-model="formBillboard.verticalOrigin" placeholder="请选择纵向定位">
                  <el-option v-for="item in verticalOriginTypeList" :key="item.value" :label="item.label"
                    :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="横向偏移" prop="horizontalOffset">
                <el-input-number v-model="formBillboard.horizontalOffset" style="width: calc(100% - 60px);" />
                <span style="margin-left: 8px;">(右为正)</span>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="纵向偏移" prop="verticalOffset">
                <el-input-number v-model="formBillboard.verticalOffset" style="width: calc(100% - 60px);" />
                <span style="margin-left: 8px;">(下为正)</span>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <!-- 标签样式 -->
        <el-form v-if="showLabel" :model="formLabel" ref="formLabelRef" :label-width="labelWidth">
          <el-divider content-position="left" class="style-title">标签样式配置</el-divider>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="字号" prop="font">
                <el-input-number v-model="formLabel.font" :min="12" style="width: 100%;" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="颜色" prop="fillColor">
                <el-color-picker v-model="formLabel.fillColor" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label="轮廓线" prop="showOutline">
            <el-switch v-model="formLabel.showOutline" />
          </el-form-item>
          <el-row v-if="formLabel.showOutline" :gutter="20">
            <el-col :span="12">
              <el-form-item label="宽度" prop="outlineWidth">
                <el-input-number v-model="formLabel.outlineWidth" :min="1" style="width: 100%;" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="颜色" prop="outlineColor">
                <el-color-picker v-model="formLabel.outlineColor" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label="背景" prop="showBackground">
            <el-switch v-model="formLabel.showBackground" />
          </el-form-item>
          <el-row v-if="formLabel.showBackground" :gutter="20">
            <el-col :span="12">
              <el-form-item label="横向内边距" prop="horizontalPadding">
                <el-input-number v-model="formLabel.horizontalPadding" :min="0" style="width: 100%;" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="纵向内边距" prop="verticalPadding">
                <el-input-number v-model="formLabel.verticalPadding" :min="0" style="width: 100%;" />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="颜色" prop="backgroundColor">
                <el-color-picker v-model="formLabel.backgroundColor" show-alpha />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="横向定位" prop="horizontalOrigin">
                <el-select v-model="formLabel.horizontalOrigin" placeholder="请选择横向定位">
                  <el-option v-for="item in horizontalOriginTypeList" :key="item.value" :label="item.label"
                    :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="纵向定位" prop="verticalOrigin">
                <el-select v-model="formLabel.verticalOrigin" placeholder="请选择纵向定位">
                  <el-option v-for="item in verticalOriginTypeList" :key="item.value" :label="item.label"
                    :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="横向偏移" prop="horizontalOffset">
                <el-input-number v-model="formLabel.horizontalOffset" style="width: calc(100% - 60px);" />
                <span style="margin-left: 8px;">(右为正)</span>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="纵向偏移" prop="verticalOffset">
                <el-input-number v-model="formLabel.verticalOffset" style="width: calc(100% - 60px);" />
                <span style="margin-left: 8px;">(下为正)</span>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <!-- 通用样式 -->
        <el-form :model="formCommon" ref="formCommonRef" :label-width="labelWidth">
          <el-divider content-position="left" class="style-title">通用样式配置</el-divider>
          <el-form-item label="贴地" prop="clampToGround">
            <el-switch v-model="formCommon.clampToGround" />
          </el-form-item>
          <div v-if="['point', 'billboard', 'label'].includes(form.styleType)">
            <el-form-item label="按视距缩放" prop="scaleByDistance">
              <el-switch v-model="formCommon.scaleByDistance" />
            </el-form-item>
            <el-row v-if="formCommon.scaleByDistance" :gutter="20">
              <el-col :span="12">
                <el-form-item label="缩放近视距" prop="scaleNear">
                  <el-input-number v-model="formCommon.scaleNear" :min="0" style="width: 100%;" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="缩放比例" prop="scaleNearValue">
                  <el-input-number v-model="formCommon.scaleNearValue" style="width: 100%;" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row v-if="formCommon.scaleByDistance" :gutter="20">
              <el-col :span="12">
                <el-form-item label="缩放远视距" prop="scaleFar">
                  <el-input-number v-model="formCommon.scaleFar" :min="1" style="width: 100%;" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="缩放比例" prop="scaleFarValue">
                  <el-input-number v-model="formCommon.scaleFarValue" style="width: 100%;" />
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </el-form>
      </div>
    </div>
    <icon-dialog ref="iconDialog" v-model:current="formBillboard.image" v-model="showIconDialog" />
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleConfirm">保存</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup name="styleDialog">
import * as Cesium from 'cesium'

import CesiumMap from '@/components/CesiumMap/index.vue';
import { getStyle } from "@/components/CesiumMap/utils/styleFn";
import { createFeature } from "@/components/CesiumMap/utils/layerFn";
import IconDialog from "./iconDialog.vue";

import { getStyleType, getStyle as getStyleApi, addStyle, updateStyle } from "@/api/gisManagement/configStyle"

import checkPointIcon from '@/assets/icons/example/check_point.png'

const emits = defineEmits(['refresh'])
const { proxy } = getCurrentInstance()

const showDialog = ref(false)
const title = ref('');
const labelWidth = '85px'
let viewer = null
let entity = null
const defaultPoint = [102, 25]
const defaultPosition = Cesium.Cartesian3.fromDegrees(...defaultPoint)
const defaultPolyline = Cesium.Cartesian3.fromDegreesArray([102.1, 24.9, 102.1, 25.1, 101.9, 24.9, 101.9, 25.2])
const defaultPolygon = Cesium.Cartesian3.fromDegreesArray([102.1, 24.9, 102.1, 25.1, 101.9, 25.1, 101.9, 24.9])
const mapOptions = {
  setView: {
    x: defaultPoint[0],
    y: defaultPoint[1],
    z: 5000,
    heading: 0,
    pitch: -90,
    roll: 0
  }
}
const styleTypeList = ref([])
const horizontalOriginTypeList = ref([
  { label: '左', value: 1 },
  { label: '中', value: 0 },
  { label: '右', value: -1 }
])
const verticalOriginTypeList = ref([
  { label: '上', value: -1 },
  { label: '中', value: 0 },
  { label: '下', value: 1 }
])
const form = ref({
  id: null,
  styleName: '',
  styleType: [],
  description: '',
  config: '',
})
const showPoint = ref(false)
const formPoint = ref({
  pixelSize: 10,
  color: '#ffffff',
  showOutline: false,
  outlineWidth: 1,
  outlineColor: '#000000',
})
const showPolyline = ref(false)
const formPolyline = ref({
  width: 1,
  color: '#ffffff',
  closed: false,
})
const showPolygon = ref(false)
const formPolygon = ref({
  color: '#ffffff',
  showOutline: false,
  outlineWidth: 1,
  outlineColor: '#000000',
})
const showBillboard = ref(false)
const formBillboard = ref({
  image: checkPointIcon,
  scale: 1,
  rotation: 0,
  horizontalOrigin: 0,
  verticalOrigin: 1,
  horizontalOffset: 0,
  verticalOffset: 0,
})
const showIconDialog = ref(false)
const showLabel = ref(false)
const formLabel = ref({
  font: 12,
  fillColor: '#ffffff',
  showOutline: false,
  outlineWidth: 1,
  outlineColor: '#000000',
  showBackground: false,
  backgroundColor: 'rgba(42, 42, 42, 0.8)',
  horizontalPadding: 0,
  verticalPadding: 0,
  horizontalOrigin: 0,
  verticalOrigin: 1,
  horizontalOffset: 0,
  verticalOffset: 0,
})
const formCommon = ref({
  clampToGround: true,
  scaleByDistance: false,
  scaleNear: 0,
  scaleNearValue: 0,
  scaleFar: 1,
  scaleFarValue: 0,
})

/**
 * 打开弹窗的方法
 * @param id 样式id
 */
const show = async (id) => {
  reset()
  if (id) {
    title.value = '修改样式信息'
    getStyleApi(id).then(res => {
      // const data = response.data
      // form.value.styleName = data.styleName
      // form.value.styleType = data.styleType
      // form.value.description = data.description
      form.value = res.data
      const config = JSON.parse(form.value.config)
      if (config.point) {
        showPoint.value = true
        formPoint.value = config.point
      }
      if (config.polyline) {
        showPolyline.value = true
        formPolyline.value = config.polyline
      }
      if (config.polygon) {
        showPolygon.value = true
        formPolygon.value = config.polygon
      }
      if (config.billboard) {
        showBillboard.value = true
        formBillboard.value = config.billboard
      }
      if (config.label) {
        showLabel.value = true
        formLabel.value = config.label
      }
      formCommon.value = config.common
    })
  } else {
    title.value = '新增样式信息'
    form.value.id = null
  }
  // 获取样式类型
  getStyleType().then(response => {
    styleTypeList.value = response
  })

  showDialog.value = true;
}

/**
 * 初始化地图
 */
const initMap = (viewerInstance) => {
  // 初始化地图变量
  viewer = viewerInstance
  // entity = viewer.entities.add({
  //   id: 'stylePreview',
  //   position: defaultPosition, // 默认位置
  // })
  // 设置不能平移
  viewer.camera.lookAt(
    defaultPosition, // 设置初始位置
    new Cesium.HeadingPitchRange(Cesium.Math.toRadians(0), Cesium.Math.toRadians(-90), 5000) // 设置初始视角
  );
  refreshMap()
}

/**
 * 样式类型改变, 切换配置项显示
 * @param {string} val 类型值
 */
const handleTypeChange = (val) => {
  if (val === 'point') {
    showPoint.value = true
    showPolyline.value = false
    showPolygon.value = false
    showBillboard.value = false
    showLabel.value = false
  } else if (val === 'polyline') {
    showPoint.value = false
    showPolyline.value = true
    showPolygon.value = false
    showBillboard.value = false
    showLabel.value = false
  } else if (val === 'polygon') {
    showPoint.value = false
    showPolyline.value = false
    showPolygon.value = true
    showBillboard.value = false
    showLabel.value = false
  } else if (val === 'billboard') {
    showPoint.value = false
    showPolyline.value = false
    showPolygon.value = false
    showBillboard.value = true
    showLabel.value = false
  } else if (val === 'label') {
    showPoint.value = false
    showPolyline.value = false
    showPolygon.value = false
    showBillboard.value = false
    showLabel.value = true
  } else {
    // 隐藏所有样式配置项
    showPoint.value = false
    showPolyline.value = false
    showPolygon.value = false
    showBillboard.value = false
    showLabel.value = false
  }
}

/**
 * 打开图标选择对话框
 */
const handleIconSelect = () => {
  showIconDialog.value = true;
}

/**
 * 刷新地图
 * 更新样式后触发
 */
const refreshMap = () => {
  if(!viewer) {
    return
  }

  const options = {
    type: form.value.styleType,
  }
  if (showPoint.value) options.point = formPoint.value
  if (showPolyline.value) options.polyline = formPolyline.value
  if (showPolygon.value) options.polygon = formPolygon.value
  if (showBillboard.value) options.billboard = formBillboard.value
  if (showLabel.value) options.label = formLabel.value
  options.common = formCommon.value
  console.log('更新样式配置:', JSON.stringify(options))
  form.value.config = JSON.stringify(options)

  if (entity) {
    viewer.entities.remove(entity)
  }
  const style = getStyle(options)
  style.id = 'stylePreview'
  let position = defaultPosition
  if (style.properties?.type === 'polyline') {
    position = defaultPolyline
  } else if (style.properties?.type === 'polygon') {
    position = defaultPolygon
  }
  entity = createFeature(style, position, '测试')
  if (entity) {
    viewer.entities.add(entity)
  }

}

const reset = () => {
  viewer = null
  entity = null
  form.value = {
    id: null,
    styleName: '',
    styleType: [],
    description: '',
    config: '',
  }
  showPoint.value = false
  formPoint.value = {
    pixelSize: 10,
    color: '#ffffff',
    showOutline: false,
    outlineWidth: 1,
    outlineColor: '#000000',
  }
  showPolyline.value = false
  formPolyline.value = {
    width: 1,
    color: '#ffffff',
    closed: false,
  }
  showPolygon.value = false
  formPolygon.value = {
    color: '#ffffff',
    showOutline: false,
    outlineWidth: 1,
    outlineColor: '#000000',
  }
  showBillboard.value = false
  formBillboard.value = {
    image: checkPointIcon,
    scale: 1,
    rotation: 0,
    horizontalOrigin: 0,
    verticalOrigin: 1,
    horizontalOffset: 0,
    verticalOffset: 0,
  }
  showLabel.value = false
  formLabel.value = {
    font: 12,
    fillColor: '#ffffff',
    showOutline: false,
    outlineWidth: 1,
    outlineColor: '#000000',
    showBackground: false,
    backgroundColor: 'rgba(42, 42, 42, 0.8)',
    horizontalPadding: 0,
    verticalPadding: 0,
    horizontalOrigin: 0,
    verticalOrigin: 1,
    horizontalOffset: 0,
    verticalOffset: 0,
  }
  formCommon.value = {
    clampToGround: true,
    scaleByDistance: false,
    scaleNear: 0,
    scaleNearValue: 0,
    scaleFar: 1,
    scaleFarValue: 0,
  }
}

/**
 * 确定
 */
const handleConfirm = () => {
  // proxy.$refs["styleRef"].validate(valid => {
  //   if (valid) {
  //     if (form.value.userId != null) {
  //       updateUser(form.value).then(response => {
  //         proxy.$modal.msgSuccess("修改成功")
  //         open.value = false
  //         getList()
  //       })
  //     } else {
  //       addUser(form.value).then(response => {
  //         proxy.$modal.msgSuccess("新增成功")
  //         open.value = false
  //         getList()
  //       })
  //     }
  //   }
  // })

  proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      if (form.value.id) {
        updateStyle(form.value).then(response => {
          proxy.$modal.msgSuccess("修改成功")
          emits('refresh', response)
          showDialog.value = false
        })
      } else {
        addStyle(form.value).then(response => {
          proxy.$modal.msgSuccess("新增成功")
          emits('refresh', response)
          showDialog.value = false
        })
      }
    }
  })

}

/**
 * 取消
 */
const handleCancel = () => {
  showDialog.value = false
}

watch(form.value.styleType, (val) => {
  if (val === 'polyline' || val === 'polygon') {
    formCommon.value.scaleByDistance = false
  }
})

watch(() => [form.value.styleType, formPoint, formPolyline, formPolygon, formBillboard, formLabel, formCommon], refreshMap, {
  deep: true
})

defineExpose({
  show
})
</script>

<style lang="scss" scoped>
.base-container {
  display: flex;

  .base-info {
    flex: auto;
  }

  .map-preview {
    width: 40%;
    min-width: 400px;
    height: 250px;
    margin-left: 20px;
    border: 1px solid var(--el-border-color);
  }
}

.sub-container {
  margin-top: 12px;
  max-height: calc(70vh - 290px);
  overflow-x: hidden;
  overflow-y: auto;
}

.style-title {
  margin: 32px 0;
}

.style-billboard-image {
  width: 48px;
  height: 48px;
  border: 1px solid var(--el-border-color);
  border-radius: 4px;
  cursor: pointer;
}
</style>