<template>
  <div class="absolute top-0 left-0 h-full w-full" style="height: calc(100vh - 85px)">
    <div id="dialogMap" style="height: 100%"></div>
    <!-- 右侧驾校列表 -->
    <div class="asider" :class="showSchool ? '' : 'hidden-school'">
      <el-card class="box-card" :body-style="{ flex: 1, 'overflow-y': 'scroll', padding: 0 }">
        <div style="margin: 10px">
          <el-input v-model="searchValue" placeholder="请输入驾校名" />
        </div>
        <template #header>
          <div class="clearfix">
            <div class="map-card-title">驾校列表</div>
            <el-switch
              v-model="showAllSchool"
              :active-value="true"
              :inactive-value="false"
              active-text="隐藏所有"
              inactive-text="展示所有"
              @change="showAllSchoolChange"
            />
          </div>
        </template>
        <div
          v-for="school in schoolList.filter(
            (item) => searchValue == undefined || item.schoolName.includes(searchValue)
          )"
          :key="school.schoolId"
          style="margin: 10px"
          :class="currentdeptId == school.schoolId ? 'actived-school' : ''"
        >
          <el-card :body-style="{ padding: '10px' }">
            <template #header>
              <div class="clearfix">
                <div class="map-card-title">{{ school.schoolName }}</div>
                <el-switch
                  v-model="school.showInMap"
                  class="add-icon"
                  active-text="展示"
                  inactive-text="隐藏"
                  @change="changeSchoolStatus(school)"
                />
              </div>
            </template>
            <el-button @click="handleClickSchool(school)">{{
              `数据管理(${getCount(school.schoolId)})`
            }}</el-button>
            <el-tooltip
              content="新增场地"
              placement="left"
              effect="dark"
              v-if="checkPermi(['school:place:add'])"
            >
              <el-button class="add-place-btn" @click="handleInsertPlace(school.schoolId)">
                <Icon icon="ep:plus" />
              </el-button>
            </el-tooltip>
          </el-card>
        </div>
      </el-card>
      <div class="asider-sub">
        <el-tooltip
          :content="`${showSchool ? '折叠' : '展开'}驾校列表`"
          placement="left"
          effect="dark"
        >
          <el-button class="is-circle" @click="toggleSchool">
            <Icon class="text-12px" :icon="`ep:d-arrow-${showSchool ? 'right' : 'left'}`" />
          </el-button>
        </el-tooltip>
      </div>
    </div>

    <!-- 左侧场地弹框 -->
    <el-card v-if="placeDialogShow" class="place-dialog" :body-style="{ padding: '10px' }">
      <template #header>
        <div class="clearfix">
          <div class="map-card-title">场地设置</div>
          <el-tooltip content="取点" placement="right" effect="dark">
            <el-button class="add-icon" @click="isPointing = !isPointing">
              <Icon icon="ep:location" />
            </el-button>
          </el-tooltip>
        </div>
      </template>
      <el-tabs v-model="placeTab">
        <el-tab-pane label="场地信息" name="info">
          <el-form ref="FormPlace" :model="placeForm" label-width="70px">
            <el-form-item label="所属驾校" prop="schoolId">
              <el-select v-model="placeForm.schoolId" placeholder="请选择" clearable class="w-full">
                <el-option
                  v-for="dict in schoolList"
                  :key="dict.schoolId"
                  :label="dict.schoolName"
                  :value="dict.schoolId"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="名称" prop="name">
              <el-input v-model="placeForm.name" placeholder="输入名称" />
            </el-form-item>
            <el-form-item label="旗子颜色" prop="flagColor">
              <el-radio-group v-model="placeForm.flagColor">
                <el-radio v-for="(item, index) in colorOptions" :key="index" :label="item">
                  <img :src="flagMap[item]" style="width: 20px" />
                </el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="地址" prop="address">
              <el-input v-model="placeForm.address" placeholder="输入地址" />
            </el-form-item>
            <el-form-item label="经度" prop="lng">
              <el-input-number
                v-model="placeForm.lng"
                :min="1"
                :controls="false"
                placeholder="输入经度"
                style="width: 100%"
              />
            </el-form-item>
            <el-form-item label="纬度" prop="lat">
              <el-input-number
                v-model="placeForm.lat"
                :min="1"
                :controls="false"
                placeholder="输入纬度"
                style="width: 100%"
              />
            </el-form-item>
            <el-form-item label="所属区域" prop="area">
              <el-select v-model="placeForm.area" placeholder="请选择" clearable class="w-full">
                <el-option
                  v-for="dict in areaOptions"
                  :key="dict.id"
                  :label="dict.name"
                  :value="dict.id"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="电话" prop="phone">
              <el-input v-model="placeForm.phone" placeholder="输入电话" />
            </el-form-item>
            <el-form-item label="负责人" prop="contact">
              <el-input v-model="placeForm.contact" placeholder="输入负责人" />
            </el-form-item>
            <!-- <el-form-item label="是否推荐" prop="contact">
              <el-radio v-model="placeForm.recommend" :label="true">是</el-radio>
              <el-radio v-model="placeForm.recommend" :label="false">否</el-radio>
            </el-form-item> -->
          </el-form>
        </el-tab-pane>
        <el-tab-pane label="描述" name="desc">
          <Editor v-model:modelValue="placeForm.introduce" />
        </el-tab-pane>
      </el-tabs>
      <div class="flex items-center justify-center mt-10px">
        <el-button type="primary" @click="onSubmit">保存</el-button>
        <el-button @click="closePlaceDialog">取消</el-button>
      </div>
    </el-card>
    <el-autocomplete
      :style="{
        position: 'absolute',
        top: '20px',
        left: placeDialogShow ? '380px' : '20px',
        width: '200px'
      }"
      v-model="areaValue"
      clearable
      placeholder="输入并搜索位置"
      :fetch-suggestions="remoteMethod"
      @select="currentSelect"
    />

    <!-- 底部驾校场地列表 -->
    <el-card
      :class="placeListDialogShow ? '' : 'hidden-place-list'"
      class="place-list-dialog"
      :style="{ right: showSchool ? '300px' : '0', top: fullScreenPlaceList ? '0px' : '420px' }"
      :body-style="{ padding: '10px', height: 'calc(100% - 52px)' }"
    >
      <template #header>
        <div class="clearfix">
          <div class="map-card-title">
            {{ placeListDialogTitle }}
            <el-input v-model="tableSearch" placeholder="请输入场地名称" clearable />
          </div>
          <el-tooltip content="全屏" placement="top" effect="dark">
            <el-button class="add-icon" @click="fullScreenPlaceList = !fullScreenPlaceList">
              <Icon icon="ep:full-screen" />
            </el-button>
          </el-tooltip>
          <el-tooltip content="关闭" placement="top" effect="dark">
            <el-button class="add-icon" @click="closePlaceList">
              <Icon icon="ep:close" />
            </el-button>
          </el-tooltip>
        </div>
      </template>
      <el-table
        :data="placeTableData"
        border
        stripe
        class="place-table-list"
        size="small"
        height="100%"
      >
        <el-table-column label="序号" type="index" fixed="left" width="50" />
        <el-table-column prop="name" label="名称" min-width="100" />
        <el-table-column prop="phone" label="电话" width="120" />
        <el-table-column prop="contact" label="负责人" width="120" />
        <el-table-column prop="address" label="地址" min-width="100" />
        <el-table-column prop="lng" label="经度" width="110" />
        <el-table-column prop="lat" label="纬度" width="110" />
        <el-table-column prop="area" label="所属区域" width="110" />
        <el-table-column label="启用" width="100">
          <template #default="scope">
            <el-switch
              v-model="scope.row.status"
              :active-value="0"
              :inactive-value="1"
              :disabled="!checkPermi(['school:place:update'])"
              @change="changePlaceStatus(scope.row)"
            />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="100">
          <template #default="scope">
            <el-tooltip content="编辑" placement="top" effect="dark">
              <el-button
                type="primary"
                style="padding: 4px 8px"
                @click="handleEditPlace(scope.row)"
                v-hasPermi="['school:place:update']"
              >
                <Icon icon="ep:edit" />
              </el-button>
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <div
      v-if="isPointing"
      class="map-tip"
      :style="{
        transform: 'translate3D(' + (tipPostion.x + 15) + 'px,' + (tipPostion.y - 10) + 'px, 0)'
      }"
      >{{ mapHelpText }}</div
    >
    <Icon
      v-if="isPointing"
      icon="ep:s-flag"
      class="circle"
      :style="{ transform: 'translate3D(' + tipPostion.x + 'px,' + tipPostion.y + 'px, 0)' }"
    />
  </div>
