<template>
  <div class="report-view">
    <!-- 加载中 -->
    <div v-if="loading" class="loading-wrap">
      <view class="loading-spinner"></view>
      <span>加载报告中...</span>
    </div>

    <!-- 未找到 -->
    <div v-else-if="notFound" class="not-found">
      <view class="empty"><text>报告不存在或链接已失效</text></view>
    </div>

      <!-- 报告内容 -->
    <div v-else-if="reportData" class="report-content">
      <!-- 品牌头部 -->
      <div class="brand-header" :style="brandHeaderSafeStyle">
        <div class="header-actions">
          <view class="header-btn" @click="goHome">
            <AppIcon name="home" :size="15" color="#ffffff" />
          </view>
          <view class="header-placeholder"></view>
        </div>
        <div class="brand-logo">{{ reportData.store?.name || '宠伴生活馆' }}</div>
        <div class="brand-sub">宠物服务，让爱更专业</div>
        <div class="brand-contact">
          <span v-if="reportData.store?.phone">电话：{{ reportData.store.phone }}</span>
          <span v-if="reportData.store?.address">地址：{{ reportData.store.address }}</span>
        </div>
      </div>

      <!-- 暖心问候 (C端视角) -->
      <div v-if="!isStaff" class="customer-greeting">
        亲爱的宠主，<span class="highlight">{{ reportData.petName }}</span> 今天的服务已完成，快来看看TA的变美记录吧！
      </div>

      <!-- 报告标题 -->
      <div class="report-title-wrap">
        <div class="report-title">服务报告</div>
        <div class="report-time">{{ formatTime(reportData.appointmentTime) }}</div>
      </div>

      <!-- 服务信息 -->
      <view class="van-cell-group service-info">
        <view class="van-cell">
          <view class="van-cell__title">宠物名字</view>
          <view class="van-cell__value">{{ reportData.petName }}</view>
        </view>
        <view class="van-cell">
          <view class="van-cell__title">服务项目</view>
          <view class="van-cell__value">{{ reportData.serviceType }}</view>
        </view>
        <view class="van-cell">
          <view class="van-cell__title">服务时间</view>
          <view class="van-cell__value">{{ formatTime(reportData.appointmentTime) }}</view>
        </view>
        <view class="van-cell">
          <view class="van-cell__title">服务技师</view>
          <view class="van-cell__value">{{ reportData.staffName || '-' }}</view>
        </view>
      </view>

      <!-- 照片对比 -->
      <div class="photo-section section-card">
        <div class="section-label">服务前后对比</div>
        
        <div class="photo-group">
          <div class="photo-group-title">服务前</div>
          <div v-if="beforePhotos.length > 0" class="photo-grid">
            <image
              v-for="(img, idx) in beforePhotos"
              :key="'before-'+idx"
              :src="imgUrl(img)"
              class="photo-image"
              mode="aspectFill"
            />
          </div>
          <view v-else class="photo-empty">暂无照片</view>
        </div>

        <div class="photo-group" style="margin-top: 16px;">
          <div class="photo-group-title">服务后</div>
          <div v-if="afterPhotos.length > 0" class="photo-grid">
            <image
              v-for="(img, idx) in afterPhotos"
              :key="'after-'+idx"
              :src="imgUrl(img)"
              class="photo-image"
              mode="aspectFill"
            />
          </div>
          <view v-else class="photo-empty">暂无照片</view>
        </div>
      </div>

      <!-- 备注 -->
      <div class="remark-section section-card">
        <div class="section-label">备注</div>
        <div class="remark-content">
          {{ reportData.remark || '暂无备注' }}
        </div>
      </div>

      <!-- 操作按钮区 -->
      <div class="action-section">
        <!-- 店员视角 -->
        <template v-if="isStaff">
          <button open-type="share" class="van-button van-button--primary van-button--round van-button--block share-btn">
            <AppIcon name="profile" :size="16" color="#ffffff" style="margin-right: 6px;" /> 转发给宠主
          </button>
          <button class="van-button van-button--block btn-ghost" @click="generatePoster">生成海报 · 保存到相册</button>
        </template>
        
        <!-- 宠主视角 -->
        <template v-else>
          <button class="van-button van-button--primary van-button--round van-button--block" @click="callStore">
            联系门店
          </button>
          <button class="van-button van-button--block btn-ghost" @click="navToStore">导航去门店</button>
          <button class="van-button van-button--block btn-ghost" style="margin-top: 12px;" @click="goHome">我也要预约</button>
        </template>
      </div>
    </div>

    <!-- Canvas 海报（H5 DOM / 小程序 2d） -->
    <!-- #ifdef H5 -->
    <canvas ref="posterCanvas" class="poster-canvas-offscreen" />
    <!-- #endif -->
    <!-- #ifdef MP-WEIXIN -->
    <canvas
      id="reportPosterCanvas"
      type="2d"
      class="poster-canvas-offscreen"
    />
    <!-- #endif -->
  </div>
