<script setup lang="ts">
import {ref, onMounted, reactive, nextTick} from "vue";
import {Close} from '@vicons/carbon';
import {t} from "@/language";
import {fetchSceneExampleList} from "@/http/api/sceneExample";
import ProjectInfoForm from "@/components/project/ProjectInfoForm.vue";
import {App,defaultProjectInfo} from "@astral3d/engine";
import CesiumConfig from "@/components/project/CesiumConfig.vue";
import {fetchAddScene} from "@/http/api/scenes";
import EsTip from "@/components/es/EsTip.vue";
import {getServiceStaticFile} from "@/utils/common/file";

withDefaults(defineProps<{
  visible: boolean
}>(), {
  visible: false
})
const emits = defineEmits(['update:visible', "refresh"]);

const projectInfoFormRef = ref();
const cesiumConfigRef = ref();

const spin = ref(false);

const settingTabsValue = ref("project");
const currentType = ref<"Web3D" | "WebGIS">("Web3D");
const currentExample = ref<ISceneFetchData | null>(null);
const typeList: { name: string, type: "Web3D" | "WebGIS", img: string,isDev:boolean }[] = [
  {name: "Web3D", type: "Web3D", img: "/static/images/placeholder/Web3D.jpg",isDev:false},
  // {name: "WebGIS", type: "WebGIS", img: "/static/images/placeholder/WebGIS.jpg",isDev:true},
];
const exampleList = reactive<{
  Web3D: ISceneFetchData[],
  WebGIS: ISceneFetchData[]
}>({
  Web3D: [],
  WebGIS: []
})

async function getExampleScene() {
  const res = await fetchSceneExampleList({
    limit: 1000
  })
  if (res.data === null) return;

  res.data.items.forEach(item => {
    switch (item.projectType) {
      case 0:
        exampleList.Web3D.push(item);
        break;
      case 1:
        exampleList.Web3D.push(item);
        break;
    }
  })
}

// 切换场景类型
function handleChangeProjectType(type) {
  if(type.isDev){
    window.$message?.warning(`${type.name}: ${t("prompt['Related modules are under development, unstable versions.']")}`)
  }

  currentType.value = type.type;

  // 选中空场景
  currentExample.value = null;
  App.project.setKey("sceneInfo",defaultProjectInfo().sceneInfo);

  settingTabsValue.value = '';
  nextTick(() => {
    settingTabsValue.value = 'project';
  })
}

// 选中示例模板
function handleSelectExample(example: ISceneFetchData | null) {
  currentExample.value = example;

  App.project.setKey("sceneInfo",example || defaultProjectInfo().sceneInfo);
}

// 确认创建项目
function handleSubmit() {
  projectInfoFormRef.value.validate().then(() => {
    const submit = async () => {
      const data: ISceneFetchData = projectInfoFormRef.value.getData();
      let cesiumData;
      if (currentType.value === 'WebGIS') {
        cesiumData = cesiumConfigRef.value.getData();
        data.projectType = 1;
      }

      spin.value = true;
      const res = await fetchAddScene({
        ...data,
        id: "",
        zip: "",
        coverPicture:"",
        sceneVersion:1,
        exampleSceneId: data.id,
        cesiumConfig: cesiumData ? JSON.stringify(cesiumData) : undefined
      })

      spin.value = false;

      if (res.error === null) {
        window.$dialog.success({
          title: t("other.Tips"),
          content: t("prompt['The project is created successfully. Do you want to enter?']"),
          positiveText: t("other.Ok"),
          negativeText: t('other.Cancel'),
          onPositiveClick: () => {
            // 新窗口打开项目
            window.open(window.location.origin + "/#/editor/" + res.data.id, "_blank");

            emits('update:visible', false);
            // 刷新父页面列表
            emits('refresh');
          },
          onNegativeClick: () => {
            emits('update:visible', false);
            // 刷新父页面列表
            emits('refresh');
          }
        })
      }
    }

    // 如果是创建GIS项目，还得验证GIS表单
    if (currentType.value === 'WebGIS') {
      cesiumConfigRef.value.validate().then(() => {
        submit();
      }).catch(() => {
        settingTabsValue.value = 'cesium'
      })
    } else {
      submit();
    }
  }).catch(() => {
    settingTabsValue.value = 'project'
  })
}

onMounted(() => {
  getExampleScene()
})
</script>