</template>

<script setup name="Place">
import * as PlaceApi from '@/api/school/place'
import { getConfigByConfigKey } from '@/api/system/set'
import { getAreaSimpleList } from '@/api/school/setting/area'
import { checkPermi } from '@/utils/permission'

import FlagRed from '@/assets/imgs/flag/flag_red.png'
import FlagYellow from '@/assets/imgs/flag/flag_yellow.png'
import FlagPurple from '@/assets/imgs/flag/flag_purple.png'
import FlagGreen from '@/assets/imgs/flag/flag_green.png'
import FlagBlue from '@/assets/imgs/flag/flag_blue.png'
import FlagBlack from '@/assets/imgs/flag/flag_black.png'
import AMapLoader from '@amap/amap-jsapi-loader'

const message = useMessage() // 消息弹窗

// 地图相关
const dialogMap = ref(null)
const aMap = ref(null)
const geoCoder = ref(null)
const locationMarker = ref(null)

const flagMap = {
  red: FlagRed,
  yellow: FlagYellow,
  purple: FlagPurple,
  green: FlagGreen,
  blue: FlagBlue,
  black: FlagBlack
}
const colorOptions = ['red', 'yellow', 'blue', 'green', 'purple', 'black']
const areaOptions = ref([])
const mapHelpText = ref('')
const tipPostion = ref({})
const placeTab = ref('info')

