<template>
  <view :class="themeClass" class="page-container card-page">
    <view class="card-nav" :style="{ paddingTop: (statusBarHeight + 12) + 'px' }">
      <view class="step-back" @click="goBack">
        <text class="step-back-arrow">‹</text>
      </view>
      <text class="card-nav-title">酒局卡片</text>
    </view>

    <!-- 大卡片预览 -->
    <view class="card-preview-area">
      <DrinkCard v-if="record" :record="record" />
      <view v-else class="card-empty">暂无记录</view>
    </view>

    <!-- 操作按钮 -->
    <view class="card-actions">
      <button class="btn-cta save-btn" :loading="saving" :disabled="saving" @click="saveToAlbum">
        <text>{{ saving ? '保存中...' : '保存到相册' }}</text>
      </button>
      <button class="btn-secondary share-btn" open-type="share">
        <text>分享给好友</text>
      </button>
      <button class="close-home-btn" @click="closeToHome">
        <text class="close-home-icon">⌂</text>
        <text>完成，返回首页</text>
      </button>
    </view>

    <canvas canvas-id="shareCanvas" class="export-canvas" :style="{width:'750px',height:'1600px'}"></canvas>
  </view>
</template>

<script>
import DrinkCard from '../../components/DrinkCard.vue'
import client from '../../common/api'
import { getRecords } from '../../common/mock-data'
import { calcStandardCups, unitToMl } from '../../common/utils'
import { DRINK_CATEGORIES, FOOD_CATEGORIES, DRINK_QUOTES, FEELINGS } from '../../common/constants'
import themeMixin from '../../common/theme-mixin'

const UNIT_NAMES = { ml: 'ml', liang: '两', bottle: '瓶', cup: '杯', can: '听', shot: 'shot' }

