<script setup>
import { ref, computed, watch, onMounted } from "vue"
import { useRouter, useRoute } from 'vue-router'
import positionMaps from '../static/positionMaps.js'
import imagePositionMaps from '../static/imagePositionMaps.js'
import { Request, Storage } from "../libs/utils"
import { globalStore } from "../globalstore.js";
import faceTemplate from "../static/ali_face_template.js";
import MyPhoto from './MyPhoto.vue'
import PhotoSquare from './PhotoSquare.vue'
import { loadFaceApiModels, validateFaceInImage } from "../libs/faceValidator.js"

defineProps({
  show: true
})

onMounted(async () => {
  await loadFaceApiModels()
})

import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue';
import { tr } from "element-plus/es/locales.mjs"
const router = useRouter();

// 上传前的校验
const beforeUpload = (file) => {
  // 基础格式校验
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  if (!isJpgOrPng) {
    ElMessage.error('只能上传JPG或PNG格式的图片!');
    return false;
  }
  
  const isLt2M = file.size / 1024 / 1024 < 5;
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过5MB!');
    return false;
  }
  
  return new Promise(async (resolve) => {
    const loadingInstance = ElMessage({
      message: '正在验证人脸...',
      type: 'info',
      duration: 0,
      showClose: false
    });
    
    try {
      const faceValidationResult = await validateFaceInImage(file);
      loadingInstance.close();
      
      if (!faceValidationResult.success) {
        ElMessage({
          message: faceValidationResult.message,
          type: 'error',
          duration: 4000
        });
        resolve(false);
      } else {
        ElMessage({
          message: faceValidationResult.message,
          type: 'success',
          duration: 2000
        });
        resolve(true);
      }
      
    } catch (error) {
      loadingInstance.close();
      console.error('人脸验证出错:', error);
      ElMessage({
        message: '人脸验证失败，请重试',
        type: 'error',
        duration: 3000
      });
      resolve(false);
    }
  });
};

const getTemplateIdsFromUrl = (response, url, index)=> {
  const filename = url.split('/').pop();
  const matchedTemplate = faceTemplate.find(template => filename.includes(template.name));
  if (!matchedTemplate) {
    console.error(`No template found for filename: ${filename}`);
    return null;
  }

  const dataItem = matchedTemplate.data[index];
  if (!dataItem) {
    console.error(`No data found at index ${index} for template: ${filename}`);
    return null;
  }

  return  {
      "mergeId": response.id,
      "template_id": matchedTemplate.template_id,
      "templateFaceID": dataItem.templateFaceID
    }
  ;
}

// 上传成功回调
const handleSuccess = (response, index) => {
  // 上传成功后，将文件信息添加到数组
  if (response) {
    const ids = getTemplateIdsFromUrl(response, globalStore.select_template, index);
    uploadedFiles.push({
      templateIds: ids
    });
  }
  if (response && response.url) {
    uploadItems.value[index].imageUrl = response.url;
    ElMessage.success('上传成功！');
  }
  if (response && response.message !== 'success') {
    ElMessage.error(response.message);
  }
};

// 上传失败回调
const handleError = (error) => {
  console.error('上传失败:', error);
  ElMessage.error('上传失败，请重试！');
};

const uploadItems = ref([])

const initializeUploadItems = (item) => {
  if (!item) {
    router.push({
      name: 'home'
    });
  }
  const count = globalStore.people_count;
  
  const items = Array(count).fill(null).map(() => ({
    imageUrl: '',
    uploadData: {}
  }))

  uploadItems.value = items
}

const route = useRoute()
const imageUrl = ref(globalStore.select_template);

watch(imageUrl, (item) => {
  initializeUploadItems(item)
}, { immediate: true })

const uploadRefs = ref([]);

// 删除图片
const clearUploadFile = (index) => {
  if (uploadRefs.value[index]) {
    uploadRefs.value[index].clearFiles();
    uploadItems.value[index].imageUrl = '';
    
    uploadedFiles.splice(index, 1);
  }
};

// 存储上传成功的文件数据
const uploadedFiles = [];
const currentImageUrl = ref(null)