const defaultLatLng = ref({
  lat: 31.86119,
  lng: 117.283042
})
const defaultCity = ref('合肥')

let AutoComplete = ref(null)
async function initMap() {
  const data = await getConfigByConfigKey({ configKey: 'defaultLocation' })
  const cityInfo = JSON.parse(data.configValue)
  defaultLatLng.value = {
    lat: cityInfo.lat,
    lng: cityInfo.lng
  }
  defaultCity.value = cityInfo.locationName
  AMapLoader.load({
    key: '713d839ff505943b0f18e6df45f3b0dc', //设置您的key
    version: '2.0',
    plugins: ['AMap.Geocoder', 'AMap.AutoComplete']
  }).then((AMap) => {
    aMap.value = AMap
    geoCoder.value = new AMap.Geocoder()
    dialogMap.value = new AMap.Map('dialogMap', {
      zoom: 12,
      zooms: [2, 22],
      center: [defaultLatLng.value.lng, defaultLatLng.value.lat]
    })
    AutoComplete.value = new AMap.AutoComplete({
      city: defaultCity.value
    })
    locationMarker.value = new AMap.Marker({
      icon: FlagRed
    })
    getPageData()
    dialogMap.value.on('click', (ev) => {
      if (isPointing.value) {
        placeForm.value.lat = ev.lnglat.lat
        placeForm.value.lng = ev.lnglat.lng
        regeoCode()
        locationMarker.value.setPosition([placeForm.value.lng, placeForm.value.lat])
        dialogMap.value.add(locationMarker.value)
        isPointing.value = false
      }
    })
    dialogMap.value.on('mousemove', (ev) => {
      // if (isRanging.value) {
      //   mapHelpText.value =
      //     '左键单击选点，双击/右键单击完成选点，再次点击测距按钮可退出测距模式，并清除测距结果'
      //   tipPostion.value = {
      //     x: ev.pixel.x,
      //     y: ev.pixel.y
      //   }
      // } else if (isPointing.value) {
      mapHelpText.value = '点击地图添加标注'
      tipPostion.value = {
        x: ev.pixel.x,
        y: ev.pixel.y
      }
      // }
    })
  })
}

