<template>
  <div class="preview-container"> 
    <view class="backstyle_1"></view>
    <view class="backstyle_2"></view>
    <div class="header" @click="goBack">
      <span class="back-icon"><van-icon name="arrow-left" size="16px" /> 效果预览</span>
    </div>
    <div class="step-container">
      <div class="step-item">
        <div class="step-content">
          <div class="step-title">正面照片</div>
          <div class="step-desc">清晰的正面照片</div>
        </div>
      </div>
      <div class="step-item active">
        <div class="step-num">2</div>
        <div class="step-content">
          <div class="step-title">确认下单</div>
          <div class="step-desc">选择一个你喜欢的效果图下单</div>
        </div>
      </div>
    </div>
    <div v-if="!imageUrl" class="progress-section">
      <div class="progress-bar-bg">
        <div class="progress-bar-fg" :style="{ width: progress + '%' }"></div>
      </div>
      <div class="progress-text">{{progressText}} {{progress}}%</div>
      <div class="progress-desc">总计大约需要90秒，请耐心等待...</div>
    </div>
    <div v-else class="progress-section-picture" style="width: 320px;height: 320px;">
      <div class="progress-section-img" style="width: 320px;height: 320px;">
        <img v-if="shapeImage" class="box1-back-image" :src="shapeImage" style="width: 320px;height: 320px;"  alt="">
        <div class="box1-front-box" :style="getStyle">
          <img class="box1-front-image" :src="imageUrl" alt="">
          <!-- <div class="box1-round-shadow" v-if="shapeId == 1 && shapeImage == ''" style="width: 320px;height: 320px;"></div> -->
        </div>
        <div class="shape-text" :style="shapeTextStyle" v-if="shapeText">{{shapeText}}</div>
      </div>
    </div>
    <div class="image-list-box" v-if="imageList.length > 1">
      <div class="image-list-item" v-for="item in imageList" :key="item.key">
        <img v-if="item.status == 1" class="image-list-item-img" :class="{ imgActive: item.key == imgKey }" :src="item.origin_url" alt="" @click="changeImage(item)">
        <div v-else-if="item.status == 0" class="image-list-item-loading">
          设计中
        </div>
        <div v-else-if="item.status == 2" class="image-list-item-loading">
          设计失败
        </div>
      </div>
    </div>
    <div class="info-section">
      <div class="info-item">
        <div class="info-title" v-if="typeId == 1">{{ prodId == 7 ? '人物立体徽章' : '宠物立体徽章' }}</div>
        <div class="info-title" v-if="typeId == 2">{{ prodId == 7 ? '人物浮雕相框' : '宠物浮雕相框' }}</div>
        <div class="info-title" v-if="typeId == 3">{{ prodId == 7 ? '人物3D冰箱贴' : '宠物3D冰箱贴' }}</div>
        <div class="info-content">产品类型</div>
      </div>
      <div class="info-item">
        <div class="info-title">3D全彩打印</div>
        <div class="info-content">工艺</div>
      </div>
      <div class="info-item">
        <div class="info-title">环保树脂</div>
        <div class="info-content">材料</div>
      </div>
    </div>
    <div class="shape-body">
      <div class="shape-type" v-if="imageUrl && typeId == 3">
        <div class="shape-type-item" :class="{ 'shape-active': item.id == shapeId }" v-for="item in shapeList" :key="item.id" @click="shapeChange(item)">{{item.name}}</div>
      </div>
      <div class="shape-box" v-if="imageUrl && typeId != 3">
        <block v-for="item in shapeList" :key="item.id">
          <div class="shape-item" @click="shapeChange(item)">
            <div class="shape-item-list">
              <img class="shape-item-image" :class="{ 'shape-item-image-round': item.id == 1 || item.id == 2 }" :src="item.cover_path || imageUrl"/>
              <van-icon v-if="item.id == shapeId" class="shape-icon" color="#15CF5F" name="checked" size="18px" />
            </div>
            <div class="shape-item-text">{{item.name}}</div>
          </div>
        </block>
      </div>
      <div class="shape-box-input" v-if="imageUrl && custom_switch == 1">
        <input class="shape-box-input-text" type="text" placeholder="请输入文字" v-model="shapeText" @change="changeShapeText" @input="changeShapeText" @onBlur="changeShapeText" />
      </div>
    </div>
    <!-- <div class="info-desc">
      下单后预计需要7天完成生产发货。<br>
      实物3D打印色彩与图片有合理色差，如对产品有疑问，可以联系客服咨询。
    </div> -->
    <div style="padding: 0 16px;">
      <van-divider />
    </div>
    <div class="order-section" v-if="trialCode == false && imageUrl">
      <div class="order-title">订购数量</div>
      <block v-for="item in sizeList" :key="item.id">
        <block>
          <div class="order-item">
            <span class="order-size">{{ item.size }}</span>
            <span class="order-free">(剩余兑换：{{ item.remaining }})</span>
            <div class="order-ctrl">
              <van-stepper v-model="item.count" :min="0" :max="item.remaining" @change="changeValue" />
            </div>
          </div>
        </block>
        <!-- <block v-if="orderStat.use_type == 2">
          <div class="order-item">
            <span class="order-size">{{ item.size }}</span>
            <span class="order-free">(剩余兑换：{{ item.remaining }})</span>
            <div class="order-ctrl">
              <van-stepper v-model="item.count" :min="0" :max="item.remaining" @change="changeValue" />
            </div>
          </div>
        </block> -->
      </block>
    </div>
    <div class="address-box" v-if="orderStat.use_type == 2 && imageUrl">
      <div class="order-title" style="padding: 0 16px;">收货地址</div>
      <div class="address-item">
        <van-address-edit
          :area-list="areaList"
          show-delete
          show-search-result
          :search-result="searchResult"
          :area-columns-placeholder="['请选择', '请选择', '请选择']"
          @change="nameTelChange"
          @change-area="changeArea"
          @change-detail="onChangeDetail"
        />
      </div>
    </div>
    <div style="height: 130px;"></div>
    <div class="confirm-box">
      <div class="action-section">
        <button v-if="trialCode == false" @click="sureReload" :disabled="flag < 1" class="action-btn"><img class="action-img" src="@/assets/badge/reload.png" alt=""> 再次生成</button>
        <button @click="compare" :disabled="flag < 1" class="action-btn"><img class="action-img" src="@/assets/badge/duibi.png" alt=""> 前后对比</button>
        <button @click="save" :disabled="flag < 1" class="action-btn"><img class="action-img" src="@/assets/badge/down.png" alt=""> 保存图片</button>
      </div>
      <div class="btn-box" v-if="trialCode == false">
        <button @click="confirm" :disabled="flag < 1" class="confirm-btn">确认选择</button>
      </div>
    </div>
  </div>
  
  <van-action-sheet v-model:show="showCompare" title="前后对比" :close-on-click-overlay="true" closeable>
    <div style="padding: 16px;">
      <div style="display: flex; align-items: center; justify-content: center; gap: 20px;">
        <div style="text-align: center;">
          <img :src="compareList.origin_path" alt="原图" style="max-width: 120px; max-height: 120px; border-radius: 8px;">
        </div>
        <div style="font-size: 24px; color: #333;">
          <van-icon name="arrow" size="20px" />
        </div>
        <div style="text-align: center;">
          <img :src="imageUrl" alt="效果图" style="width: 120px; height: 120px; border-radius: 8px;">
        </div>
      </div>
      <div style="text-align: center; margin-top: 16px; color: #999; font-size: 12px;">
        温馨提示：<br/>
        AI设计的徽章效果图是根据用户提供的照片机器学习生成的，<br/>
        多试几次就能找到你满意的徽章~
      </div>
    </div>
  </van-action-sheet>

  <div v-if="showPreview">
    <div class="preview-mask" @click="showPreview = false">
      <img :src="imageWater" alt="徽章预览" />
      <p>长按图片 → 保存到相册</p>
    </div>
  </div>
