<template>
  <RightFillPano>
    <ui-group title="初始画面" borderBottom>
      <ui-group-option>
        <div class="init-pic" :class="{ disabled: isEdit }">
          <img :src="getFileUrl(setting!.cover)" class="init-puc-cover" />
          <div class="init-pic-set" @click="enterSetPic">设置</div>
        </div>
      </ui-group-option>
    </ui-group>

    <ui-group title="指北针">
      <template #icon>
        <ui-icon
          ctrl
          :type="setting?.openCompass ? 'eye-s' : 'eye-n'"
          @click="
            changeBack(
              setting!.back,
              setting!.backType,
              !setting!.openCompass,
              setting!.mapOpen,
              setting!.mapType,
              { scale: setting!.scale!, rotate: setting?.rotate! }
            )
          "
        />
      </template>
    </ui-group>

    <ui-group title="地图" v-if="caseProject!.tmProject?.latlng">
      <template #icon>
        <ui-icon
          ctrl
          :type="setting?.mapOpen ? 'eye-s' : 'eye-n'"
          @click="
            changeBack(
              setting!.back,
              setting!.backType,
              setting!.openCompass,
              !setting!.mapOpen,
              setting!.mapType,
              { scale: setting!.scale!, rotate: setting?.rotate! }
            )
          "
        />
      </template>
      <ui-group-option v-if="setting?.mapOpen">
        <ui-input
          type="select"
          width="100%"
          :options="[
            { label: '卫星地图', value: 'satellite' },
            { label: '矢量地图', value: 'standard' },
          ]"
          :modelValue="setting!.mapType"
          @update:modelValue="(e: string )=> changeBack(setting!.back, setting!.backType, setting!.openCompass, setting!.mapOpen, e, {scale: setting!.scale!, rotate: setting?.rotate!})"
        />
      </ui-group-option>
    </ui-group>

    <ui-group title="视角范围">
      <ui-group-option class="ant-modal-root">
        <Slider
          :value="setting!.fov || 70"
          :min="40"
          :step="1"
          :max="100"
          @update:value="(val: any) => changeFov(val)"
        />
      </ui-group-option>
    </ui-group>

    <ui-group title="设置背景">
      <ui-group-option>
        <div class="back-layout">
          <div
            v-for="back in settingResources"
            :key="back.resource"
            class="back-item"
            :class="{ [back.backType]: true, active: setting!.back === back.resource }"
            @click="
              setting!.back !== back.resource &&
                changeBack(
                  back.resource,
                  back.backType,
                  setting!.openCompass,
                  setting!.mapOpen,
                  setting!.mapType,
                  { scale: setting!.scale!, rotate: setting?.rotate! }
                )
            "
          >
            <img
              :src="back.covre || back.resource"
              v-if="back.backType === 'img' || back.backType === 'bimg'"
            />
            <i
              class="iconfont"
              :class="back.resource"
              v-else-if="back.backType === 'icon'"
            />
            <span :style="{ background: back.resource }" v-else></span>

            <a class="back-item-desc">
              {{
                (settingResourceTypeDesc[back.backType] &&
                  settingResourceTypeDesc[back.backType] + "-") + back.name
              }}
            </a>

            <ui-icon
              v-if="!back.sys"
              type="close"
              class="del"
              @click.stop="delBack(back)"
            />
          </div>
          <ui-input
            class="input"
            preview
            accept=".jpg, .jpeg, .png"
            @update:modelValue="iconUpload"
            type="file"
          >
            <template v-slot:replace>
              <div class="back-item icon">
                <i class="iconfont icon-add" />
              </div>
            </template>
          </ui-input>
        </div>
      </ui-group-option>
    </ui-group>
    <Teleport
      to="#layout-app"
      v-if="
        (setting?.backType === SettingResourceType.bottomImage &&
          $router.currentRoute.value.name === RoutesName.setting)
      "
    >
      <div class="slider-demo-block-group">
        <div class="slider-demo-block ant-modal-root">
          <span> 缩放</span>
          <Slider
            :value="setting!.scale || 1"
            :min="0.1"
            :step="0.01"
            :max="3"
            @update:value="(val: any) => changeBack(setting!.back, setting!.backType, setting!.openCompass, setting!.mapOpen, setting!.mapType, {scale: val, rotate: setting?.rotate!})"
          />
        </div>
        <div class="slider-demo-block ant-modal-root">
          <span> 旋转</span>
          <Slider
            :value="setting!.rotate || 0"
            :min="0.1"
            :step="0.01"
            :max="360"
            @update:value="(val: any) => changeBack(setting!.back, setting!.backType, setting!.openCompass, setting!.mapOpen, setting!.mapType, {scale: setting!.scale!, rotate: val})"
          />
        </div>
      </div>
    </Teleport>
  </RightFillPano>

  <div class="edit-add-type" v-if="addTemp">
    <div class="edit-hot-item">
      <h3 class="edit-title">
        背景图
        <ui-icon
          type="close"
          ctrl
          @click.stop="addTemp = undefined"
          class="edit-close"
        />
      </h3>

      <ui-input
        require
        class="input"
        width="100%"
        placeholder="请输入背景图名称标注"
        type="text"
        v-model="addTemp.name"
        maxlength="15"
      />
      <ui-input
        require
        class="input"
        width="100%"
        placeholder="请输入背景图名称标注"
        type="select"
        :options="options"
        v-model="addTemp.backType"
        maxlength="15"
      />
      <div class="edit-hot">
        <a @click="addBack">
          <ui-icon type="nav-edit" />
          确定
        </a>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { RightFillPano } from "@/layout";