const areaValue = ref('')
function remoteMethod(searchValue, cb) {
  if (searchValue) {
    AutoComplete.value?.search(searchValue, (status, result) => {
      if (result.tips?.length) {
        // areaList.value = result?.tips
        const list = result.tips.map((it) => ({
          ...it,
          value: it.name
        }))
        cb(list)
      } else {
        cb([])
      }
    })
  } else {
    cb([])
  }
}

function currentSelect(val) {
  if (val) {
    dialogMap.value.setCenter([val.location?.lng, val.location?.lat], true)
  }
}

function regeoCode() {
  geoCoder.value.getAddress([placeForm.value.lng, placeForm.value.lat], (status, result) => {
    if (status === 'complete' && result.regeocode) {
      placeForm.value.address = result.regeocode.formattedAddress
    } else {
      message.error('根据经纬度查询地址失败')
    }
  })
}

async function getPageData() {
  schoolList.value = []
  tableData.value = []
  const data = await PlaceApi.getPlaceList({
    schoolStatus: 0,
    isSearchSchool: true
  })
  if (data.schoolList) {
    schoolList.value = data.schoolList.map((item) => ({ ...item, showInMap: true }))
  }
  if (data.placeList) {
    tableData.value = data.placeList.map((item) => ({ ...item, showInMap: true, schoolShow: true }))
  }
  if (schoolList.value.length) {
    currentdeptId.value = schoolList.value[0].schoolId
    createMarkersInMap()
  }
}

const searchValue = ref('')
const schoolList = ref([])
const placeListDialogShow = ref(false)

const currentdeptId = ref('')

function changeSchoolStatus(school) {
  tableData.value.forEach((item) => {
    if (school.schoolId == item.schoolId) {
      item.schoolShow = school.showInMap
    }
  })
  resetMarkers()
}

function handleClickSchool(item) {
  placeListDialogShow.value = true
  placeListDialogTitle.value = `数据管理 [${item.schoolName}]`
  currentdeptId.value = item.schoolId
}

// 生成markers
function createMarkersInMap() {
  for (let i = 0; i < tableData.value.length; i++) {
    const element = tableData.value[i]
    if (!element.schoolShow || !element.showInMap || element.status == 1) {
      continue
    }
    const markerIcon = flagMap[element.flagColor || 'red']
    const tmpMarker = new aMap.value.Marker({
      map: dialogMap.value,
      position: [element.lng, element.lat],
      icon: markerIcon,
      label: {
        content: element.name,
        direction: 'right'
      },
      extData: element
    })
    tmpMarker.on('click', handleClickMarker)
    placeMarkerList.value.push(tmpMarker)
  }
}

function handleInsertPlace(schoolId) {
  placeDialogShow.value = true
  dialogMap.value.setDefaultCursor('default')
  // isRanging.value = false
  placeForm.value = {
    lat: undefined,
    lng: undefined,
    name: undefined,
    address: undefined,
    introduce: undefined,
    phone: undefined,
    schoolId: schoolId,
    showInMap: true,
    flagColor: 'red',
    recommend: false
  }
}

// 关闭场地弹窗
function closePlaceDialog() {
  placeDialogShow.value = false
  isPointing.value = false
  dialogMap.value.remove(locationMarker.value)
}

const isPointing = ref(false)