export default {
  mixins: [themeMixin],
  components: { DrinkCard },
  data() {
    const sysInfo = uni.getSystemInfoSync()
    return {
      statusBarHeight: sysInfo.statusBarHeight || 25,
      record: null,
      saving: false,
      saved: false,
      posterPath: '' // 预生成的海报图片路径
    }
  },
  async onLoad(options) {
    if (options && options.recordId) {
      try {
        const resp = await client.GetRecordDetail({ id: options.recordId })
        const rec = resp.data || resp
        if (rec) {
          this.record = {
            ...rec,
            mode: String(rec.mode),
            feeling: rec.feeling ? String(rec.feeling) : null,
            visibility: rec.visibility ? String(rec.visibility) : 'private',
            drinks: (rec.drinks || []).map(d => ({
              ...d,
              category: String(d.category),
              unit: String(d.unit)
            }))
          }
        }
      } catch (e) {
        console.warn('获取记录详情失败，降级本地:', e)
      }
    }
    if (!this.record) this.record = this.loadLocalRecord(options.recordId) || this.fallback()
  },
  onReady() {
    // 页面渲染完成后预生成海报，供分享使用
    this.preGeneratePoster()
  },
  methods: {
    loadLocalRecord(id) {
      if (!id) return null
      try {
        const records = getRecords()
        const found = records.find(r => r.id === id)
        if (!found) return null
        return {
          ...found,
          mode: String(found.mode || 'drank'),
          feeling: found.feeling ? String(found.feeling) : null,
          visibility: found.visibility ? String(found.visibility) : 'private',
          drinks: (found.drinks || []).map(d => {
            const ml = unitToMl(d.amount || 0, d.unit || 'ml')
            return {
              ...d,
              category: String(d.category || d.categoryId || ''),
              unit: String(d.unit || 'ml'),
              standardCups: d.standardCups || calcStandardCups(ml, d.degree || 0)
            }
          })
        }
      } catch (e) {
        console.warn('读取本地记录失败:', e)
        return null
      }
    },
    fallback() {
      return {
        date: new Date().toISOString().slice(0, 10), mode: 'drank',
        drinks: [{ category: 'beer', brand: '青岛啤酒', product: '经典', amount: 2, unit: 'bottle', degree: 4.3, standardCups: 3.4 }],
        food: { category: 'bbq', name: '烤串' }, feeling: 'tipsy', photos: [], standardCupsTotal: 3.4
      }
    },

    // ===== 保存流程 =====
    async saveToAlbum() {
      if (this.saving) return
      this.saving = true
      try {
        const contentH = await this.drawExportCard()
        const path = await this.exportImg(contentH)
        await this.saveImg(path)
        this.saved = true
        uni.showToast({ title: '已保存到相册', icon: 'success' })
      } catch (e) {
        console.error('保存失败:', e)
        uni.showToast({ title: e.message || e.msg || '保存失败', icon: 'none', duration: 3000 })
      } finally { this.saving = false }
    },

    loadImg(src) {
      return new Promise(r => {
        if (!src) return r(null)
        uni.getImageInfo({ src, success: res => r(res.path), fail: () => r(null) })
      })
    },

    // ===== 海报绘制（醉美夜色风格） =====
    async drawExportCard() {
      const ctx = uni.createCanvasContext('shareCanvas', this)
      const W = 750
      const rec = this.record
      const P = 56 // 内边距
      const maxW = W - P * 2
      const F = '-apple-system, PingFang SC, Helvetica Neue, sans-serif'

      // 色彩定义
      const AMBER = '#E8A838'
      const AMBER_DIM = 'rgba(232,168,56,0.7)'
      const AMBER_FAINT = 'rgba(232,168,56,0.3)'
      const WHITE = '#FFFFFF'
      const WHITE_85 = 'rgba(255,255,255,0.85)'
      const WHITE_30 = 'rgba(255,255,255,0.3)'
      const WHITE_15 = 'rgba(255,255,255,0.15)'
      const WHITE_05 = 'rgba(255,255,255,0.05)'

      // 动态计算卡片高度
      const drinks = rec.drinks || []
      const photoCount = (rec.photos || []).length
      let photoAreaH = 0
      const gap = 12
      const colW = (maxW - gap) / 2
      if (photoCount === 0) photoAreaH = 240
      else if (photoCount === 1) photoAreaH = 340
      else if (photoCount === 2) photoAreaH = colW
      else if (photoCount === 3) photoAreaH = 240 + gap + colW
      else if (photoCount === 4) photoAreaH = 2 * colW + gap
      else if (photoCount === 5) photoAreaH = 240 + gap + 2 * (colW + gap) - gap
      else photoAreaH = 3 * colW + 2 * gap

      const drinkH = drinks.length * 52 + (rec.food ? 52 : 0)
      const feelingH = rec.feeling ? 64 : 0
      const cardH = 56 + 50 + photoAreaH + 32 + feelingH + 32 + 60 + drinkH + 32 + 50 + 32 + 120 + 40 + 100 + 40

      // === 背景渐变（深紫夜色） ===
      const bgGrad = ctx.createLinearGradient(0, 0, W * 0.3, cardH)
      bgGrad.addColorStop(0, '#1C1428')
      bgGrad.addColorStop(0.4, '#0F0A1A')
      bgGrad.addColorStop(1, '#0A0710')
      ctx.setFillStyle(bgGrad)
      ctx.fillRect(0, 0, W, cardH)

      // 装饰圆形
      ctx.setStrokeStyle('rgba(232,168,56,0.12)')
      ctx.setLineWidth(1.5)
      ctx.beginPath()
      ctx.arc(W - 40, 60, 150, 0, Math.PI * 2)
      ctx.stroke()
      ctx.beginPath()
      ctx.arc(30, cardH - 300, 100, 0, Math.PI * 2)
      ctx.stroke()
      ctx.setFillStyle('rgba(232,168,56,0.03)')
      ctx.beginPath()
      ctx.arc(W - 80, 380, 60, 0, Math.PI * 2)
      ctx.fill()
      // 顶部光晕（用线性渐变模拟）
      const glowGrad = ctx.createLinearGradient(W / 2, 0, W / 2, 280)
      glowGrad.addColorStop(0, 'rgba(232,168,56,0.06)')
      glowGrad.addColorStop(1, 'rgba(232,168,56,0)')
      ctx.setFillStyle(glowGrad)
      ctx.fillRect(0, 0, W, 280)

      let y = 56

      // === 日期（居中 + 两侧线条） ===
      ctx.font = `500 22px ${F}`
      const dateStr = rec.date || ''
      const dateW = ctx.measureText(dateStr).width
      const dateX = (W - dateW) / 2
      // 左线
      const lineGrad1 = ctx.createLinearGradient(dateX - 80, y, dateX - 10, y)
      lineGrad1.addColorStop(0, 'transparent')
      lineGrad1.addColorStop(1, 'rgba(232,168,56,0.5)')
      ctx.setStrokeStyle(lineGrad1)
      ctx.setLineWidth(1.5)
      ctx.beginPath()
      ctx.moveTo(dateX - 80, y - 6)
      ctx.lineTo(dateX - 14, y - 6)
      ctx.stroke()
      // 右线
      const lineGrad2 = ctx.createLinearGradient(dateX + dateW + 14, y, dateX + dateW + 80, y)
      lineGrad2.addColorStop(0, 'rgba(232,168,56,0.5)')
      lineGrad2.addColorStop(1, 'transparent')
      ctx.setStrokeStyle(lineGrad2)
      ctx.beginPath()
      ctx.moveTo(dateX + dateW + 14, y - 6)
      ctx.lineTo(dateX + dateW + 80, y - 6)
      ctx.stroke()
      // 日期文字
      ctx.setFillStyle(AMBER_DIM)
      ctx.fillText(dateStr, dateX, y)
      y += 50

      // === 照片/图标区域 ===
      const photos = rec.photos || []
      if (photos.length > 0) {
        const imgs = await Promise.all(photos.map(p => this.loadImg(p)))
        if (photos.length === 1) {
          const heroH = 340
          ctx.save()
          this.rr(ctx, P, y, maxW, heroH, 24, 'fill')
          ctx.clip()
          if (imgs[0]) { try { ctx.drawImage(imgs[0], P, y, maxW, heroH) } catch (e) {} }
          else { ctx.setFillStyle(WHITE_05); ctx.fillRect(P, y, maxW, heroH) }
          ctx.restore()
          y += heroH + 32
        } else {
          const positions = []
          if (photos.length % 2 !== 0) {
            const heroH = 240
            positions.push({ x: P, y, w: maxW, h: heroH })
            const rowStart = y + heroH + gap
            for (let i = 1; i < photos.length; i += 2) {
              const row = Math.floor((i - 1) / 2)
              const rowY = rowStart + row * (colW + gap)
              positions.push({ x: P, y: rowY, w: colW, h: colW })
              if (i + 1 < photos.length) positions.push({ x: P + colW + gap, y: rowY, w: colW, h: colW })
            }
            const totalRows = Math.ceil((photos.length - 1) / 2)
            y = rowStart + totalRows * (colW + gap) - gap + 32
          } else {
            for (let i = 0; i < photos.length; i += 2) {
              const row = i / 2
              const rowY = y + row * (colW + gap)
              positions.push({ x: P, y: rowY, w: colW, h: colW })
              positions.push({ x: P + colW + gap, y: rowY, w: colW, h: colW })
            }
            y = y + (photos.length / 2) * (colW + gap) - gap + 32
          }
          for (let i = 0; i < positions.length; i++) {
            const pos = positions[i]
            ctx.save()
            this.rr(ctx, pos.x, pos.y, pos.w, pos.h, 16, 'fill')
            ctx.clip()
            if (imgs[i]) { try { ctx.drawImage(imgs[i], pos.x, pos.y, pos.w, pos.h) } catch (e) {} }
            else { ctx.setFillStyle(WHITE_05); ctx.fillRect(pos.x, pos.y, pos.w, pos.h) }
            ctx.restore()
          }
        }
      } else {
        // 图标圆形 + 光环
        const eR = 90
        const eCx = W / 2, eCy = y + eR + 20
        // 外环
        ctx.setStrokeStyle('rgba(232,168,56,0.15)')
        ctx.setLineWidth(2)
        ctx.beginPath()
        ctx.arc(eCx, eCy, eR + 20, 0, Math.PI * 2)
        ctx.stroke()
        // 内圆背景（用线性渐变模拟）
        const innerGrad = ctx.createLinearGradient(eCx, eCy - eR, eCx, eCy + eR)
        innerGrad.addColorStop(0, 'rgba(232,168,56,0.15)')
        innerGrad.addColorStop(1, 'rgba(232,168,56,0.04)')
        ctx.setFillStyle(innerGrad)
        ctx.beginPath()
        ctx.arc(eCx, eCy, eR, 0, Math.PI * 2)
        ctx.fill()
        // 图标
        const firstDrink = (rec.drinks || [])[0]
        const cat = firstDrink ? DRINK_CATEGORIES.find(cc => cc.id === firstDrink.category) : null
        if (cat && cat.icon) {
          this.drawJarIcon(ctx, eCx, eCy, 130)
        } else {
          const emoji = cat ? cat.emoji : '🥃'
          ctx.font = `80px ${F}`
          ctx.fillText(emoji, eCx - 40, eCy + 28)
        }
        y += (eR + 20) * 2 + 32
      }

      // === 感受徽章 ===
      if (rec.feeling) {
        const feeling = FEELINGS.find(f => f.id === rec.feeling)
        if (feeling) {
          const badgeText = `${feeling.emoji} ${feeling.name}  ${feeling.desc}`
          ctx.font = `500 24px ${F}`
          const bw = ctx.measureText(badgeText).width + 60
          const bx = (W - bw) / 2
          const bh = 48
          // 胶囊背景
          ctx.setFillStyle('rgba(232,168,56,0.1)')
          this.rr(ctx, bx, y, bw, bh, bh / 2, 'fill')
          // 边框
          ctx.setStrokeStyle('rgba(232,168,56,0.25)')
          ctx.setLineWidth(1.5)
          this.rr(ctx, bx, y, bw, bh, bh / 2, 'stroke')
          // 文字
          ctx.font = `500 24px ${F}`
          ctx.setFillStyle(AMBER)
          const tw = ctx.measureText(badgeText).width
          ctx.fillText(badgeText, (W - tw) / 2, y + 32)
          y += bh + 32
        }
      }

      // === 今夜菜单标题 ===
      // 背景卡片
      const menuY = y
      const menuH = 60 + drinkH + 20
      ctx.setFillStyle('rgba(255,255,255,0.02)')
      this.rr(ctx, P - 8, menuY, maxW + 16, menuH, 24, 'fill')
      ctx.setStrokeStyle(WHITE_05)
      ctx.setLineWidth(1.5)
      this.rr(ctx, P - 8, menuY, maxW + 16, menuH, 24, 'stroke')

      y += 36
      // 标题 "今夜菜单"
      ctx.font = `500 22px ${F}`
      const menuTitle = '今 夜 菜 单'
      const mtw = ctx.measureText(menuTitle).width
      const mtx = (W - mtw) / 2
      // 两侧圆点
      ctx.setFillStyle('rgba(232,168,56,0.5)')
      ctx.beginPath()
      ctx.arc(mtx - 24, y - 6, 4, 0, Math.PI * 2)
      ctx.fill()
      ctx.beginPath()
      ctx.arc(mtx + mtw + 24, y - 6, 4, 0, Math.PI * 2)
      ctx.fill()
      ctx.setFillStyle(AMBER_DIM)
      ctx.fillText(menuTitle, mtx, y)
      y += 40

      // === 酒水清单 ===
      drinks.forEach(d => {
        const cat = DRINK_CATEGORIES.find(cc => cc.id === d.category)
        const unitName = UNIT_NAMES[d.unit] || d.unit
        const detail = `${d.amount}${unitName}`

        let nameX = P + 12
        if (cat && cat.icon) {
          this.drawJarIcon(ctx, P + 12 + 14, y - 12, 28)
          nameX = P + 12 + 38
        } else {
          const emoji = cat ? cat.emoji : '🥃'
          ctx.font = `26px ${F}`
          ctx.fillText(emoji, P + 12, y)
          nameX = P + 12 + 36
        }

        ctx.font = `500 28px ${F}`
        ctx.setFillStyle(WHITE)
        ctx.fillText(d.brand, nameX, y)
        const brandW = ctx.measureText(d.brand).width

        // 虚线引导线
        const dotsStartX = nameX + brandW + 16
        const dotsEndX = W - P - 12 - ctx.measureText(detail).width - 16
        ctx.setStrokeStyle(WHITE_15)
        ctx.setLineWidth(1)
        ctx.setLineDash([4, 6])
        ctx.beginPath()
        ctx.moveTo(dotsStartX, y - 6)
        ctx.lineTo(dotsEndX, y - 6)
        ctx.stroke()
        ctx.setLineDash([])

        // 用量
        ctx.font = `bold 24px ${F}`
        ctx.setFillStyle(AMBER)
        const dw = ctx.measureText(detail).width
        ctx.fillText(detail, W - P - 12 - dw, y)

        y += 52
      })

      // 配餐
      if (rec.food) {
        const food = FOOD_CATEGORIES.find(f => f.id === rec.food.category)
        const foodName = food ? food.name : '美食'
        ctx.font = `26px ${F}`
        ctx.fillText('🍲', P + 12, y)
        ctx.font = `500 28px ${F}`
        ctx.setFillStyle(WHITE)
        ctx.fillText(foodName, P + 48, y)
        ctx.font = `bold 24px ${F}`
        ctx.setFillStyle(AMBER)
        ctx.fillText('佐酒', W - P - 12 - ctx.measureText('佐酒').width, y)
        y += 52
      }

      y += 32

      // === 分割装饰 ===
      const divY = y
      const divGrad = ctx.createLinearGradient(P, divY, W - P, divY)
      divGrad.addColorStop(0, 'transparent')
      divGrad.addColorStop(0.5, 'rgba(232,168,56,0.2)')
      divGrad.addColorStop(1, 'transparent')
      ctx.setStrokeStyle(divGrad)
      ctx.setLineWidth(1.5)
      ctx.beginPath()
      ctx.moveTo(P, divY)
      ctx.lineTo(W / 2 - 30, divY)
      ctx.stroke()
      ctx.beginPath()
      ctx.moveTo(W / 2 + 30, divY)
      ctx.lineTo(W - P, divY)
      ctx.stroke()
      ctx.font = `24px ${F}`
      ctx.fillText('🥂', W / 2 - 12, divY + 8)
      y += 50

      // === 酒言酒语 ===
      const quote = DRINK_QUOTES[Math.floor(Math.random() * DRINK_QUOTES.length)]
      // 上引号
      ctx.font = `48px Georgia, serif`
      ctx.setFillStyle(AMBER_FAINT)
      ctx.fillText('“', P + 20, y + 10)
      y += 20
      // 引文
      ctx.font = `italic 26px ${F}`
      ctx.setFillStyle(WHITE_85)
      let dq = quote
      if (ctx.measureText(dq).width > maxW - 40) {
        while (dq.length > 0 && ctx.measureText(dq + '…').width > maxW - 40) dq = dq.slice(0, -1)
        dq += '…'
      }
      const qw = ctx.measureText(dq).width
      ctx.fillText(dq, (W - qw) / 2, y + 16)
      y += 44
      // 下引号
      ctx.font = `48px Georgia, serif`
      ctx.setFillStyle(AMBER_FAINT)
      ctx.fillText('”', W - P - 40, y)
      y += 56

      // === 品牌底栏 ===
      // 分割线
      ctx.setStrokeStyle(WHITE_05)
      ctx.setLineWidth(1.5)
      ctx.beginPath()
      ctx.moveTo(P, y)
      ctx.lineTo(W - P, y)
      ctx.stroke()
      y += 36

      ctx.font = `bold 26px ${F}`
      ctx.setFillStyle(AMBER_DIM)
      ctx.fillText('干杯日记', P, y)
      y += 30
      ctx.font = `normal 20px ${F}`
      ctx.setFillStyle(WHITE_30)
      ctx.fillText('记录每一杯的故事', P, y)

      // 二维码占位
      const qrSize = 80
      const qrX = W - P - qrSize
      const qrY = y - 50
      ctx.setStrokeStyle('rgba(232,168,56,0.2)')
      ctx.setLineWidth(1.5)
      this.rr(ctx, qrX, qrY, qrSize, qrSize, 12, 'stroke')
      ctx.setFillStyle('rgba(232,168,56,0.04)')
      this.rr(ctx, qrX, qrY, qrSize, qrSize, 12, 'fill')

      return new Promise(resolve => {
        ctx.draw(false, () => setTimeout(() => resolve(cardH), 600))
      })
    },

    rr(ctx, x, y, w, h, r, act) {
      ctx.beginPath()
      ctx.moveTo(x + r, y)
      ctx.arcTo(x + w, y, x + w, y + h, r)
      ctx.arcTo(x + w, y + h, x, y + h, r)
      ctx.arcTo(x, y + h, x, y, r)
      ctx.arcTo(x, y, x + w, y, r)
      ctx.closePath()
      if (act === 'stroke') ctx.stroke()
      else ctx.fill()
    },

    // 绘制白酒坛子图标（Canvas 矢量，保证导出海报一致性）
    drawJarIcon(ctx, cx, cy, s) {
      ctx.save()
      ctx.translate(cx - s / 2, cy - s / 2)
      const u = s / 100

      // 红绸蝴蝶结
      ctx.setFillStyle('#C62828')
      ctx.beginPath()
      ctx.moveTo(50 * u, 22 * u)
      ctx.bezierCurveTo(43 * u, 13 * u, 31 * u, 14 * u, 33 * u, 21 * u)
      ctx.bezierCurveTo(34.5 * u, 26 * u, 44 * u, 26 * u, 50 * u, 22 * u)
      ctx.closePath()
      ctx.fill()
      ctx.beginPath()
      ctx.moveTo(50 * u, 22 * u)
      ctx.bezierCurveTo(57 * u, 13 * u, 69 * u, 14 * u, 67 * u, 21 * u)
      ctx.bezierCurveTo(65.5 * u, 26 * u, 56 * u, 26 * u, 50 * u, 22 * u)
      ctx.closePath()
      ctx.fill()
      // 结带飘尾
      ctx.setFillStyle('#A61B1B')
      ctx.beginPath()
      ctx.moveTo(44 * u, 24 * u)
      ctx.lineTo(37 * u, 35 * u)
      ctx.lineTo(44 * u, 32 * u)
      ctx.closePath()
      ctx.fill()
      ctx.beginPath()
      ctx.moveTo(56 * u, 24 * u)
      ctx.lineTo(63 * u, 35 * u)
      ctx.lineTo(56 * u, 32 * u)
      ctx.closePath()
      ctx.fill()
      // 结心
      ctx.setFillStyle('#E53935')
      ctx.beginPath()
      ctx.arc(50 * u, 22 * u, 3.5 * u, 0, Math.PI * 2)
      ctx.fill()

      // 坛盖
      ctx.setFillStyle('#8D6E63')
      this.rr(ctx, 41 * u, 25 * u, 18 * u, 7 * u, 3.5 * u, 'fill')

      // 坛颈
      ctx.setFillStyle('#191919')
      ctx.beginPath()
      ctx.moveTo(43 * u, 31 * u)
      ctx.lineTo(57 * u, 31 * u)
      ctx.lineTo(59 * u, 39 * u)
      ctx.lineTo(41 * u, 39 * u)
      ctx.closePath()
      ctx.fill()

      // 坛身
      ctx.beginPath()
      ctx.moveTo(41 * u, 39 * u)
      ctx.bezierCurveTo(27 * u, 45 * u, 23 * u, 58 * u, 25 * u, 69 * u)
      ctx.bezierCurveTo(27 * u, 82 * u, 37 * u, 91 * u, 50 * u, 91 * u)
      ctx.bezierCurveTo(63 * u, 91 * u, 73 * u, 82 * u, 75 * u, 69 * u)
      ctx.bezierCurveTo(77 * u, 58 * u, 73 * u, 45 * u, 59 * u, 39 * u)
      ctx.closePath()
      ctx.fill()

      // 釉面高光
      ctx.setStrokeStyle('rgba(255,255,255,0.28)')
      ctx.setLineWidth(Math.max(1, 4 * u))
      ctx.setLineCap('round')
      ctx.beginPath()
      ctx.moveTo(35 * u, 47 * u)
      ctx.bezierCurveTo(30 * u, 53 * u, 29 * u, 63 * u, 31 * u, 71 * u)
      ctx.stroke()

      // 红色菱形酒标
      ctx.setFillStyle('#D32F2F')
      ctx.beginPath()
      ctx.moveTo(50 * u, 49 * u)
      ctx.lineTo(64 * u, 65 * u)
      ctx.lineTo(50 * u, 81 * u)
      ctx.lineTo(36 * u, 65 * u)
      ctx.closePath()
      ctx.fill()
      ctx.setStrokeStyle('#F9A825')
      ctx.setLineWidth(Math.max(1, 1.6 * u))
      ctx.stroke()

      // 酒字
      ctx.setFillStyle('#FFF8E1')
      ctx.font = `bold ${Math.max(6, Math.round(17 * u))}px KaiTi, STKaiti, SimSun, serif`
      ctx.setTextAlign('center')
      ctx.setTextBaseline('middle')
      ctx.fillText('酒', 50 * u, 66 * u)
      ctx.setTextAlign('left')
      ctx.setTextBaseline('alphabetic')

      ctx.restore()
    },

    exportImg(contentH) {
      return new Promise((resolve, reject) => {
        const cropH = Math.min(contentH || 1600, 1600)
        uni.canvasToTempFilePath({
          canvasId: 'shareCanvas', quality: 1,
          x: 0, y: 0, width: 750, height: cropH,
          destWidth: 750, destHeight: cropH,
          success: res => resolve(res.tempFilePath),
          fail: err => reject({ msg: '导出失败: ' + (err.errMsg || '') })
        }, this)
      })
    },

    saveImg(fp) {
      return new Promise((resolve, reject) => {
        uni.saveImageToPhotosAlbum({
          filePath: fp, success: () => resolve(),
          fail: err => {
            if (err.errMsg && err.errMsg.includes('auth deny')) {
              uni.showModal({
                title: '提示', content: '需要授权保存相册',
                confirmText: '去设置', success: r => { if (r.confirm) uni.openSetting() }
              })
              reject({ msg: '请授权相册' })
            } else reject({ msg: '保存失败' })
          }
        })
      })
    },

    shareToFriend() {
      // open-type="share" 已直接触发转发，此方法保留作为兜底提示
      uni.showToast({ title: '点击右上角「···」可分享给好友', icon: 'none' })
    },

    // 预生成海报图片（分享时用作 imageUrl）
    async preGeneratePoster() {
      if (!this.record) return
      try {
        const contentH = await this.drawExportCard()
        const path = await this.exportImg(contentH)
        this.posterPath = path
      } catch (e) {
        console.warn('预生成海报失败:', e)
      }
    },

    goBack() {
      console.log('goBack called, saved:', this.saved)
      if (this.saved) {
        this._doBack()
        return
      }
      uni.showModal({
        title: '离开前保存海报？',
        content: '海报还未保存到相册，离开后需要重新生成。',
        confirmText: '保存并离开',
        cancelText: '直接离开',
        success: async (res) => {
          console.log('modal result:', res)
          if (res.confirm) {
            try { await this.saveToAlbum() } catch (e) { /* ignore */ }
          }
          this._doBack()
        },
        fail: (err) => {
          console.error('showModal fail:', err)
          this._doBack()
        }
      })
    },
    closeToHome() {
      uni.switchTab({ url: '/pages/index/index' })
    },
    _doBack() {
      console.log('_doBack called, pages:', getCurrentPages().length)
      if (getCurrentPages().length > 1) {
        uni.navigateBack({
          fail: (err) => {
            console.error('navigateBack fail:', err)
            uni.reLaunch({ url: '/pages/index/index' })
          }
        })
      } else {
        console.log('no pages to go back to, reLaunch to index')
        uni.reLaunch({ url: '/pages/index/index' })
      }
    }
  },
  onShareAppMessage() {
    const rec = this.record
    const drinks = (rec && rec.drinks) || []
    const first = drinks[0]
    const cat = first ? DRINK_CATEGORIES.find(c => c.id === first.category) : null
    const title = cat
      ? `今晚喝了${cat.name}「${first.brand || ''}」- 干杯日记`
      : '今晚的酒局记录 - 干杯日记'
    return {
      title,
      path: '/pages/index/index',
      imageUrl: this.posterPath || undefined
    }
  },
  onShareTimeline() {
    return {
      title: '今晚的酒局记录 - 干杯日记',
      query: ''
    }
  },
  onBackPress() {
    this.goBack()
    return true
  }
}
</script>

