<template>
  <view class="page-container">
    <!-- 顶部装饰背景 - 漂浮光球 -->
    <view class="bg-decoration"></view>

    <!-- 装饰光球 -->
    <view class="orb orb-1"></view>
    <view class="orb orb-2"></view>

    <view class="header-area">
      <view class="page-title">碎片合成</view>
      <view class="page-subtitle">Fragment Synthesis</view>
    </view>

    <scroll-view
      scroll-y
      class="content-scroll"
      refresher-enabled
      :refresher-triggered="isRefreshing"
      @refresherrefresh="onRefresh"
    >
      <!-- 加载状态 -->
      <view v-if="loading" class="loading-state">
        <view class="spinner"></view>
        <text>加载中...</text>
      </view>

      <!-- 空状态 -->
      <view v-else-if="recipes.length === 0" class="empty-state">
        <text class="empty-icon">🧩</text>
        <text class="empty-text">暂无可用的合成配方</text>
        <text class="empty-hint">敬请期待更多合成方案</text>
      </view>

      <!-- 配方卡片列表 -->
      <view v-else class="recipe-list">
        <view
          v-for="(recipe, index) in recipes"
          :key="recipe.id"
          class="recipe-ticket"
          :class="{ 'ticket-ready': recipe.can_synthesize }"
          :style="{ animationDelay: `${index * 0.1}s` }"
        >
          <!-- 左侧：目标商品主视觉 -->
          <view class="ticket-left">
            <view class="product-img-wrap">
              <image
                v-if="recipe.target_product"
                :src="getFirstImage(recipe.target_product.images_json)"
                mode="aspectFill"
                class="product-img"
              />
              <view v-else class="product-img-placeholder">
                <text>🎁</text>
              </view>
            </view>
            <!-- 可合成光晕 -->
            <view v-if="recipe.can_synthesize" class="ready-glow"></view>
            <view class="product-label">
              <text class="label-text" :class="recipe.can_synthesize ? 'label-ready' : 'label-lack'">
                {{ recipe.can_synthesize ? '可合成' : '待收集' }}
              </text>
            </view>
          </view>

          <!-- 分割线（带缺口） -->
          <view class="ticket-divider">
            <view class="notch notch-top"></view>
            <view class="divider-line"></view>
            <view class="notch notch-bottom"></view>
          </view>

          <!-- 右侧：配方信息 -->
          <view class="ticket-right">
            <view class="ticket-info">
              <text class="product-name">{{ recipe.target_product?.name || '目标商品' }}</text>
              <text class="recipe-name">{{ recipe.name }}</text>
              <text class="recipe-desc" v-if="recipe.description">{{ recipe.description }}</text>
            </view>

            <!-- 材料清单 -->
            <view class="materials-row">
              <view
                v-for="(mat, idx) in recipe.materials"
                :key="idx"
                class="mat-chip"
                :class="mat.owned_count >= mat.required_count ? 'mat-ok' : 'mat-lack'"
              >
                <text class="mat-name">{{ mat.name }}</text>
                <text class="mat-num">{{ mat.owned_count }}/{{ mat.required_count }}</text>
              </view>
            </view>

            <!-- 底部：进度 + 按钮 -->
            <view class="ticket-footer">
              <text class="ready-hint">
                {{ getReadyCount(recipe) }}/{{ recipe.materials?.length || 0 }} 材料就绪
              </text>
              <view
                class="synth-btn"
                :class="recipe.can_synthesize ? 'btn-ready' : 'btn-locked'"
                @tap="onSynthesize(recipe)"
              >
                <text class="btn-text">{{ synthesizing ? '合成中' : (recipe.can_synthesize ? '合成' : '不足') }}</text>
                <view v-if="recipe.can_synthesize" class="btn-shine"></view>
              </view>
            </view>
          </view>
        </view>
      </view>
    </scroll-view>
  </view>
</template>

<script setup>
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getSynthesisRecipes, doSynthesis } from '../../api/synthesis.js'

const loading = ref(true)
const synthesizing = ref(false)
const isRefreshing = ref(false)
const recipes = ref([])

function getFirstImage(imagesJson) {
  if (!imagesJson) return '/static/placeholder.png'
  try {
    const imgs = JSON.parse(imagesJson)
    return imgs && imgs.length > 0 ? imgs[0] : '/static/placeholder.png'
  } catch {
    return imagesJson
  }
}

function getReadyCount(recipe) {
  if (!recipe.materials) return 0
  return recipe.materials.filter(m => m.owned_count >= m.required_count).length
}