function checkPlaceFormValidate() {
  const valid = []
  if (!placeForm.value.name) {
    valid.push('名称')
  }
  if (!placeForm.value.address) {
    valid.push('地址')
  }
  if (!placeForm.value.lng) {
    valid.push('经度')
  }
  if (!placeForm.value.lat) {
    valid.push('纬度')
  }
  if (!placeForm.value.phone) {
    valid.push('电话')
  }
  if (valid.length == 0) {
    return true
  } else {
    message.error(`请将以下填写完整: ${valid.join(',')}`)
    return false
  }
}

function handleClickMarker(ev) {
  if (!checkPermi(['school:place:update'])) {
    return
  }
  placeForm.value = ev.target.getExtData()
  placeDialogShow.value = true
}

async function onSubmit() {
  // 保存接口
  if (checkPlaceFormValidate()) {
    try {
      let resp
      if (placeForm.value.placeId) {
        resp = await PlaceApi.updatePlace(placeForm.value)
      } else {
        resp = await PlaceApi.createPlace(placeForm.value)
        placeForm.value.placeId = resp.data
      }
      message.success('操作成功')
      // 移除选点用 的标记
      dialogMap.value.remove(locationMarker.value)
      // 根据form创建新marker 并添加到地图上
      const tmpMarker = new aMap.value.Marker({
        map: dialogMap.value,
        position: [placeForm.value.lng, placeForm.value.lat],
        icon: flagMap[placeForm.value.flagColor],
        label: {
          content: placeForm.value.name,
          direction: 'right'
        },
        extData: placeForm.value
      })
      // 新marker事件
      tmpMarker.on('click', handleClickMarker)
      // 如果当前选择的marker点存在（编辑）
      // if (selectMarker.value) {
      //   // 地图上 移除选择的点
      //   dialogMap.value.remove(selectMarker.value)
      //   selectMarker.value = null
      // }
      // 关闭场地弹窗
      placeDialogShow.value = false
      isPointing.value = false

      // 场地列表 移除原列表中操作的场地数据
      const tmpArr = tableData.value.filter((item) => item.placeId !== placeForm.value.placeId)
      // 新增新的场地
      tmpArr.push(placeForm.value)
      // 重置场地数组
      tableData.value = tmpArr
      // 地图marker列表 移除操作的原marker 添加新marker进数组
      const tmpArr1 = placeMarkerList.value.filter(
        (item) => item.getExtData().placeId !== placeForm.value.placeId
      )
      tmpArr1.push(tmpMarker)
      placeMarkerList.value = tmpArr1
    } catch (error) {
      console.log(error)
    }
  }
}

function getCount(schoolId) {
  return tableData.value.filter((item) => item.schoolId === schoolId).length
}

const showSchool = ref(true)
const showAllSchool = ref(false)
const fullScreenPlaceList = ref(false)
const placeListDialogTitle = ref('')
const tableSearch = ref('')
const tableData = ref([])

const placeTableData = computed(() => {
  if (tableSearch.value) {
    return tableData.value.filter(
      (dataNews) =>
        dataNews.schoolId === currentdeptId.value && dataNews.name.includes(tableSearch.value)
    )
  }
  return tableData.value.filter((dataNews) => dataNews.schoolId === currentdeptId.value)
})

function showAllSchoolChange() {
  schoolList.value.forEach((item) => (item.showInMap = !showAllSchool.value))
  tableData.value.forEach((item) => (item.schoolShow = !showAllSchool.value))
  resetMarkers()
}

function toggleSchool() {
  showSchool.value = !showSchool.value
}

function closePlaceList() {
  placeListDialogShow.value = false
  fullScreenPlaceList.value = false
}

async function changePlaceStatus(row) {
  try {
    // 修改状态的二次确认
    const text = row.status == 0 ? '启用' : '停用'
    await message.confirm('确认要"' + text + '""' + row.name + '"场地吗?')
    // 发起修改状态
    await PlaceApi.updatePlaceStatus(row.placeId, row.status)
    message.success('修改成功')
    // 刷新列表
    // await getPageData()
    tableData.value.find((item) => item.placeId == row.placeId).status = row.status
    resetMarkers()
  } catch {
    // 取消后，进行恢复按钮
    row.status = row.status == 0 ? 1 : 0
  }
}

