<template>
  <!-- 菜品详情 -->
  <view class="content">
    <!-- 自定义返回栏，避免引用 NavBar 组件导致的 mp 依赖分析报错 -->
    <view class="back-bar">
      <view class="back-bar-inner">
        <view class="back-btn" hover-class="hover-active" @click="onBack">
          <text class="back-arrow">‹</text>
        </view>
        <text class="back-title">菜品详情</text>
      </view>
    </view>
    <swiper class="swiper" :circular="true" :autoplay="true" :interval="3000" v-if="swiperImages.length">
      <swiper-item v-for="(img, i) in swiperImages" :key="i">
        <image :src="getFileUrl(img)" mode="aspectFill" class="food-image"></image>
      </swiper-item>
    </swiper>
    <view class="swiper swiper-placeholder" v-else>
      <image :src="placeholderImage" mode="aspectFill" class="food-image"></image>
    </view>
    <view class="food-info">
      <view class="food-price">
        <text class="price-symbol">¥</text>
        <text class="price-main">{{ priceMain }}</text>
        <text class="price-decimal">.{{ priceDecimal }}</text>
      </view>
      <view class="food-sales">
        <image :src="getFileUrl('img/icon/star.png')" mode="aspectFill" class="star-icon"></image>
        <text class="sales-text">月售:{{ detail.monthlySales ?? 0 }}</text>
      </view>
    </view>

    <view class="food-desc">
      <view class="food-desc-title">{{ detail.name || detail.cuisineName || '—' }}</view>
      <view class="food-desc-tags" v-if="detailTags.length">
        <view v-for="(tag, ti) in detailTags" :key="ti" class="food-desc-tag" :class="tag.type || 'normal'">{{ tag.text }}</view>
      </view>
      <view class="food-desc-content">{{ detail.description || detail.desc || '暂无描述' }}</view>
    </view>
    <view class="food-desc">
      <view class="food-desc-title-intro">菜品介绍</view>
      <view class="food-desc-content">{{ detail.detailContent  || '暂无介绍' }}</view>
    </view>

    <!-- 底部按钮 -->
    <view class="bottom-btn">
      <!-- 左侧：数量选择器 -->
      <view class="quantity-selector">
        <view class="action-btn minus" :class="{ disabled: quantity === 0 }" @click="handleDecrease"
          hover-class="hover-active">
          <image :src="getFileUrl('img/icon/reduce1.png')" mode="aspectFit" class="action-icon" v-show="quantity == 0">
          </image>
          <image :src="getFileUrl('img/icon/reduce2.png')" mode="aspectFit" class="action-icon" v-show="quantity != 0">
          </image>
        </view>
        <view class="quantity">{{ quantity || 0 }}</view>
        <view class="action-btn plus" @click="handleIncrease" hover-class="hover-active">
          <image :src="getFileUrl('img/icon/add2.png')" mode="widthFix" class="action-icon" v-show="quantity < 99">
          </image>
          <image :src="getFileUrl('img/icon/add1.png')" mode="widthFix" class="action-icon" v-show="quantity >= 99">
          </image>
        </view>
      </view>
      <!-- 右侧：加入购物车按钮 -->
      <view class="add-to-cart-btn" @click="handleAddToCart" hover-class="hover-active">
        加入购物车
      </view>
    </view>

  </view>
</template>

<script setup>
import { ref, computed } from 'vue';
import { onLoad } from "@dcloudio/uni-app";
import { getFileUrl } from "@/utils/file.js";
import { GetCuisineDetail, GetOrderCart, PostOrderCartAdd, PostOrderCartUpdate } from "@/api/dining.js";

const quantity = ref(1);
const loading = ref(false);
const cuisineId = ref('');
const tableId = ref('');
/** 进入详情页时该菜品在购物车中的数量，用于与列表页一致的 Add/Update 逻辑 */
const initialCartQuantity = ref(0);
// 接口返回的菜品详情（兼容多种字段名）
const detail = ref({});