import {
  enterEdit,
  enterOld,
  setting,
  isEdit,
  updataSetting,
  caseProject,
  createTemploraryID,
  save,
} from "@/store";
import { ref } from "vue";
import { togetherCallback, getFileUrl, loadPack, asyncTimeout } from "@/utils";
import { showRightPanoStack, showRightCtrlPanoStack } from "@/env";
import { sdk, setBackdrop, setMap } from "@/sdk";
import {
  delSettingResource,
  fetchSettingResources,
  settingResources,
  settingResourceTypeDesc,
} from "@/api/setting-resource";
import { uploadFile } from "@/api";
import { SettingResource, addSettingResource } from "@/api/setting-resource";
import { SettingResourceType } from "@/api/setting-resource";
import { Dialog } from "bill/index";
import { Slider } from "ant-design-vue";
import { RoutesName } from "@/router";

fetchSettingResources();

const addBack = async () => {
  if (!addTemp.value!.name.trim()) {
    Dialog.alert("请输入名称");
    return;
  }
  await addSettingResource(addTemp.value!);
  addTemp.value = undefined;
  await fetchSettingResources();
};
const enterSetPic = () => {
  enterEdit(
    togetherCallback([
      showRightPanoStack.push(ref(false)),
      showRightCtrlPanoStack.push(ref(false)),
    ])
  );
  enterOld(async () => {
    const dataURL = await sdk.screenshot(300, 150);
    const res = await fetch(dataURL);
    const blob = await res.blob();
    setting.value = {
      ...setting.value!,
      cover: { url: dataURL, blob },
      pose: sdk.getPose(),
    };
    await updataSetting();
  });
};