// const isRanging = ref(false)
const placeForm = ref({
  lat: undefined,
  lng: undefined,
  name: undefined,
  address: undefined,
  introduce: undefined,
  phone: undefined,
  flagColor: 'red'
})
// const selectMarker = ref(null)
const placeMarkerList = ref([])

// 编辑场地
function handleEditPlace(item) {
  placeDialogShow.value = true
  dialogMap.value.setDefaultCursor('default')
  // 方法已废弃
  // if (selectMarker.value) {
  //   selectMarker.value.setAnimation('AMAP_ANIMATION_NONE')
  // }
  // isRanging.value = false
  placeForm.value = Object.assign({}, item)
  // selectMarker.value = placeMarkerList.value.find(
  //   (marker) => marker.getExtData().placeId === item.placeId
  // )
  // 方法已废弃
  // selectMarker.value && selectMarker.value.setAnimation('AMAP_ANIMATION_BOUNCE')
  dialogMap.value.setCenter([item.lng, item.lat])
}

const placeDialogShow = ref(false)

// 重置markers
function resetMarkers() {
  dialogMap.value.clearMap()
  createMarkersInMap()
}

function getDictOptions() {
  getAreaSimpleList().then((data) => {
    areaOptions.value = data
  })
}

onMounted(() => {
  initMap()
  getDictOptions()
})
</script>

<style lang="scss" scoped>
.asider {
  position: absolute;
  right: 0;
  top: 0;
  width: 300px;
  height: 100%;
  transition: 0.3s;
  z-index: 9;
}

.box-card {
  display: flex;
  flex-direction: column;
  height: 100%;
}

::v-deep(.el-card__header) {
  padding: 10px 15px;
}

.clearfix {
  display: flex;
}

.clearfix .map-card-title {
  flex: 1;
  line-height: 30px;
}

.clearfix .add-icon {
  width: auto;
  height: 30px;
}

.asider-sub {
  position: absolute;
  top: 40px;
  left: -45px;
  padding: 10px 10px 0 0;
  z-index: 900;
}

.asider-sub .is-circle {
  // display: block;
  margin: 0;
  padding: 10px;
  color: #464646;
  border-radius: 0;
  font-size: 16px;
  box-shadow: 2px 2px 2px rgba(80, 80, 80, 0.67);
}

.mt10 {
  margin-top: 10px;
}

.hidden-school {
  transform: translateX(300px);
}

.search-body {
  position: absolute;
  top: 20px;
  left: 20px;
  width: 400px;
}

::v-deep(.place-dialog) {
  position: absolute;
  left: 20px;
  top: 20px;
  width: 350px;
}

.map-tip {
  position: absolute;
  left: 0;
  top: 0;
  max-width: 150px;
  padding: 5px;
  border-radius: 2px;
  background: #000;
  color: #fff;
  opacity: 0.7;
  font-size: 12px;
  transition-duration: 1ms;
}

.circle {
  position: absolute;
  left: -8px;
  top: -25px;
  font-size: 24px;
  color: red;
  transition-duration: 1ms;
}

.add-place-btn {
  float: right;
  border: none;
  font-size: 16px;
  color: #409eff;
}

.place-dialog .el-form .el-form-item {
  margin-bottom: 8px;
}

.place-list-dialog {
  position: absolute;
  top: 420px;
  left: 0;
  bottom: 0;
  transition: 0.3s;
  z-index: 151;
  background: #e2e5ea;
}

.place-list-dialog .add-icon {
  font-size: 18px;
  border: none;
}

.hidden-place-list {
  transform: translateY(100%);
}

.place-list-dialog .clearfix .map-card-title {
  font-weight: bold;
}

.place-list-dialog .clearfix .map-card-title .el-input {
  margin-left: 20px;
  width: 240px;
}

.actived-school {
  border: 2px solid #409eff !important;
}

::v-deep(.el-radio__label) {
  vertical-align: middle;
}
</style>