function getOverallProgress(recipe) {
  if (!recipe.materials || recipe.materials.length === 0) return 0
  return Math.round((getReadyCount(recipe) / recipe.materials.length) * 100)
}

async function loadRecipes() {
  loading.value = true
  const userId = uni.getStorageSync('user_id')
  if (!userId) {
    loading.value = false
    return
  }
  try {
    const res = await getSynthesisRecipes(userId)
    recipes.value = res?.list || []
  } catch (e) {
    console.error('loadRecipes error', e)
  } finally {
    loading.value = false
  }
}

async function onRefresh() {
  isRefreshing.value = true
  await loadRecipes()
  isRefreshing.value = false
}

async function onSynthesize(recipe) {
  if (synthesizing.value || !recipe.can_synthesize) return
  try {
    await new Promise((resolve, reject) => {
      uni.showModal({
        title: '确认合成',
        content: `确定要合成「${recipe.target_product?.name || '目标商品'}」吗？合成后碎片将被消耗。`,
        success: (res) => res.confirm ? resolve() : reject('cancel'),
        fail: reject
      })
    })
  } catch {
    return
  }

  synthesizing.value = true
  const userId = uni.getStorageSync('user_id')
  try {
    await doSynthesis(userId, recipe.id)
    uni.showToast({ title: '合成成功！', icon: 'success' })
    await loadRecipes()
  } catch (e) {
    uni.showToast({ title: e?.message || '合成失败', icon: 'none' })
  } finally {
    synthesizing.value = false
  }
}

onLoad(() => {
  loadRecipes()
})

const onShow = () => {
  if (!loading.value) loadRecipes()
}
defineExpose({ onShow })
</script>

<style lang="scss" scoped>
.page-container {
  min-height: 100vh;
  background: $bg-page;
  position: relative;
  overflow: hidden;
}

/* 装饰光球 */
.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(80rpx);
  opacity: 0.5;
  pointer-events: none;
}
.orb-1 {
  width: 500rpx;
  height: 500rpx;
  background: radial-gradient(circle, rgba($brand-primary, 0.25), transparent 70%);
  top: -80rpx;
  right: -80rpx;
  animation: float 10s ease-in-out infinite;
}
.orb-2 {
  width: 400rpx;
  height: 400rpx;
  background: radial-gradient(circle, rgba($brand-primary, 0.15), transparent 70%);
  bottom: 200rpx;
  left: -100rpx;
  animation: float 14s ease-in-out infinite reverse;
}

@keyframes float {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(20rpx, 30rpx); }
}

/* Header */
.header-area {
  padding: $spacing-xl $spacing-lg;
  padding-top: calc(env(safe-area-inset-top) + 20rpx);
  position: relative;
  z-index: 1;
}

.page-title {
  font-size: 48rpx;
  font-weight: 900;
  color: $text-main;
  margin-bottom: 8rpx;
  letter-spacing: 1rpx;
  text-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
}

.page-subtitle {
  font-size: 24rpx;
  color: $text-tertiary;
  text-transform: uppercase;
  letter-spacing: 2rpx;
  font-weight: 600;
}

/* 滚动区 */
.content-scroll {
  height: calc(100vh - 220rpx);
  position: relative;
  z-index: 1;
}

/* 加载 */
.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 120rpx $spacing-lg;
  color: $text-tertiary;
  font-size: 26rpx;
  gap: 16rpx;
}

/* 空状态 */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 120rpx 0;
}

.empty-icon {
  font-size: 80rpx;
  margin-bottom: 20rpx;
}

.empty-text {
  color: $text-tertiary;
  font-size: 28rpx;
  margin-bottom: 10rpx;
}

.empty-hint {
  color: $text-tertiary;
  font-size: 24rpx;
  opacity: 0.6;
}

/* 配方列表 */
.recipe-list {
  display: flex;
  flex-direction: column;
  gap: 24rpx;
  padding: 0 $spacing-lg $spacing-xl;
}

/* 票券式卡片 */
.recipe-ticket {
  display: flex;
  background: #fff;
  border-radius: 20rpx;
  overflow: hidden;
  box-shadow: $shadow-card;
  animation: fadeInUp 0.5s ease-out backwards;
  position: relative;

  &.ticket-ready {
    box-shadow:
      $shadow-card,
      0 0 0 1.5rpx rgba($brand-primary, 0.25);
  }
}

@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(24rpx); }
  to { opacity: 1; transform: translateY(0); }
}