const placeholderImage = computed(() => getFileUrl('img/icon/star.png') || '');
// 轮播图列表：接口可能返回 image/cuisineImage/images（逗号分隔或数组）
const swiperImages = computed(() => {
  const d = detail.value;
  const raw = d?.images ?? d?.cuisineImage ?? d?.image ?? d?.imageUrl ?? '';
  if (Array.isArray(raw)) return raw.filter(Boolean);
  if (typeof raw === 'string' && raw) return raw.split(',').map((s) => s.trim()).filter(Boolean);
  return [];
});
const priceMain = computed(() => {
  const p = detail.value?.totalPrice ?? detail.value?.unitPrice ?? detail.value?.price ?? detail.value?.salePrice ?? 0;
  const num = Number(p);
  return Number.isNaN(num) ? '0' : String(Math.floor(num));
});
const priceDecimal = computed(() => {
  const p = detail.value?.totalPrice ?? detail.value?.unitPrice ?? detail.value?.price ?? detail.value?.salePrice ?? 0;
  const num = Number(p);
  if (Number.isNaN(num)) return '00';
  const dec = Math.round((num - Math.floor(num)) * 100);
  return String(dec).padStart(2, '0');
});
// 标签：接口可能返回 tags 数组、JSON 字符串或逗号/顿号分隔字符串，解析为 [{ text, type }] 数组
const detailTags = computed(() => {
  const t = detail.value?.tags;
  if (Array.isArray(t)) {
    return t.map((item) => {
      if (item == null) return { text: '', type: 'normal' };
      if (typeof item === 'string') return { text: item, type: 'normal' };
      return { text: item?.text ?? item?.tagName ?? item?.name ?? '', type: item?.type ?? 'normal' };
    }).filter((x) => x.text !== '' && x.text != null);
  }
  if (t && typeof t === 'string') {
    const s = t.trim();
    if (!s) return [];
    // 尝试 JSON 解析（如 "[{\"text\":\"招牌\",\"type\":\"signature\"}]"）
    if (s.startsWith('[')) {
      try {
        const arr = JSON.parse(s);
        if (Array.isArray(arr)) {
          return arr.map((item) => {
            if (item == null) return { text: '', type: 'normal' };
            if (typeof item === 'string') return { text: item, type: 'normal' };
            return { text: item?.text ?? item?.tagName ?? item?.name ?? '', type: item?.type ?? 'normal' };
          }).filter((x) => x.text !== '' && x.text != null);
        }
      } catch (_) {}
    }
    // 按逗号、顿号、空格等拆成数组
    return s.split(/[,，、\s]+/).map((part) => ({ text: part.trim(), type: 'normal' })).filter((x) => x.text !== '');
  }
  return [];
});

const onBack = () => {
  uni.navigateBack();
};

// 加减号只改本地数量，不调接口；只有点击「加入购物车」才调接口
const handleIncrease = () => {
  if (quantity.value >= 99) return;
  quantity.value++;
};

const handleDecrease = () => {
  if (quantity.value > 0) quantity.value--;
};

// 与列表页一致：购物车无该商品或数量从 0 到 1 用 Add，否则用 Update
const handleAddToCart = async () => {
  const id = cuisineId.value;
  const tid = tableId.value;
  if (!id) {
    uni.showToast({ title: '缺少菜品信息', icon: 'none' });
    return;
  }
  if (!tid) {
    uni.showToast({ title: '请先选择桌号', icon: 'none' });
    return;
  }
  const targetQty = quantity.value || 0;
  if (targetQty <= 0) {
    uni.showToast({ title: '请选择数量', icon: 'none' });
    return;
  }
  if (loading.value) return;
  loading.value = true;
  try {
    const needAdd = initialCartQuantity.value === 0 && targetQty >= 1;
    if (needAdd) {
      await PostOrderCartAdd({
        cuisineId: id,
        quantity: targetQty,
        tableId: tid
      });
    } else {
      await PostOrderCartUpdate({
        cuisineId: id,
        quantity: targetQty,
        tableId: tid
      });
    }
    uni.showToast({ title: '已加入购物车', icon: 'none' });
    setTimeout(() => uni.navigateBack(), 500);
  } catch (e) {
    // 与列表页一致：接口失败（如 code 400）时不保留本次修改，数量回滚为进入页时的购物车数量
    quantity.value = initialCartQuantity.value;
    uni.showToast({ title: e?.message || '加入失败', icon: 'none' });
  } finally {
    loading.value = false;
  }
};

onLoad(async (options) => {
  const id = options?.cuisineId ?? options?.id ?? '';
  const tid = options?.tableId ?? options?.tableid ?? uni.getStorageSync('currentTableId') ?? '';
  cuisineId.value = id;
  tableId.value = tid;
  // 从列表页带过来的购物车数量，用于底部数量展示和 Add/Update 判断
  const fromQuery = Math.max(0, Number(options?.quantity) || 0);
  quantity.value = fromQuery || 1;
  initialCartQuantity.value = fromQuery;

  if (!id) {
    uni.showToast({ title: '缺少菜品ID', icon: 'none' });
    return;
  }
  try {
    const res = await GetCuisineDetail(id, tid);
    const data = res?.data ?? res;
    detail.value = data || {};
  } catch (e) {
    uni.showToast({ title: e?.message || '加载失败', icon: 'none' });
  }
  // 有桌号时拉取购物车，以接口数量为准覆盖展示和 initialCartQuantity（与列表同步）
  if (tid) {
    try {
      const cartRes = await GetOrderCart(tid);
      const list = cartRes?.items ?? cartRes?.list ?? cartRes?.data?.items ?? [];
      const arr = Array.isArray(list) ? list : [];
      const cartItem = arr.find(
        (it) => String(it?.cuisineId ?? it?.id ?? '') === String(id)
      );
      const cartQty = cartItem ? (Number(cartItem.quantity) || 0) : 0;
      quantity.value = cartQty > 0 ? cartQty : quantity.value;
      initialCartQuantity.value = cartQty;
    } catch (_) {}
  }
});
</script>