<template>
  <n-modal :show="visible" @update:show="(v) => emits('update:visible',v)">
    <n-spin :show="spin">
      <n-card :title="t('home.New project')" :bordered="false" size="small" class="w-max"
              header-style="background:var(--n-color);">
        <template #header-extra>
          <n-icon size="20" class="cursor-pointer" @click="emits('update:visible',false)">
            <Close/>
          </n-icon>
        </template>

        <div class="flex flex-wrap justify-between pt-20px h-max">
          <div class="flex flex-col mr-20px">
            <div v-for="type in typeList" :key="type.type" @click="handleChangeProjectType(type)"
                 class="relative cursor-pointer">
              <img width="300" :src="type.img" class="mb-15px b-rd-2 transition-all-500"
                   :style="{border:currentType === type.type ? '2px solid var(--n-color-target)' : '2px solid transparent'}"/>
              <p class="text-16px absolute bottom-30px left-10px" style="text-shadow: 1px 1px 2px black;">
                {{ type.name }}</p>

              <EsTip v-if="type.isDev" size="25" class="absolute top-10px right-10px">
                {{ t("prompt['Related modules are under development, unstable versions.']") }}
              </EsTip>
            </div>
          </div>

          <div class="grid grid-cols-3 gap-10px grid-auto-rows-max w-560px max-h-full mr-10px">
            <div style="grid-column: 1 / -1;">
              <h4>{{ t("home.Template") }}</h4>
              <n-divider class="!my-10px"/>
            </div>

            <n-card hoverable @click="handleSelectExample(null)"
                    class="w-178px h-max cursor-pointer"
                    :style="{border:currentExample === null ? '1px solid var(--n-color-target)' : '1px solid transparent'}"
                    :footer-style="`background:var(${currentExample === null ? '--n-color-target' : '--n-action-color'});padding:10px;`">
              <template #cover>
                <img src="/static/images/carousel/Astral3DEditor.jpg" :alt="t('home.Empty project')"
                     class="h-110px hover:transform-scale-140 transition-all-200">
              </template>

              <template #footer>
                <span> {{ t("home.Empty project") }} </span>
              </template>
            </n-card>

            <n-card hoverable v-for="example in exampleList[currentType]" :key="example.id"
                    @click="handleSelectExample(example)"
                    class="w-178px h-max cursor-pointer"
                    :style="{border:currentExample === example ? '1px solid var(--n-color-target)' : '1px solid transparent'}"
                    :footer-style="`background:var(${currentExample === example ? '--n-color-target' : '--n-action-color'});padding:10px;`">
              <template #cover>
                <n-tag type="success" :bordered="false" class="absolute top-10px right-10px z-10">
                  {{ example.sceneType }}
                </n-tag>
                <img :src="getServiceStaticFile(example.coverPicture) || '/static/images/carousel/Astral3DEditor.jpg'" :alt="example.sceneName"
                     class="h-110px hover:transform-scale-140 transition-all-200">
              </template>

              <template #footer>
                <span> {{ example.sceneName }} </span>
              </template>
            </n-card>
          </div>

          <div class="h-full flex">
            <n-divider vertical class="!h-auto"/>

            <div class="h-full w-320px flex flex-col justify-start ml-10px">
              <img :src="getServiceStaticFile(currentExample?.coverPicture || '') || '/static/images/carousel/Astral3DEditor.jpg'" class="w-full">

              <h3 class="mt-10px mb-8px">{{ currentExample?.sceneName || t("home.Empty project") }}</h3>
              <p class="h-100px overflow-y-auto">
                {{
                  currentExample === null ? t("home.A blank project without any scene elements") : currentExample.sceneIntroduction
                }}</p>

              <n-button tertiary size="small" class="mt-8px w-full text-left block">
                {{ t("home.Project default settings") }}
              </n-button>

              <n-tabs v-model:value="settingTabsValue" type="segment" size="small"
                      class="project-setting-tabs mt-24px" pane-class="h-220px">
                <n-tab-pane name="project" :tab="t('home.Project')" display-directive="show">
                  <ProjectInfoForm :value="currentExample" ref="projectInfoFormRef" class="!p-15px"/>
                </n-tab-pane>
                <n-tab-pane name="cesium" tab="Cesium" v-if="currentType === 'WebGIS'" display-directive="show">
                  <CesiumConfig ref="cesiumConfigRef" class="!p-15px"/>
                </n-tab-pane>
              </n-tabs>

              <div class="w-full text-end mt-15px">
                <n-button type="primary" size="small" @click.stop="handleSubmit">{{ t("other.Ok") }}</n-button>
                <n-button size="small" class="ml-10px" @click="emits('update:visible',false)">{{ t("other.Cancel") }}
                </n-button>
              </div>
            </div>
          </div>
        </div>
      </n-card>
    </n-spin>
  </n-modal>
</template>

<style scoped lang="less">
.project-setting-tabs {
  :deep(.n-tabs-nav) {
    justify-content: center;

    .n-tabs-rail {
      width: 50%;
    }
  }
}
</style>