const faces = [];
const displayMyPhotoBtn = ref(false);
const displayScanImg = ref(false);
const disableScanAnimation = ref(false);
const generateImage = async (options) => {
  console.log(uploadedFiles);
  if (uploadedFiles.length === 0) {
    weui.alert("请上传头像照片！")
    return false;
  }
  globalStore.generateStatus = true;
  displayScanImg.value = true;
  const urlParams = new URLSearchParams(window.location.search);
  currentImageUrl.value = urlParams.get('imageUrl');
  

  disableClick.value = true;
  displayScanModel.value = true;

  uploadedFiles.forEach(file => {
    globalStore.generateImgTemplates.push({
      merge_id: file.templateIds.mergeId,
      backgroundImg: currentImageUrl.value
    });
    faces.push({
      image_id: file.templateIds.mergeId,
      template_face_id: file.templateIds.templateFaceID
    });
  });

  const formData = {
    "template_id": uploadedFiles[0].templateIds.template_id,
    "faces": faces,
    "is_public": false
  }

  try {
    const loading = weui.loading();
    const response = await fetch('https://huodong2.lzlj.com/api/faceFamily/face/merge', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Accept: "application/json",
        'Authorization': `Bearer ${Storage.get("userinfos").api_token}`
      },
      body: JSON.stringify(formData)
    });

    const data = await response.json()
    if (response.status == 200 || response.status == 201) {
      globalStore.mergeId = data.merge_id;
      const navigateToSynthesizedResults = () => {
        router.push({
          name: 'synthesizedResults'
        })
      }
      
      let index = 0
      const max = 4;
      const Timer = setInterval(()=>{
        if (index >= max) {
          loading.hide();
          clearInterval(Timer)
        } else {
          index++
          mergeFetch(index)
        }
      }, 1000)

      const mergeFetch = async (index)=> {
        const statusRes = await Request(`face/merge/${data.merge_id}/status`, {}, 'GET', true)

        if (statusRes.res.status === 200) {
          if (statusRes.json.status === 'success') {
            displayMyPhotoBtn.value = false;
            loading.hide();
            clearInterval(Timer)
            navigateToSynthesizedResults();
            globalStore.result_url = statusRes.json.result_url;
          } else {
            if (index === 4) {
              disableScanAnimation.value = true;
              displayMyPhotoBtn.value = true;
            }
          }
        } else {
          if (index === 4) {
            disableScanAnimation.value = true;
            displayMyPhotoBtn.value = true;
          }
        }
      }
    } else {
      ElMessage.error(data.message);
      loading.hide();
    }
    
  } catch (error) {
    console.error('Merge API error:', error);
    loading.hide();
  }
}

const goBack = () => {
  router.back();
};

const currentVersion = computed(() => {
  const url = imageUrl.value;
  const match = url.match(/(shenxian|xianxia|fugu|xinzhongshi|luying|paidui)_(\d)/);
  
  if (!match) return positionMaps.shenxian[1];
  const [_, category, version] = match;
  
  return positionMaps[category]?.[version] || positionMaps.shenxian[1];
});

const buttonPosition = (index) => {
  const versionData = currentVersion.value;
  if (!versionData || !versionData.positions[index - 1]) {
    return {};
  }
  const pos = versionData.positions[index - 1];
  return {
    top : pos.top,
    left : pos.left,
    "--item-width": pos.width
  };
};

const buttonUploadedPosition = (index) => {
  const versionData = currentVersion.value;
  if (!versionData?.positions?.[index - 1]) {
    return {};
  }

  const pos = versionData.positions[index - 1];
  const url = imageUrl.value;
  
  const match = url.match(/(shenxian|xianxia|fugu|xinzhongshi|luying|paidui)_(\d)/);
  if (!match) {
    return {
      top: pos.top,
      left: pos.left,
      "--item-width": pos.width
    };
  }

  const [_, category, versionStr] = match;
  const version = parseInt(versionStr);
  
  const originalTop = parseFloat(pos.top);
  if (isNaN(originalTop)) {
    return {
      top: pos.top,
      left: pos.left,
      "--item-width": pos.width
    };
  }

  const ADJUSTMENT_CONFIG = {
    shenxian: { 
      1:16, 2:12, 3:12, 4:10, 5:10, 6:8 
    },
    xianxia: { 
      1:11, 2:12, 3:12, 4:10, 5:10, 6:8 
    },
    fugu: { 
      1:12, 2:14, 3:14, 4:10, 5:10, 6:8 
    },
    xinzhongshi: { 
      1:12, 2:14, 3:8, 4:10, 5:6, 6:8 
    },
    luying: { 
      1:12, 2:14, 3:8, 4:10, 5:6, 6:8 
    },
    paidui:{ 
      1:12, 2:14, 3:12, 4:10, 5:12, 6:8 
    }
  };

  let adjustedTop = originalTop;
  if (ADJUSTMENT_CONFIG[category]?.[version] !== undefined) {
      adjustedTop -= ADJUSTMENT_CONFIG[category][version];
  }

  return {
    top:`${adjustedTop}vw`,
    left :pos.left ,
    "--item-width" :pos.width  
  };
};