const initBack = setting.value!.back;
const initType = setting.value!.backType;
const initOpenCompass = setting.value!.openCompass;
const initopenMap = setting.value!.mapOpen;
const initmapType = setting.value!.mapType;
const initScale = setting.value!.scale;
const initRotate = setting.value!.rotate;
let isFirst = true;
const changeBack = (
  back: string,
  type: SettingResourceType,
  openCompass: boolean,
  openMap: boolean,
  mapType: string,
  tb: { scale: number; rotate: number } = { scale: 1, rotate: 0 }
) => {
  if (
    type === SettingResourceType.map &&
    !caseProject.value!.tmProject?.latlng
  ) {
    Dialog.alert("当前案件没绑定经纬度，无法开启地图功能");
    return;
  }

  setting.value!.back = back;
  setting.value!.backType = type;
  setting.value!.openCompass = openCompass;
  setting.value!.mapOpen = openMap;
  setting.value!.mapType = mapType;
  setting.value!.scale = tb.scale;
  setting.value!.rotate = tb.rotate;

  setBackdrop(back, type, tb);
  setMap(openMap, mapType);

  (document.querySelector("#direction") as HTMLDivElement)!.style.display =
    openCompass ? "block" : "none";

  if (isFirst) {
    let isSave = false;
    isFirst = false;
    enterEdit(() => {
      if (!isSave) {
        setting.value!.back = initBack;
        setting.value!.backType = initType;
        setting.value!.openCompass = initOpenCompass;
        setting.value!.mapOpen = initopenMap;
        setting.value!.mapType = initmapType;
        setting.value!.scale = initScale;
        setting.value!.rotate = initRotate;

        setBackdrop(initBack, initType, {
          scale: initScale,
          rotate: initRotate,
        });
        setMap(initopenMap, initmapType);
        (document.querySelector(
          "#direction"
        ) as HTMLDivElement)!.style.display = initOpenCompass
          ? "block"
          : "none";
      }
      isFirst = true;
    });
    enterOld(async () => {
      isSave = true;
      await loadPack(updataSetting());
    });
  }
};

const delBack = async (back: SettingResource) => {
  if (setting.value?.back === back.resource) {
    changeBack(
      settingResources.value[0].resource,
      settingResources.value[0].backType,
      setting!.value.openCompass,
      setting!.value.mapOpen,
      setting!.value.mapType,
      { scale: setting!.value.scale!, rotate: setting!.value.rotate! }
    );
    await asyncTimeout(100);
    await save();
  }

  const ndx = settingResources.value.indexOf(back);
  if (~ndx) {
    settingResources.value.splice(ndx, 1);
  }
  await delSettingResource(back);
};
const delBack1 = (() => {
  let isFirst = true;
  let oldResources: SettingResource[];
  let dels: SettingResource[] = [];
  return (back: SettingResource) => {
    if (setting.value?.back === back.resource) {
      changeBack(
        settingResources.value[0].resource,
        settingResources.value[0].backType,
        setting!.value.openCompass,
        setting!.value.mapOpen,
        setting!.value.mapType,
        { scale: setting!.value.scale!, rotate: setting!.value.rotate! }
      );
    }

    if (isFirst) {
      dels = [];
      oldResources = [...settingResources.value];
    }
    const ndx = settingResources.value.indexOf(back);
    if (~ndx) {
      settingResources.value.splice(ndx, 1);
      dels.push(back);
    }

    if (isFirst) {
      let isSave = false;
      isFirst = false;

      enterEdit(() => {
        if (!isSave) {
          settingResources.value = oldResources;
        }
        isFirst = true;
      });
      enterOld(async () => {
        isSave = true;
        await loadPack(Promise.all(dels.map(delSettingResource)));
      });
    }
  };
})();

const changeFov = (() => {
  let isFirst = true;
  let initFov: number;
  return (fov: number) => {
    if (isFirst) {
      initFov = setting.value!.fov;
    }
    setting.value!.fov = fov;

    if (isFirst) {
      let isSave = false;
      isFirst = false;
      enterEdit(() => {
        if (!isSave) {
          setting.value!.fov = initFov;
        }
        isFirst = true;
      });
      enterOld(async () => {
        isSave = true;
        await loadPack(updataSetting());
      });
    }
  };
})();

const options = [
  {
    value: SettingResourceType.envImage,
    label: settingResourceTypeDesc[SettingResourceType.envImage],
  },
  {
    value: SettingResourceType.bottomImage,
    label: settingResourceTypeDesc[SettingResourceType.bottomImage],
  },
];
const addTemp = ref<SettingResource>();
const iconUpload = async (data: any) => {
  addTemp.value = {
    resource: await uploadFile({ blob: data.file as any, url: "" }),
    name: "",
    backType: SettingResourceType.envImage,
  };
};
</script>