<style lang="scss" scoped>
.card-page {
  padding: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background: $bg-base;
}

.card-nav {
  display: flex;
  align-items: center;
  gap: $sp-md;
  padding: $sp-md $sp-lg;
  padding-top: 0;
}

.step-back {
  width: 64rpx;
  height: 64rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: $radius-full;
  background: $bg-card;
  flex-shrink: 0;
}

.step-back-arrow {
  font-size: $fs-xl;
  color: $text-secondary;
  font-weight: $fw-bold;
}

.card-nav-title {
  font-size: $fs-lg;
  font-weight: $fw-bold;
  color: $text-primary;
}

/* 大卡片预览区 */
.card-preview-area {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: $sp-lg;
  min-height: 0;
}

.card-empty {
  color: $text-tertiary;
  font-size: $fs-md;
}

/* 操作按钮 */
.card-actions {
  padding: $sp-lg;
  padding-bottom: calc($sp-lg + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: $sp-md;
}

.save-btn {
  width: 100%;
  height: 92rpx;
  border-radius: $radius-full;
  font-size: $fs-lg;
  font-weight: $fw-bold;
  display: flex;
  align-items: center;
  justify-content: center;
}

.share-btn {
  width: 100%;
  height: 92rpx;
  border-radius: $radius-full;
  font-size: $fs-base;
  background: transparent;
  border: 2rpx solid var(--border-active, rgba(255, 255, 255, 0.12));
  color: $text-secondary;
  display: flex;
  align-items: center;
  justify-content: center;

  &::after {
    border: none;
  }
}

.close-home-btn {
  width: 100%;
  height: 80rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: $sp-xs;
  background: $bg-elevated;
  border: 2rpx solid var(--border-subtle, rgba(255, 255, 255, 0.10));
  border-radius: $radius-full;
  color: $text-secondary;
  font-size: $fs-base;
  font-weight: $fw-medium;
  transition: all $duration-fast $ease-out;

  &::after { display: none; }

  &:active {
    background: $amber-glow;
    border-color: rgba(232, 168, 56, 0.3);
    color: $amber;
    transform: scale(0.97);
  }
}

.close-home-icon {
  font-size: $fs-lg;
  line-height: 1;
}

.export-canvas {
  position: fixed;
  left: -9999px;
  top: -9999px;
}
</style>