const currentImgVersion = computed(() => {
  const url = imageUrl.value;
  const match = url.match(/(shenxian|xianxia|fugu|xinzhongshi|luying|paidui)_(\d)/);
  
  if (!match) return imagePositionMaps.shenxian[1];
  const [_, category, version] = match;
  
  return imagePositionMaps[category]?.[version] || imagePositionMaps.shenxian[1];
});

const imagePosition = (index) => {
  const versionData = currentImgVersion.value;
  if (!versionData || !versionData.positions[index - 1]) {
    return {};
  }
  const pos = versionData.positions[index - 1];
  return {
    top : pos.top,
    left : pos.left,
    width: pos.width,
    height: pos.width
  };
};

// 自定义上传方法
const customUpload = async (options) => {
  const loading = weui.loading()
  const { file, data, onProgress, onSuccess, onError } = options
  
  try {
    const formData = new FormData()
    formData.append('type', 'ali-face')
    formData.append('image', file)

    fetch('https://huodong2.lzlj.com/api/faceFamily/upload/image', {
      method: 'POST',
      headers: {
          'Authorization': `Bearer ${Storage.get("userinfos").api_token}`
      },
      body: formData
    })
    .then(async response => {
      const data = await response.json()
      if (response.status == 200 || response.status == 201) {
        loading.hide();
        onSuccess(data);
      } else {
        ElMessage.error(data.message);
        loading.hide();
      }
    })
    .catch((error) => {
      loading.hide();
      console.error('Error:', error);
    });    
  } catch (error) {
    loading.hide();
    onError(error)
    throw error
  }
}

const displayScanModel = ref(false);
const disableClick = ref(false);

const isMyPhotoVisible = ref(false);
const isPhotoSquareVisible = ref(false);
const showMyPhoto = () => {
  router.push({
    name: 'home',
    query: { myPhotoValue: true }
  })
  isMyPhotoVisible.value = true;
  // displayMyPhotoBtn.value = false;
  isPhotoSquareVisible.value = false;
};

const showPhotoSquare = () => {
  isMyPhotoVisible.value = false;
  isPhotoSquareVisible.value = true;
};

import imgLoading from '../assets/images/generate-img-loading-bg.webp'
import generateImg from '../assets/images/generate-img-bg.webp'
</script>

<template>
  <div :show="show" class="main">
    <div class="home-wrapper" :style="{
      backgroundImage: displayScanModel 
        ? `url(${imgLoading})`
        : `url(${generateImg})`
    }">
      <div class="scene-item item-1">
        <img src="../assets/images/back-btn.webp" @click="goBack" alt="后退">
      </div>

      <div v-if="!isMyPhotoVisible && !isPhotoSquareVisible" class="scene-item img-from-template scene-item-img" 
      :style="{ pointerEvents: displayMyPhotoBtn ? 'none' : 'auto' }" >
        <img :src="imageUrl" alt="模板图片">
      </div>

      <div v-if="!displayScanModel" class="scene-item item-2">
        <img src="../assets/images/generate-title.webp" alt="描述">
      </div>

      <div v-if="!displayScanModel" class="scene-item item-3" @click="generateImage">
        <img src="../assets/images/generate-btn.webp" alt="开始合成">
      </div>

      <div class="scene-item item-4" v-if="displayScanModel && !isMyPhotoVisible && !isPhotoSquareVisible">
        <img src="../assets/images/scan.webp" class="blocked-image" alt="扫描框">
      </div>
      <img v-if="displayScanImg" src="../assets/images/scan-line.webp" class="moving-image"
       :style="{ animationPlayState: disableScanAnimation ? 'paused' : 'running' }" alt="扫描line">

      <div v-if="displayMyPhotoBtn" class="scene-item item-5" @click="showMyPhoto" >
        <img src="../assets/images/my-photo-btn.webp" class="blocked-image" alt="查看我的照片">
      </div>

      <div v-if="!isMyPhotoVisible && !isPhotoSquareVisible" class="upload-container">
        <div v-for="(item, index) in uploadItems" :key="index" class="upload-item-wrapper">
          <el-upload
            :ref="(el) => (uploadRefs[index] = el)"
            :http-request="customUpload"
            :show-file-list="false"
            :before-upload="beforeUpload"
            :on-success="(res) => handleSuccess(res, index)"
            :on-error="handleError"
            :data="item.uploadData"
            accept="image/*"
          >
            <el-button class="upload-img-wrapper upload-btn" :style="buttonPosition(index + 1)">
              <div class="scene-item item scene-item-img" :class="{ uploaded: item.imageUrl, 'no-pointer-events': disableClick }"
              :style="{ width: buttonPosition(index + 1)['--item-width'], 'z-index': 11 }">
                <img 
                  v-if="!item.imageUrl"
                  src="../assets/images/upload-img.webp" 
                  alt="上传图片"
                >
                <div v-if="!item.imageUrl"></div>
              </div>
            </el-button>
          </el-upload>

          <!-- 图片预览 -->
          <div v-if="item.imageUrl" class="preview-container" :style="{ pointerEvents: displayMyPhotoBtn ? 'none' : 'auto' }">
            <div class="preview-image upload-btn" :style="imagePosition(index + 1)">
              <img 
                :src="item.imageUrl" 
                alt="预览图"
                class="pre-img"          
              />
            </div>
            <button @click.stop.prevent="clearUploadFile(index)" :style="buttonUploadedPosition(index + 1)" style="position: absolute;">
              <div :style="{ width: buttonUploadedPosition(index + 1)['--item-width'] }" >
                <img src="../assets/images/img-uploaded.webp" class="delete-btn upload-img-wrapper" alt="删除图片">
              </div>
            </button>
          </div>
          <template v-else>
            <Plus />
          </template>
        </div>
      </div>
    </div>
  </div>
  <MyPhoto 
    @go-photo-square="showPhotoSquare" 
    v-model:show="isMyPhotoVisible" 
  />
  <PhotoSquare 
    @go-my-photo="showMyPhoto" 
    v-model:show="isPhotoSquareVisible" 
  />