<style scoped lang="scss">
.init-pic {
  height: 150px;
  border-radius: 4px;
  overflow: hidden;
  position: relative;
}

.init-puc-cover {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.init-pic-set {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(0, 0, 0, 0.5);
  font-size: 12px;
  color: #fff;
  line-height: 32px;
  z-index: 1;
  text-align: center;
  cursor: pointer;
}

.back-layout {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.back-item {
  position: relative;
  > span,
  .iconfont,
  img {
    display: block;
    height: 88px;
    cursor: pointer;
    outline: 2px solid transparent;
    transition: all 0.3s;
    border-radius: 4px;
    width: 88px;
    object-fit: cover;
  }

  .del {
    position: absolute;
    background: #ef4347;
    width: 20px;
    height: 20px;
    top: -10px;
    right: -10px;
    opacity: 0;
    // opacity: 1;
    border-radius: 50%;

    &.iconfont {
      font-size: 10px;
      color: #fff;
    }

    &:hover {
      opacity: 1 !important;
    }
  }

  &:hover .del {
    opacity: 0.9;
  }

  .iconfont {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #525252;
    font-size: 32px;
  }

  img {
    object-fit: cover;
  }

  &.active {
    > span,
    .iconfont,
    img {
      outline-color: #00c8af;
    }
  }
}
:deep(.back-item .del.iconfont) {
  outline-style: none;
}
.back-item-desc {
  font-size: 14px;
  color: #fff;
  margin-top: 10px;
  display: block;
  text-align: center;

  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  -o-text-overflow: ellipsis;

  white-space: nowrap; //文本不会换行
  width: 88px;
}
.edit-add-type {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(4px);
  z-index: 2000;
  padding: 20px;
  overflow-y: auto;

  .edit-hot-item {
    margin: 100px auto 20px;
    width: 400px;
    padding: 20px;
    background: rgba(27, 27, 28, 0.8);
    box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.3);
    border-radius: 4px;

    .input {
      margin-bottom: 10px;
    }
  }
}

.edit-hot {
  margin-top: 20px;
  text-align: right;

  span {
    font-size: 14px;
    color: rgba(255, 255, 255, 0.6);
    cursor: pointer;
  }
}

.edit-close {
  position: absolute;
  cursor: pointer;
  top: calc((100% - 18px) / 2);
  right: 0;
  transform: translateY(-50%);
}

.edit-title {
  padding-bottom: 18px;
  margin-bottom: 18px;
  position: relative;

  &::after {
    content: "";
    position: absolute;
    left: -20px;
    right: -20px;
    height: 1px;
    bottom: 0;
    background-color: rgba(255, 255, 255, 0.16);
  }
}
.slider-demo-block-group {
  position: absolute;
  z-index: 10000;
  padding: 8px 24px;
  background-color: rgba(0, 0, 0, 0.3);
  left: 50%;
  border-radius: 5px;
  bottom: 20px;
  transform: translateX(-50%);
  margin-right: 20px;
  z-index: 99;
  // height: 300px;
  width: 386px;
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
}
.slider-demo-block {
  flex: 1 1 100%;
  display: inline-flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  span {
    padding-right: 10px;
  }
  .ant-slider {
    flex: 1;
  }
}
:global(.ant-modal-root .ant-slider-track) {
  background-color: #00c8af;
}
:global(.ant-modal-root .ant-slider:hover .ant-slider-track) {
  background-color: #00c8af;
}
:global(.ant-modal-root .ant-slider-handle) {
  border: solid 2px #00c8af !important;
}
:global(.ant-modal-root .ant-slider-handle.ant-tooltip-open) {
  border-color: #00c8af;
}
:global(
    .ant-modal-root .ant-slider-handle:focus,
    .ant-modal-root .ant-slider-handle:hover,
    .ant-modal-root .ant-slider-handle:active
  ) {
  border: solid 2px #03ad99 !important;
  box-shadow: none;
}
</style>