<style lang="scss" scoped>
.back-bar {
  position: sticky;
  top: 0;
  z-index: 101;
  padding-top: constant(safe-area-inset-top);
  padding-top: env(safe-area-inset-top);
  background: rgba(0, 0, 0, 0.3);
}
.back-bar-inner {
  height: 88rpx;
  padding: 0 24rpx;
  display: flex;
  align-items: center;
}
.back-btn {
  width: 64rpx;
  height: 64rpx;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 16rpx;
  &.hover-active {
    opacity: 0.8;
  }
}
.back-arrow {
  font-size: 48rpx;
  color: #fff;
  font-weight: 300;
  line-height: 1;
  margin-left: -4rpx;
}
.back-title {
  font-size: 32rpx;
  color: #fff;
  font-weight: 500;
}

.swiper {
  width: 100%;
  height: 510rpx;
}

.food-image {
  width: 100%;
  height: 510rpx;
}

.food-info {
  width: 100%;
  height: 100rpx;
  background: linear-gradient(90deg, #1E1E1E 0%, #464646 100%);
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #fff;
  box-sizing: border-box;
  padding: 0 30rpx;

  .food-price {
    display: flex;
    align-items: baseline;
    line-height: 1;

    .price-symbol {
      font-size: 24rpx;
      font-weight: bold;
      margin-right: 10rpx;
    }

    .price-main {
      font-size: 44rpx;
      font-weight: bold;
    }

    .price-decimal {
      font-size: 24rpx;
      font-weight: bold;
    }
  }

  .food-sales {
    font-size: 22rpx;
    color: #fff;
    display: flex;
    align-items: center;
    gap: 4rpx;
  }

  .star-icon {
    width: 26rpx;
    height: 26rpx;
  }
}

.food-desc {
  width: 100%;
  padding: 30rpx;
  box-sizing: border-box;
  background-color: #fff;
  margin-top: 20rpx;

  .food-desc-title {
    font-weight: bold;
    font-size: 38rpx;
    color: #151515;
  }

  .food-desc-tags {
    display: flex;
    gap: 10rpx;
    margin-top: 10rpx;
  }

  .food-desc-tag {
    padding: 4rpx 12rpx;
    border-radius: 4rpx;
    font-size: 20rpx;

    &.signature {
      background: linear-gradient(90deg, #FCB13F 0%, #FC793D 100%);
      color: #fff;
    }

    &.spicy {
      background: #2E2E2E;
      color: #fff;
    }

    &.normal {
      background: #f0f0f0;
      color: #666;
    }
  }

  .food-desc-content {
    font-size: 27rpx;
    color: #666666;
    line-height: 38rpx;
    margin-top: 22rpx;
  }

  .food-desc-title-intro {
    font-weight: bold;
    font-size: 27rpx;
    color: #151515;
  }
}

.bottom-btn {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20rpx 30rpx;
  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
  box-sizing: border-box;
  background-color: #fff;
  box-shadow: 0rpx -11rpx 46rpx 0rpx rgba(0, 0, 0, 0.05);
}

.quantity-selector {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 214rpx;
  height: 58rpx;
  background: #F8F8F8;
  border-radius: 56rpx;
  box-sizing: border-box;
  padding: 0 3rpx;
}

.action-btn {
  width: 52rpx;
  height: 52rpx;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32rpx;
  font-weight: 600;
  transition: all 0.3s;
  background-color: #fff;

  .action-icon {
    width: 24rpx;
    height: 24rpx;
  }

  &.disabled {
    opacity: 0.5;
  }
}

.quantity {
  font-size: 30rpx;
  color: #000;
  min-width: 40rpx;
  text-align: center;
}

.add-to-cart-btn {
  width: 266rpx;
  height: 80rpx;
  margin-left: 20rpx;
  background: linear-gradient(90deg, #FF6B35 0%, #F7931E 100%);
  border-radius: 40rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 32rpx;
  font-weight: bold;
  transition: all 0.3s;

  &.hover-active {
    opacity: 0.8;
  }
}
</style>