</template>

<style scoped>
.pre-img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  object-position: top;
}
.main {
  height: 100%;
  overflow-y: auto;
}
.moving-image {
  width: 100%;
  position: absolute;
  animation: moveUpDown 3s linear infinite;
  z-index: 9;
}

@keyframes moveUpDown {
  0%, 100% {
    top: 44vw;
    transform: translateY(0);
  }
  50% {
    top: calc(100% + -40vw);
    transform: translateY(-100%);
   }
}
.no-pointer-events {
  pointer-events: none;
}
.scene-item-img {
  transition: none !important;
}
.preview-image {
  z-index: 999;
}
.delete-btn {
  position: relative;
  width: 100%;
  z-index: 999;
}
.uploaded {
}
.upload-btn {
  position: absolute;
}
.remove-img-1 {
  top: 31.6%;
  left: 24%;
  position: absolute;
}
.remove-img-2 {
  top: 30.4%;
  left: 44.2%;
  position: absolute;
}
.remove-img-3 {
  top: 39.4%;
  left: 57.2%;
  position: absolute;
}
.remove-img-4 {
  top: 34.4%;
  left: 72.2%;
  position: absolute;
}
.remove-img-5 {
  top: 48.4%;
  left: 37.2%;
  position: absolute;
}
.upload-img-wrapper.el-button {
  background: transparent !important;
  background-color: transparent !important;
  border: none !important;
  border-color: transparent !important;
  padding: 0 !important;
  margin: 0 !important;
  color: inherit !important;
  box-shadow: none !important;
  text-shadow: none !important;
  cursor: pointer;
  outline: none !important;
  
  border-radius: 0 !important;
  height: auto !important;
  line-height: inherit !important;
  width: auto !important;
  min-width: auto !important;
  display: inline-block !important;
  justify-content: inherit !important;
  align-items: inherit !important;
  transition: none !important;
}

.upload-img-wrapper.el-button:hover,
.upload-img-wrapper.el-button:focus,
.upload-img-wrapper.el-button:active {
  background: transparent !important;
  background-color: transparent !important;
  border: none !important;
  border-color: transparent !important;
  box-shadow: none !important;
  color: inherit !important;
  outline: none !important;
}
.home-wrapper {
  width: 100vw;
  height: 200vw;
  background-size: 100%;
  background-repeat: no-repeat;
  margin-top: -8vw;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: relative;
}
.img-from-template {
  width: 75vw;
  height: 103vw;
  margin-top: -6vw;
  border-radius: 16px !important;
  margin-left: 1vw;
}
.scene-item {
  position: absolute;
  z-index: 2;
  cursor: pointer;
  border-radius: 8px;
  transition: all 0.4s ease;
  overflow: hidden;
  border: 3px solid transparent;
  animation: float 4s ease-in-out infinite;
}

.scene-item:hover {
  z-index: 10;
}

.scene-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.item-1 {
  width: 5vw;
  top: 6.7%;
  left: 5%;
  animation-delay: 0s;
}

.item-2 {
  width: 70vw;
  bottom: 15%;
  animation-delay: 0s;
}

.item-3 {
  width: 54vw;
  bottom: 6vw;
  animation-delay: 0s;
}

.item {
  width: 17vw;
}
.item-4 {
  width: 72vw;
  top: 48vw;
  pointer-events: none;
}
.item-5 {
  width: 48vw;
  bottom: 3vw;
  animation-delay: 0s;
}
</style>