/* 左侧商品区 */
.ticket-left {
  width: 200rpx;
  flex-shrink: 0;
  background: linear-gradient(145deg, #FFF5EC, #FFF0E0);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 28rpx 16rpx;
  position: relative;
  overflow: hidden;
}

.ticket-ready .ticket-left {
  background: linear-gradient(145deg, #FFF5EC, #FFE8C8);
}

/* 可合成光晕 */
.ready-glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 40%, rgba($brand-primary, 0.12), transparent 70%);
  pointer-events: none;
}

.product-img-wrap {
  width: 120rpx;
  height: 120rpx;
  border-radius: 20rpx;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.7);
  box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.08);
  margin-bottom: 16rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.product-img {
  width: 100%;
  height: 100%;
}

.product-img-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 48rpx;
}

.product-label {
  padding: 4rpx 16rpx;
  border-radius: 100rpx;
  background: rgba(255, 255, 255, 0.8);
}

.label-text {
  font-size: 20rpx;
  font-weight: 700;

  &.label-ready {
    color: $brand-primary;
  }
  &.label-lack {
    color: $text-tertiary;
  }
}

/* 分割线（票券缺口效果） */
.ticket-divider {
  width: 28rpx;
  position: relative;
  background: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
}

.notch {
  width: 28rpx;
  height: 28rpx;
  background: $bg-page;
  border-radius: 50%;
  position: absolute;
  left: 0;
  z-index: 2;

  &.notch-top { top: -14rpx; }
  &.notch-bottom { bottom: -14rpx; }
}

.divider-line {
  width: 0;
  height: 75%;
  border-left: 2rpx dashed rgba(0, 0, 0, 0.1);
}

/* 右侧信息区 */
.ticket-right {
  flex: 1;
  padding: 24rpx 24rpx 20rpx;
  display: flex;
  flex-direction: column;
  gap: 14rpx;
  overflow: hidden;
  min-width: 0;
}

.ticket-info {
  display: flex;
  flex-direction: column;
  gap: 4rpx;
}

.product-name {
  font-size: 30rpx;
  font-weight: 800;
  color: $text-main;
  letter-spacing: 0.5rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.recipe-name {
  font-size: 22rpx;
  color: $text-sub;
  font-weight: 500;
}

.recipe-desc {
  font-size: 20rpx;
  color: $text-tertiary;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 材料芯片行 */
.materials-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8rpx;
}

.mat-chip {
  display: flex;
  align-items: center;
  gap: 6rpx;
  padding: 5rpx 12rpx;
  border-radius: 100rpx;
  background: rgba(0, 0, 0, 0.04);
  border: 1.5rpx solid rgba(0, 0, 0, 0.06);

  &.mat-ok {
    background: rgba($color-success, 0.08);
    border-color: rgba($color-success, 0.2);
  }

  &.mat-lack {
    background: rgba($color-error, 0.06);
    border-color: rgba($color-error, 0.15);
  }
}

.mat-name {
  font-size: 20rpx;
  color: $text-sub;
  max-width: 100rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mat-num {
  font-size: 20rpx;
  font-weight: 700;
  color: $text-tertiary;

  .mat-ok & { color: $color-success; }
  .mat-lack & { color: $color-error; }
}

/* 底部行：进度提示 + 按钮 */
.ticket-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 4rpx;
}

.ready-hint {
  font-size: 20rpx;
  color: $text-tertiary;
}

/* 合成按钮 - 小胶囊 */
.synth-btn {
  height: 56rpx;
  padding: 0 28rpx;
  border-radius: 28rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
  transition: all 0.2s cubic-bezier(0.18, 0.89, 0.32, 1.28);

  &.btn-ready {
    background: $gradient-brand;
    box-shadow: 0 6rpx 16rpx rgba($brand-primary, 0.3);

    &:active {
      transform: scale(0.94);
      opacity: 0.9;
    }
  }

  &.btn-locked {
    background: rgba(0, 0, 0, 0.05);
  }
}

.btn-text {
  font-size: 24rpx;
  font-weight: 700;
  letter-spacing: 1rpx;
  position: relative;
  z-index: 2;

  .btn-ready & { color: #fff; }
  .btn-locked & { color: $text-tertiary; }
}

.btn-shine {
  position: absolute;
  top: 0;
  left: -100%;
  width: 60%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
  transform: skewX(-20deg);
  animation: shine 3s infinite;
}

@keyframes shine {
  0% { left: -100%; }
  20%, 100% { left: 200%; }
}

/* 加载动画 */
.spinner {
  width: 28rpx;
  height: 28rpx;
  border: 3rpx solid $bg-secondary;
  border-top-color: $brand-primary;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}
</style>