</template>

<script setup>
import { ref, computed, onMounted, getCurrentInstance } from 'vue'
import { onLoad, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
import { getReportByToken, imgUrl } from '../../api/index.js'
import { formatDateTimeYMDHM } from '../../utils/datetime.js'
import { drawReportPoster, POSTER_W, POSTER_H } from '../../utils/reportPosterDraw.js'
import AppIcon from '../../components/AppIcon.vue'
import { isLoggedIn } from '../../utils/session.js'

const loading = ref(true)
const notFound = ref(false)
const reportData = ref(null)
const posterCanvas = ref(null)
const routeToken = ref('')

const isStaff = computed(() => isLoggedIn())

const beforePhotos = computed(() => {
  if (!reportData.value?.beforePhoto) return []
  return reportData.value.beforePhoto.split(',').filter(Boolean)
})

const afterPhotos = computed(() => {
  if (!reportData.value?.afterPhoto) return []
  return reportData.value.afterPhoto.split(',').filter(Boolean)
})

/** 转发标题：店名 + 宠物 + 服务，更易产生点击欲 */
const shareTitle = computed(() => {
  const r = reportData.value
  if (!r) return '宠物洗护美容报告'
  const store = r.store?.name || '宠伴生活馆'
  const pet = r.petName || '爱宠'
  const svc = r.serviceType || '洗护美容'
  return `${store}｜${pet}的${svc}已完成，点击查看报告`
})

/** 分享封面：优先服务后首图（微信要求可访问 https 图床） */
const shareCoverUrl = computed(() => {
  if (afterPhotos.value.length > 0) return imgUrl(afterPhotos.value[0])
  if (beforePhotos.value.length > 0) return imgUrl(beforePhotos.value[0])
  return ''
})
const brandHeaderSafeStyle = (() => {
  const statusBarHeight = uni.getSystemInfoSync?.().statusBarHeight || 20
  return `padding-top:${statusBarHeight + 10}px;`
})()

const formatTime = (time) => formatDateTimeYMDHM(time)

const loadReport = async () => {
  let token = routeToken.value
  // #ifdef H5
  token = new URLSearchParams(window.location.search).get('token')
  // #endif
  if (!token) { notFound.value = true; loading.value = false; return }

  uni.showLoading({ title: '加载中...' })
  const res = await getReportByToken(token)
  uni.hideLoading()
  loading.value = false
  if (res.code === 200) {
    reportData.value = res.data
  } else {
    notFound.value = true
  }
}

const goHome = () => {
  uni.reLaunch({ url: '/pages/home/Home' })
}

const callStore = () => {
  const phone = reportData.value?.store?.phone
  if (!phone) return uni.showToast({ title: '门店未设置电话', icon: 'none' })
  uni.makePhoneCall({ phoneNumber: phone })
}

const navToStore = () => {
  const store = reportData.value?.store
  if (!store || !store.latitude || !store.longitude) {
    return uni.showToast({ title: '门店未设置导航坐标', icon: 'none' })
  }
  uni.openLocation({
    latitude: Number(store.latitude),
    longitude: Number(store.longitude),
    name: store.name || '宠伴生活馆',
    address: store.address || ''
  })
}

onShareAppMessage(() => {
  const q = routeToken.value ? `token=${encodeURIComponent(routeToken.value)}` : ''
  return {
    title: shareTitle.value,
    path: `/pages/report-view/reportView${q ? '?' + q : ''}`,
    imageUrl: shareCoverUrl.value || undefined
  }
})

onShareTimeline(() => {
  const q = routeToken.value ? `token=${encodeURIComponent(routeToken.value)}` : ''
  return {
    title: shareTitle.value,
    query: q,
    imageUrl: shareCoverUrl.value || undefined
  }
})

// #ifdef H5
const loadImageH5 = (src) => {
  return new Promise((resolve) => {
    const img = new Image()
    img.crossOrigin = 'anonymous'
    img.onload = () => resolve(img)
    img.onerror = () => resolve(null)
    img.src = src
  })
}

const generatePoster = async () => {
  if (!reportData.value) return
  const r = reportData.value
  uni.showToast({ title: '正在生成海报...', icon: 'none' })
  const beforeUrl = beforePhotos.value[0] ? imgUrl(beforePhotos.value[0]) : ''
  const afterUrl = afterPhotos.value[0] ? imgUrl(afterPhotos.value[0]) : ''
  const [beforeImg, afterImg] = await Promise.all([
    beforeUrl ? loadImageH5(beforeUrl) : Promise.resolve(null),
    afterUrl ? loadImageH5(afterUrl) : Promise.resolve(null)
  ])
  const canvas = posterCanvas.value
  if (!canvas) return
  const ctx = canvas.getContext('2d')
  canvas.width = POSTER_W
  canvas.height = POSTER_H
  drawReportPoster(ctx, {
    storeName: r.store?.name || '',
    storePhone: r.store?.phone || '',
    storeAddr: r.store?.address || '',
    petName: r.petName || '',
    serviceType: r.serviceType || '',
    timeStr: formatTime(r.appointmentTime) || '',
    staffName: r.staffName || '',
    remark: r.remark || '',
    beforeImg,
    afterImg
  })
  const link = document.createElement('a')
  link.download = `服务报告_${r.petName || '宠物'}.png`
  link.href = canvas.toDataURL('image/png')
  link.click()
  uni.showToast({ title: '已下载海报', icon: 'success' })
}
// #endif

// #ifdef MP-WEIXIN
function downloadToTemp(url) {
  return new Promise((resolve) => {
    if (!url) {
      resolve(null)
      return
    }
    uni.downloadFile({
      url,
      success: (res) => {
        if (res.statusCode === 200) resolve(res.tempFilePath)
        else resolve(null)
      },
      fail: () => resolve(null)
    })
  })
}

function loadCanvasImage(canvas, tempPath) {
  return new Promise((resolve) => {
    if (!tempPath) {
      resolve(null)
      return
    }
    const img = canvas.createImage()
    img.onload = () => resolve(img)
    img.onerror = () => resolve(null)
    img.src = tempPath
  })
}

const generatePoster = async () => {
  if (!reportData.value) return
  const r = reportData.value
  uni.showLoading({ title: '生成海报中...', mask: true })
  try {
    const beforeUrl = beforePhotos.value[0] ? imgUrl(beforePhotos.value[0]) : ''
    const afterUrl = afterPhotos.value[0] ? imgUrl(afterPhotos.value[0]) : ''
    const [beforePath, afterPath] = await Promise.all([
      downloadToTemp(beforeUrl),
      downloadToTemp(afterUrl)
    ])

    const inst = getCurrentInstance()
    const proxy = inst?.proxy

    await new Promise((resolve) => {
      uni.createSelectorQuery()
        .in(proxy)
        .select('#reportPosterCanvas')
        .fields({ node: true, size: true })
        .exec(async (res) => {
          const canvas = res[0]?.node
          if (!canvas) {
            uni.showToast({ title: '画布未就绪，请重试', icon: 'none' })
            resolve()
            return
          }
          const ctx = canvas.getContext('2d')
          const dpr = Math.min(uni.getSystemInfoSync().pixelRatio || 2, 3)
          canvas.width = POSTER_W * dpr
          canvas.height = POSTER_H * dpr
          ctx.scale(dpr, dpr)

          const beforeImg = await loadCanvasImage(canvas, beforePath)
          const afterImg = await loadCanvasImage(canvas, afterPath)

          drawReportPoster(ctx, {
            storeName: r.store?.name || '',
            storePhone: r.store?.phone || '',
            storeAddr: r.store?.address || '',
            petName: r.petName || '',
            serviceType: r.serviceType || '',
            timeStr: formatTime(r.appointmentTime) || '',
            staffName: r.staffName || '',
            remark: r.remark || '',
            beforeImg,
            afterImg
          })

          uni.canvasToTempFilePath(
            {
              canvas,
              fileType: 'png',
              quality: 1,
              destWidth: POSTER_W,
              destHeight: POSTER_H,
              success: (out) => {
                uni.saveImageToPhotosAlbum({
                  filePath: out.tempFilePath,
                  success: () => {
                    uni.showToast({ title: '已保存到相册', icon: 'success' })
                  },
                  fail: (err) => {
                    const msg = err.errMsg || ''
                    if (msg.includes('auth deny') || msg.includes('authorize')) {
                      uni.showModal({
                        title: '需要相册权限',
                        content: '保存海报需要授权保存到相册，请在设置中开启。',
                        confirmText: '去设置',
                        success: (m) => {
                          if (m.confirm) uni.openSetting({})
                        }
                      })
                    } else {
                      uni.showToast({ title: '保存失败', icon: 'none' })
                    }
                  }
                })
              },
              fail: () => {
                uni.showToast({ title: '导出图片失败', icon: 'none' })
              }
            },
            proxy
          )
          resolve()
        })
    })
  } catch (_) {
    uni.showToast({ title: '生成失败', icon: 'none' })
  } finally {
    uni.hideLoading()
  }
}
// #endif

// #ifndef H5
// #ifndef MP-WEIXIN
const generatePoster = () => {
  uni.showToast({ title: '请截图分享报告页', icon: 'none' })
}
// #endif
// #endif

onLoad((options) => {
  routeToken.value = options?.token || ''
})

onMounted(() => loadReport())
</script>

<style scoped>
.poster-canvas-offscreen {
  position: fixed;
  left: -9999px;
  top: 0;
  width: 375px;
  height: 550px;
  pointer-events: none;
}
.report-view { background: #f5f7fb; min-height: 100vh; }
.loading-wrap {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 100vh; gap: 16px; color: #999;
}
.loading-spinner {
  width: 32px; height: 32px;
  border: 3px solid #e0e0e0;
  border-top-color: #07c160;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.not-found { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; }
.report-content { max-width: 430px; margin: 0 auto; background: #f8fafc; min-height: 100vh; box-shadow: 0 10px 30px rgba(15, 23, 42, 0.06); }
.brand-header {
  background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
  padding: 20px 20px 18px;
  text-align: center; color: #fff;
  border-radius: 0 0 16px 16px;
  box-shadow: 0 8px 20px rgba(34, 197, 94, 0.24);
  position: relative;
}
.header-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}
.header-btn {
  width: 30px;
  height: 30px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.45);
  background: rgba(255, 255, 255, 0.2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.header-placeholder {
  width: 30px;
  height: 30px;
}
.brand-logo { font-size: 20px; font-weight: 700; letter-spacing: 1px; margin-bottom: 4px; }
.brand-sub { font-size: 12px; opacity: 0.7; margin-bottom: 12px; }
.brand-contact { font-size: 12px; opacity: 0.85; display: flex; justify-content: center; gap: 16px; flex-wrap: wrap; }
.report-title-wrap { text-align: center; padding: 20px 20px 14px; }
.report-title { font-size: 22px; font-weight: 700; color: #333; }
.report-time { font-size: 13px; color: #999; margin-top: 6px; }
.service-info { margin: 0 16px 12px; border-radius: 14px !important; }
.section-card {
  margin: 0 16px 12px;
  background: #fff;
  border: 1px solid #e8edf4;
  border-radius: 14px;
  padding: 12px;
  box-shadow: 0 6px 16px rgba(15, 23, 42, 0.04);
}
.section-label { font-size: 15px; font-weight: 700; color: #1f2937; margin-bottom: 10px; }
.photo-group-title { font-size: 13px; color: #64748b; margin-bottom: 8px; }
.photo-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.photo-image {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
}
.photo-empty {
  width: 100%;
  height: 80px;
  background: #f1f5f9;
  border: 1px dashed #d1d9e6;
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center; color: #94a3b8; font-size: 13px;
}
.remark-content { background: #f8fafc; border: 1px solid #e8edf4; border-radius: 12px; padding: 14px; font-size: 14px; color: #64748b; line-height: 1.6; min-height: 60px; }
.action-section { margin: 0 16px 24px; display: flex; flex-direction: column; gap: 12px; }
.share-btn {
  margin-top: 0 !important;
  box-shadow: 0 6px 14px rgba(34, 197, 94, 0.2) !important;
}
.btn-ghost {
  margin-top: 0 !important;
  background: #fff !important; 
  color: #666 !important; 
  border: 1px solid #e0e0e0 !important; 
  box-shadow: none !important;
}
.customer-greeting {
  margin: -10px 16px 12px;
  padding: 14px 16px;
  background: #fff;
  border-radius: 12px;
  font-size: 14px;
  color: #475569;
  line-height: 1.5;
  box-shadow: 0 4px 12px rgba(0,0,0,0.03);
  position: relative;
  z-index: 2;
}
.customer-greeting .highlight {
  color: #16a34a;
  font-weight: 700;
  margin: 0 2px;
}
</style>