</template>
<script setup lang="ts">
import { onMounted, ref, onUnmounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { showSuccessToast, showToast, showNotify, showConfirmDialog, AddressEdit, Area } from 'vant';
import { localStorage } from '@/utils/local-storage'
import * as badgeApi from '@/api/badge'
import { areaList } from '@/utils/area'
const router = useRouter();
const value = ref(0);
const showReload = ref(false)
const showCompare = ref(false)
const showBgCompare = ref(false)
const currentIndex = ref(0)
const imageList = ref([])
const imageWater = ref('')
function compare() {
  showCompare.value = true
}

function sureReload() {
  console.log('orderStat', orderStat.value)
  if (orderStat.value.remain_count <= 0) {
    showToast('当前次数已用完,请重新购买')
    return
  }
  isPreview.value = false
  showConfirmDialog({
  title: '再次生成',
  message:
    '请确认是否重新生成。',
  })
  .then(() => {
    group.value = newGroup.value
    const params = {
      pid: pid.value,
      group: group.value,
      prod_id: prodId.value,
      type_id: typeId.value
    }
    badgeApi.putModeling(params).then((res: any) => {
      console.log('putModeling', res)
      imageUrl.value = '';
      imageList.value = []
      imgKey.value = '';
      createLog()
    }).catch((err) => {
      console.log('putModeling', err)
      showReload.value = false
      showToast({
        message: err.message,
        duration: 2000,
      })
    }).finally(() => {
      showReload.value = false
    })
  })
  .catch(() => {
    showReload.value = false
  });
  
}

const imgKey = ref(101)
const frameUrl = ref('')
const changeImage = (item: any) => {
  console.log('changeImage', item)
  imgKey.value = item.key
  imageUrl.value = shapeId.value == 17 || shapeId.value == 18 ? item.frame_url : item.origin_url
  frameUrl.value = item.frame_url
  imageWater.value = item.url
}

const createLog = () => {
  badgeApi.createLog({
    pid: pid.value,
    group: group.value,
    prod_id: prodId.value
  }).then((res: any) => {
    console.log('createLog', res)
    showReload.value = false
    progressTimer.value = null
    getImageList()
    progressList()
    getCompareImage()
    timer.value = setInterval(() => {
      getImageList()
    }, 10000)
  }).catch((err) => {
    console.log('createLog', err)
    showToast({
      message: err.message,
      duration: 2000,
    })
  }).finally((err) => {
    showReload.value = false
  })
}

const showPreview = ref(false)
function save() {
  showPreview.value = true;
}
const compareList = ref({})
const style_name = ref('')
function getCompareImage() {
  badgeApi.getCompareImage({
    pid: pid.value,
    group: group.value,
    prod_id: prodId.value,
    type_id: typeId.value
  }).then((res: any) => {
    console.log('getCompareImage', res)
    compareList.value = res
    style_name.value = res.list[0].kind_name || res.kind_name
  }).catch((err) => {
    console.log('getCompareImage', err)
    showToast({
      message: err.message,
      duration: 2000,
    })
  }).finally((err) => {
    
  })
}
function goBack() {
  router.back()
}

const sizeList = ref([])
const shapeItem = ref({})
const getSizeList = () => {
  badgeApi.getOrderPrice({}).then((res: any) => {
    console.log('getSizeList', res);
    sizeList.value = res
    getShapeList()
  })
}

const contact_name = ref('')
const contact_mobile = ref('')
const province_id = ref(0)
const city_id = ref(0)
const county_id = ref(0)
const province_name = ref('')
const city_name = ref('')
const county_name = ref('')
const address = ref('')
const nameTelChange = (res: any) => {
  console.log('nameTelChange', res)
  if (res.key == 'name') {
    contact_name.value = res.value
  } else {
    contact_mobile.value = res.value
  }
}

const changeArea = (value: any) => {
  console.log('changeArea', value)
  province_id.value = value[0].value
  city_id.value = value[1].value
  county_id.value = value[2].value
  province_name.value = value[0].text
  city_name.value = value[1].text
  county_name.value = value[2].text
}

const onChangeDetail = (value: any) => {
  console.log('onChangeDetail', value)
  address.value = value
}

const payAmount = ref(0)
const changeValue = (value: number) => {
  console.log(value) 
  payAmount.value = value
}

const key = ref(0)
const loading = ref(false)
const confirm = () => {
  if (loading.value) return
  console.log('confirm')
  if (payAmount.value <= 0) {
    showToast('请先选择下单数量')
    return
  }
  if (typeId.value == 2 && (shapeText.value == '' || !shapeText.value.trim())) {
    showToast('请输入自定义文本')
    return
  }
  if (orderStat.value.use_type == 2 && !contact_name.value) {
    showToast('请先填写收货人信息')
    return
  }
  if (orderStat.value.use_type == 2 && !contact_mobile.value) {
    showToast('请先填写收货人手机号')
    return
  }
  if (orderStat.value.use_type == 2 && !province_id.value) {
    showToast('请先选择地区')
    return
  }
  if (orderStat.value.use_type == 2 && !address.value) {
    showToast('请先填写详细地址')
    return
  }
  getPosition()
  loading.value = true
  showConfirmDialog({
  title: '确认下单',
  message:
    '请再次确认是否选择这个模型下单，下单后预计需要10天完成生产发货。如对产品有疑问，可以联系客服咨询。',
  })
  .then(() => {
    const parms = {
      pid: pid.value,
      key: imgKey.value,
      pay_amount: payAmount.value,
      products: sizeList.value,
      prod_id: prodId.value,
      shape_id: shapeId.value,
      custom_text: shapeText.value
    }
    if (orderStat.value.use_type == 2) {
      parms.province_id = province_id.value
      parms.city_id = city_id.value
      parms.county_id = county_id.value
      parms.province_name = province_name.value
      parms.city_name = city_name.value
      parms.county_name = county_name.value
      parms.address = address.value
      parms.contact_name = contact_name.value
      parms.contact_mobile = contact_mobile.value
      parms.addr_id = 0
      parms.country_id = 45
    }
    badgeApi.creatOrder(parms).then((res: any) => {
      console.log('creatOrder', res)
      showSuccessToast({
        message: '下单成功',
        duration: 2000,
      })
      router.push({
        path: '/badge/myOrder'
      })
      loading.value = false
    }).catch((err) => {
      console.log('creatOrder', err)
      loading.value = false
      showToast({
        message: err.message,
        duration: 2000,
      })
    }).finally(() => {
      loading.value = false
    })
  })
  .catch(() => {
    loading.value = false
    // on cancel
  });
  
}

const getPosition = () => {
  badgeApi.composite({
    pid: pid.value,
    num: imgKey.value,
    custom_text: shapeText.value,
    shape_id: shapeId.value,
  }).then((res: any) => {
    console.log('getPosition', res)
  }).catch((err) => {
    console.log('getPosition', err)
  }).finally((err) => {
    
  })
}

const imageUrl = ref('')
const originUrl = ref('')
const group = ref(1);
// 轮询获取图片
const flag = ref(1)
const timer = ref()
const progress = ref(0)
const progressTimer = ref()
const progressText = ref('')
const progressList = () => {
  // 启动进度条计时器
  progress.value = 0
  if (!progressTimer.value) {
    progressTimer.value = setInterval(() => {
      if (progress.value < 90) {
        progress.value += 1
        if (progress.value < 25) {
          progressText.value = '照片数据分析中'
        } else if (progress.value < 50) {
          progressText.value = '提炼图像关键词'
        } else if (progress.value < 75) {
          progressText.value = '图像生成中'
        } else {
          progressText.value = '图像后处理与优化'
        }
      }
    }, 300)
  }
}

const newGroup = ref(0)
const isPreview = ref(false)
const getImageList = () => {
  badgeApi.getImageList({
    pid: pid.value, 
    group: group.value,
    prod_id: prodId.value
  }).then((res: any) => {
    console.log('getImageList', res)
    const data = res || []
    flag.value = data.flag
    prodId.value = data.prod_id
    if (data.flag === 1) {
      newGroup.value = data.next_group
      
      nextTick(() => {
        // 更新图片列表
        const newList = data.list.map(item => ({
          ...item,
          isNew: true
        }))

        // 找到第一个状态为1(已生成)的图片
        const firstGeneratedImage = newList.find(item => item.status === 1)

        // 如果有已生成的图片且还未设置预览图,则显示第一个生成的图片
        if (firstGeneratedImage && !isPreview.value) {
          originUrl.value = firstGeneratedImage.origin_url
          imageUrl.value = firstGeneratedImage.origin_url
          frameUrl.value = firstGeneratedImage.frame_url
          imageWater.value = firstGeneratedImage.url
          imgKey.value = firstGeneratedImage.key
          isPreview.value = true
        }

        // 合并新旧列表,保持原有顺序
        const mergedList = imageList.value.map(item => {
          const newItem = newList.find(n => n.key === item.key)
          return newItem || item
        })

        // 添加新图片
        newList.forEach(newItem => {
          if (!mergedList.find(item => item.key === newItem.key)) {
            mergedList.push(newItem)
          }
        })

        // 更新图片列表
        imageList.value = mergedList

        // 如果已有选中图片,保持显示当前选中的图片
        console.log('imgKey.value', imgKey.value)
        if (imgKey.value) {
          const currentImage = mergedList.filter((item: any) => item.key === imgKey.value)[0]
          console.log('currentImage', currentImage)
          if (currentImage && currentImage.status === 1) {
            originUrl.value = currentImage.origin_url
            imageUrl.value = currentImage.origin_url
            frameUrl.value = currentImage.frame_url
            imageWater.value = currentImage.url
            isPreview.value = true
          } else {
            originUrl.value = currentImage.origin_url
            imageUrl.value = currentImage.origin_url
            frameUrl.value = currentImage.frame_url
            imageWater.value = currentImage.url
            isPreview.value = true
          }
        }
      })
    }
    if (data.flag === 2) {
      newGroup.value = data.next_group
      // 清除轮询和进度条计时器
      clearInterval(timer.value)
      clearInterval(progressTimer.value)
      
      // 进度条到100%
      progress.value = 100
      
      // 显示图片
      imageList.value = data.list
      if (imgKey.value) {
        originUrl.value = data.list.filter((item: any) => item.key == imgKey.value)[0].origin_url
        imageUrl.value = data.list.filter((item: any) => item.key == imgKey.value)[0].origin_url
        frameUrl.value = data.list.filter((item: any) => item.key == imgKey.value)[0].frame_url
        imageWater.value = data.list.filter((item: any) => item.key == imgKey.value)[0].url
      } else {
        originUrl.value = data.list[0].origin_url
        imageUrl.value = data.list[0].origin_url
        frameUrl.value = data.list[0].frame_url
        imageWater.value = data.list[0].url
        imgKey.value = data.list[0].key
      }
      localStorage.remove('userId')
    }
  }).catch((err) => {
    // 清除轮询和进度条计时器
    // clearInterval(timer.value)
    // clearInterval(progressTimer.value)
    // progress.value = 0
    showToast({
      message: err.message,
      duration: 2000,
    })
  }).finally((err) => {
    
  })
}

const shapeId = ref(0)
const shapeImage = ref('')

const shapeList = ref([])
const custom_switch = ref(0)
const limitCount = ref(0)
const getShapeList = () => {
  badgeApi.getShapeList({
    prod_id: prodId.value,
    type_id: orderStat.value.type_id
  }).then((res: any) => {
    console.log('getShapeList', res)
    shapeList.value = res.list
    shapeId.value = res.list[0].id
    shapeImage.value = res.list[0]?.frame_path
    custom_switch.value = res.list[0]?.custom_switch
    limitCount.value = res.list[0]?.text_limit_max
    ImageShow(res.list[0])
    if (custom_switch.value == 1) {
      textShow(res.list[0])
    }
  }).catch((err) => {
    console.log('getShapeList', err)
  }).finally((err) => {
    
  })
}

const getStyle = ref('')
const ImageShow = (item: any) => {
  const scale = 0.6;
  const img = new Image()
  img.src = item.frame_path
  img.onload = () => {
    console.log('img', img)
    const ratioWidth = 320 / img.width;
    const ratioHeight = 320 / img.height;
    const x = item.axisx * ratioWidth * scale;
    const y = item.axisy * ratioHeight * scale;
    const path_width = item.width * ratioWidth * scale;
    const path_height = item.height * ratioHeight * scale;
    getStyle.value = `left: ${x}px;top: ${y}px;width: ${path_width}px;height: ${path_height}px;`
  }
}

const shapeTextStyle = ref('')
const textShow = (item: any) => {
  const scale = 0.6;
  const img = new Image()
  img.src = item.frame_path
  img.onload = () => {
    console.log('img', img)
    const ratioWidth = 320 / img.width;
    const ratioHeight = 320 / img.height;
    const x = item.text_axisx * ratioWidth * scale;
    const y = item.text_axisy * ratioHeight * scale;
    const path_width = item.text_width * ratioWidth * scale;
    const path_height = item.text_height * ratioHeight * scale;
    const text_size = item.font_size * Math.min(ratioWidth * scale, ratioHeight * scale);
    shapeTextStyle.value = `left: ${x}px;top: ${y}px;width: ${path_width}px;height: ${path_height}px;text-align: center;line-height: ${path_height}px;font-size: ${text_size}px;color: ${item.font_color};font-weight: ${item.font_weight};`
  }
}

const shapeText = ref('')
const changeShapeText = (e: any) => {
  console.log('changeShapeText', e.target.value)
  if (!validateInput(e.target.value)) {
    showToast('输入的文字不能包含特殊符号！')
    // 移除特殊符号，仅保留字母、数字、中文和空格
    shapeText.value = e.target.value.replace(/[^a-zA-Z0-9\u4e00-\u9fa5\s]/g, '');
    return;
  } 
  handleInput(e.target.value)
}

const validateInput = (input: string) => {
  // 正则说明：只允许字母（大小写）、数字、中文和空格
  const regex = /^[a-zA-Z0-9\u4e00-\u9fa5\s]+$/;
  return regex.test(input);
}

const handleInput = (value: string) => {
  let byteLength = calculateByteLength(value);
  // 如果超过最大字节数，禁止继续输入
  console.log('byteLength', byteLength, limitCount.value)
  if (byteLength > limitCount.value) {
    // 超出字节数，直接截断到允许的最大字节数
    let validValue = '';
    let currentBytes = 0;
    for (let i = 0; i < value.length; i++) {
      const char = value.charAt(i);
      const charBytes = char.charCodeAt(0) > 255 ? 2 : 1;
      if (currentBytes + charBytes <= limitCount.value) {
        validValue += char;
        currentBytes += charBytes;
      } else {
        break;
      }
    }
    shapeText.value = validValue;
    return;
  }
  // 未超过最大字节数，正常更新
  shapeText.value = value;
}

const calculateByteLength = (str: string) => {
  let len = 0;
  for (let i = 0; i < str.length; i++) {
    const code = str.charCodeAt(i);
    // 中文字符和特殊符号占2字节，英文占1字节
    len += code > 255 ? 2 : 1;
  }
  return len;
}

// const typeChange = (id: number) => {
//   console.log('typeChange', id)
//   typeId.value = id;
//   shapeList.value = [];
//   shapeImage.value = '';
//   getStyle.value = '';
//   getShapeList()
// }

const shapeChange = (item: any) => {
  console.log('shapeChange', item)
  sizeList.value.map((item: any) => {
    if (item.shape_id !== item.id) {
      item.count = 0
    }
  })
  shapeText.value = '';
  shapeId.value = item.id
  shapeImage.value = item.frame_path
  custom_switch.value = item.custom_switch
  limitCount.value = item.text_limit_max
  if (typeId.value == 3) {
    imageUrl.value = item.id == 15 || item.id == 16 ? originUrl.value : frameUrl.value
  } else {
    imageUrl.value = originUrl.value
  }
  ImageShow(item)
  if (custom_switch.value == 1) {
    textShow(item)
  }
}

const trialCode = ref(false)
const getTrialCode = () => {
  const value = localStorage.get('trialCode')
  if (value) {
    trialCode.value = true
  } else {
    getOrderStat()
  }
}

const orderStat = ref({})
const typeId = ref(0)
const getOrderStat = () => {
  badgeApi.getOrderStat({}).then((res: any) => {
    console.log('getOrderStat', res)
    orderStat.value = res
    typeId.value = res.type_id
    getSizeList()
  })
}

function handleBeforeUnload(_event: BeforeUnloadEvent) {
  localStorage.remove('code')
  localStorage.remove('trialCode')
  localStorage.remove('userId')
  // 清除轮询和进度条计时器
  clearInterval(timer.value)
  clearInterval(progressTimer.value)
}

const pid = ref(0)
const route = useRoute()
const prodId = ref(0)
onMounted(() => {
  pid.value = route.query.pid
  group.value = route.query.group
  if (route.query.key) {
    imgKey.value = route.query.key
  }
  if (route.query.prod_id) {
    prodId.value = route.query.prod_id
  }

  // pid.value = 281505;
  // group.value = 1;
  // prodId.value = 7;
  // getTypesList()
  getImageList()
  progressList()
  getCompareImage()
  getTrialCode()
  timer.value = setInterval(() => {
    getImageList()
  }, 10000)
  window.addEventListener('beforeunload', handleBeforeUnload);
})

onUnmounted(() => {
  clearInterval(timer.value)
  clearInterval(progressTimer.value)
})
</script>
<style scoped>
.preview-container {
  min-height: 100vh;
  font-family: 'PingFang SC', Arial, sans-serif;
  color: #222;
}
.backstyle_1 {
  position: fixed;
  left: -110px;
  top: -40px;
  width: 328px;
  height: 216px;
  opacity: 0.2;
  transform: rotate(-13.72deg);
  border-radius: 50%;
  /* background: radial-gradient(48.48% 50% at 50% 50%, #EBD4A0 0%, #ebd5a000 81.94%); */
  background-image: radial-gradient( rgba(250, 182, 55, 0.726), #ebd5a09c, #d4cab100);
  z-index: -10;
}
.backstyle_2 {
  position: fixed;
  left: 97px;
  top: -95px;
  width: 370px;
  height: 374px;
  opacity: 0.1;
  border-radius: 50%;
  /* background: radial-gradient(59.73% 50% at 50% 50%, #90F272 0%, #90f27200 84.03%); */
  background-image: radial-gradient( rgb(69, 255, 63), #90f2729a, #90f27200);
  z-index: -10;
}
.header {
  display: flex;
  align-items: center;
  height: 40px;
  font-size: 14px;
  color: #999;
  padding: 16px 16px 0 16px;
}
.back-icon {
  margin-right: 8px;
  color: #222;
  font-size: 16px;
  cursor: pointer;
}

.step-container {
  display: flex;
  align-items: flex-start;
  padding: 16px 16px 16px 0;
}
.step-item {
  display: flex;
  align-items: center;
  flex: 1;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.step-item.active {
  flex: 2.5;
}
.step-num {
  font-size: 48px;
  line-height: 1;
  position: relative;
  margin-right: 8px;
  text-shadow: 0 2px 8px #e6f7e6;
  color: #CCCCCC;
}
.step-item.active .step-num {
  color: #fff;
  text-shadow:
    1px 1px 0 #000,
    -1px -1px 0 #000,
    -1px 1px 0 #000,
    1px -1px 0 #000,
    0 1px 0 #000,
    1px 0 0 #000,
    0 -1px 0 #000,
    -1px 0 0 #000;
}
.step-item.active .step-num::after {
  content: '';
  position: absolute;
  top: 20px;
  right: 0;
  width: 15px;
  height: 15px;
  background-color: #50cf54;
  opacity: 0.5;
  border-radius: 50%;
}
.step-content {
  display: flex;
  flex-direction: column;
  height: 48px;
}
.step-item.active .step-title {
  color: #000;
  font-weight: bold;
  font-size: 16px;
}
.step-item.active .step-desc {
  color: #808080;
  font-size: 13px;
}
.step-title {
  font-size: 16px;
  color: #808080;;
}
.step-desc {
  font-size: 12px;
  color: #808080;
  margin-top: 2px;
}
.progress-section {
  margin: 0 auto;
  text-align: center;
  width: 100vw;
  height: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}
.progress-section-picture {
  width: 320px;
  height: 320px;
  position: relative;
  margin: 0 auto;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}
.progress-section-img {
  position: relative;
}
.box1-back-image {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  object-fit: cover;
  border-radius: 10px;
} 
.box1-front-box {
  position: absolute;
  z-index: 1;
}
.box1-front-image {
  width: 100%;
  height: auto;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.3);
}
.box1-round-shadow {
  position: absolute;
  top: 0;
  left: 0;
  width: 320px;
  height: 320px;
  border-radius: 50%;
  box-shadow: 2px 2px 4px  #00000042,inset -2px -2px 4px  #00000048,inset 2px 2px 4px  #ffffffb4;
  z-index: 10;
}
.box1-round-image {
  border-radius: 50%;
}
.progress-bar-bg {
  width: 70%;
  height: 10px;
  background: #eee;
  border-radius: 5px;
  margin: 0 auto 8px auto;
  position: relative;
  overflow: hidden;
}
.progress-bar-fg {
  height: 100%;
  background: #6fdc8c;
  border-radius: 5px;
  transition: width 0.3s;
}
.progress-text {
  font-size: 15px;
  color: #222;
  margin-bottom: 2px;
}
.progress-desc {
  font-size: 12px;
  color: #999;
}
.info-section {
  display: flex;
  justify-content: flex-start;
  padding: 16px;
}
.info-item {
  flex: 1;
}
.info-title {
  font-size: 13px;
  color: #222;
  font-weight: 600;
  margin-bottom: 2px;
}
.info-content {
  font-size: 12px;
  color: #999;
}
.info-desc {
  font-size: 12px;
  color: #999;
  margin-bottom: 18px;
  line-height: 1.5;
  text-align: left;
  padding: 0 16px;
}
.order-section {
  border-radius: 10px;
  padding: 0 16px;
  margin-bottom: 18px;
}
.order-title {
  font-size: 14px;
  color: #222;
  font-weight: 600;
  margin-bottom: 10px;
}
.order-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}
.order-size {
  font-size: 15px;
  color: #222;
  margin-right: 8px;
}
.order-free {
  font-size: 12px;
  color: #999;
  margin-right: 16px;
}
.order-ctrl {
  display: flex;
  align-items: center;
  margin-left: auto;
}
.order-btn {
  width: 26px;
  height: 26px;
  border: none;
  background: #e8e8e8;
  color: #bbb;
  font-size: 18px;
  border-radius: 4px;
  margin: 0 4px;
  cursor: pointer;
}
.order-btn:disabled {
  background: #f2f2f2;
  color: #ddd;
  cursor: not-allowed;
}
.order-count {
  font-size: 15px;
  color: #222;
  width: 22px;
  text-align: center;
}
.confirm-box {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  background: #fff;
  z-index: 10;
  padding: 0 16px 16px 16px;
  border-top: 1px solid #e6e6e6;
}
.action-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  padding: 0 16px;
}
.action-btn {
  flex: 1;
  margin: 0 4px;
  border: none;
  border-radius: 8px;
  color: #222;
  font-size: 13px;
  padding: 8px 0;
  cursor: pointer;
  transition: background 0.2s;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #fff;
}
.action-img {
  width: 20px;
  height: 20px;
  margin-right: 5px;
}
.btn-box {
  display: flex;
  justify-content: center;
  align-items: center;
}
.confirm-btn {
  width: 80vw;
  background: linear-gradient(90deg, #D1ED8E 0%, #55E668 100%);
  color: #000;
  font-size: 17px;
  font-weight: 600;
  border: none;
  border-radius: 24px;
  padding: 12px 0;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(111,220,140,0.08);
  letter-spacing: 2px;
}
.confirm-btn:active {
  background: linear-gradient(90deg, #5ccf7a 0%, #8fdca0 100%);
}
.style-selection {
  padding: 16px;
}
.style-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.style-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
  position: relative;
  width: 28vw;
}
.style-img {
  width: 28vw;
  height: 28vw;
  border-radius: 8px;
  object-fit: cover;
  background: #f5f5f5;
  border: 2px solid transparent;
  transition: border 0.2s;
}
.style-item .style-selected {
  position: absolute;
  right: 4px;
  bottom: 25px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background-color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
}
.style-label {
  font-size: 13px;
  color: #333;
  margin-top: 4px;
}
.confirm-wrapper {
  margin-top: 24px;
}
.confirm-button {
  width: 100%;
  background: linear-gradient(90deg, #D1ED8E 0%, #55E668 100%);
  color: #000;
  font-size: 17px;
  font-weight: 600;
  border: none;
  border-radius: 24px;
  padding: 12px 0;
  cursor: pointer;
}
.confirm-button:active {
  background: linear-gradient(90deg, #5ccf7a 0%, #8fdca0 100%);
}
.style-item.active .style-img {
  border: 2px solid #50cf54;
}
.style-item.active .style-label {
  color: #50cf54;
}
.preview-mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
.preview-mask img {
  max-width: 80%;
  max-height: 80%;
  border-radius: 10px;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
}
.preview-mask p {
  margin-top: 16px;
  color: #fff;
  font-size: 16px;
  text-align: center;
} 
.progress-image-item-shadow {
  position: absolute;
  top: 0;
  left: 0;
  width: 80vw;
  height: 80vw;
  object-fit: cover;
  box-shadow: inset 2px 2px 4px  rgba(255, 255, 255, 0.5),inset -2px -2px 4px  rgba(0, 0, 0, 0.2);
  border-radius: 50%;
}
.image-list-box {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 16px 16px 0 16px;
}
.image-list-item {
  width: 20vw;
  height: 20vw;
}
.image-list-item-img {
  width: 20vw;
  height: 20vw;
  border-radius: 12px;
  border: 3px solid #fff;
  background: rgba(0, 0, 0, 0.3);
}
.image-list-item-img.imgActive {
  border: 3px solid #50cf54;
}
.image-list-item-loading {
  width: 20vw;
  height: 20vw;
  border-radius: 12px;
  background: #f0f0f0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: #999;
}
.shape-body {
  background: #fff;
  border-radius: 8px;
  padding: 0 20px;
}
.shape-box {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-start;
}
.shape-title {
  padding-bottom: 12px;
  font-size: 14px;
  font-weight: bold;
}
.shape-item {
  position: relative;
  flex: 0 0 24%;
  /* margin-right: calc(4% / 3); */
  margin-bottom: calc(4% / 2);
  margin-right: 8px!important;
}
.shape-item:nth-child(4n){ 
  margin-right: 0; 
} 
.shape-item:last-child{ 
  margin-right: auto; 
}
.shape-item-image {
  width: 20vw;
  height: 20vw;
  border-radius: 8px;
}
.shape-icon {
  position: absolute;
  right: 6px;
  bottom: 24px;
}
.shape-item-text {
  font-size: 12px;
  text-align: center;
}
.shape-type {
  display: -webkit-box;
  overflow-x: scroll;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding-bottom: 16px;
}
.shape-type-item {
  background: #F0F2F5;
  font-size: 12px;
  height: 7vw;
  padding: 0px 16px;
  border-radius: 4px;
  margin-right: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.shape-active {
  background: #15CF5F;
  color: #fff;
}
.shape-box-input {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 10px;
}
.shape-box-input-text {
  width: 100%;
  height: 40px;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 0 10px;
}
.shape-text {
  position: absolute;
  z-index: 2;
  font-family: chinese;
  overflow: hidden;
  text-shadow: 1px 0px 1px #000000a1;
}
.shape-item-image-round {
  border-radius: 50%;
}
.van-address-edit {
  padding: 0!important;
}
</style>