<template>
  <view class="container">
    <view class="header">
      <text class="title">菜品管理</text>
      <button class="add" @click="startAdd">新增菜品</button>
    </view>

    <view v-for="item in list" :key="item.ID" class="row">
      <view class="left">
        <image :src="item.img" class="thumb" mode="aspectFill" />
        <view class="meta">
          <text class="name">{{ item.name }}</text>
          <text class="desc">分类：{{ getCategoryName(item.categoryId) }}</text>
        </view>
      </view>
      <view class="ops">
        <button size="mini" class="op-btn edit" @click="startEdit(item)">编辑</button>
        <button size="mini" class="op-btn delete" @click="remove(item)">删除</button>
      </view>
    </view>

    <uni-popup ref="popup" type="center">
      <view class="dialog">
        <text class="dialog-title">{{ current?.ID ? '编辑菜品' : '新增菜品' }}</text>
        <uni-easyinput v-model="form.name" placeholder="名称"></uni-easyinput>
        <uni-easyinput v-model="form.desc" placeholder="描述" type="textarea"></uni-easyinput>
        <view class="uploader">
          <view class="uploader-title">菜品图片</view>
          <view class="uploader-box" @click="chooseImage">
            <image v-if="form.img" :src="form.img" class="uploader-preview" mode="aspectFill" />
            <view v-else class="uploader-placeholder">
              <uni-icons type="camera" size="28" color="#999"></uni-icons>
              <text class="txt">点击上传</text>
            </view>
          </view>
          <view v-if="form.img" class="uploader-actions">
            <button size="mini" class="op-btn delete" @click.stop="form.img = ''">移除</button>
            <button size="mini" class="op-btn edit" @click.stop="chooseImage">更换</button>
          </view>
        </view>
        <picker :range="categoryList" range-key="name" @change="onCatChange">
          <view class="picker">分类：{{ pickCategoryName }}</view>
        </picker>
        <view class="dialog-actions">
          <button @click="close">取消</button>
          <button type="primary" @click="save">保存</button>
        </view>
      </view>
    </uni-popup>
  </view>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import api from '@/api'
import config from '@/config'

const list = ref([])
const categoryList = ref([])
const popup = ref(null)
const current = ref(null)
const form = ref({ name: '', desc: '', img: '', categoryId: null })
const selectedCatIdx = ref(-1)

const chooseImage = () => {
  uni.chooseImage({
    count: 1,
    sizeType: ['compressed','original'],
    success: async (res) => {
      const tempPath = res.tempFilePaths?.[0]
      if (!tempPath) return
      try {
        uni.showLoading({ title: '上传中' })
        // H5/APP/小程序通用上传
        const uploadRes = await new Promise((resolve, reject) => {
          const fullUrl = (config.baseUrl || '').replace(/\/$/, '') + '/user/upload'
          uni.uploadFile({
            url: fullUrl,
            filePath: tempPath,
            name: 'file',
            formData: {},
            header: { 'Authorization': uni.getStorageSync('token') || '' },
            success: (r) => {
              try { resolve(JSON.parse(r.data)) } catch (e) { resolve({ code: -1 }) }
            },
            fail: reject
          })
        })
        if (uploadRes?.code === 0 && uploadRes.data?.file?.url) {
          form.value.img = uploadRes.data.file.url
        } else {
          // 兜底：仍显示临时路径，避免影响表单交互
          form.value.img = tempPath
          uni.showToast({ title: uploadRes?.msg || '上传失败', icon: 'none' })
        }
      } catch (e) {
        form.value.img = tempPath
        uni.showToast({ title: '上传失败', icon: 'none' })
      } finally {
        uni.hideLoading()
      }
    }
  })
}

const load = async () => {
  const [catsRes, foodsRes] = await Promise.all([
    api.getFoodCategoryList({ page: 1, pageSize: 100 }),
    api.getFoodList({ page: 1, pageSize: 200 })
  ])
  if (catsRes?.code === 0) categoryList.value = catsRes.data?.list || []
  if (foodsRes?.code === 0) list.value = foodsRes.data?.list || []
}

onMounted(load)

const startAdd = () => { current.value = null; form.value = { name: '', desc: '', img: '', categoryId: null }; selectedCatIdx.value = -1; popup.value.open() }
const startEdit = (item) => {
  current.value = item
  form.value = { name: item.name, desc: item.desc, img: item.img, categoryId: item.categoryId }
  selectedCatIdx.value = categoryList.value.findIndex(c => c.ID === item.categoryId)
  popup.value.open()
}
const close = () => popup.value.close()

const onCatChange = (e) => {
  selectedCatIdx.value = Number(e.detail.value)
  form.value.categoryId = categoryList.value[selectedCatIdx.value]?.ID || null
}

const pickCategoryName = computed(() => {
  if (selectedCatIdx.value < 0) return '未选择'
  return categoryList.value[selectedCatIdx.value]?.name || '未选择'
})

const getCategoryName = (id) => categoryList.value.find(c => c.ID === id)?.name || '—'

const save = async () => {
  if (!form.value.name.trim()) { uni.showToast({ title: '请输入菜品名称', icon: 'none' }); return }
  if (!form.value.categoryId) { uni.showToast({ title: '请选择分类', icon: 'none' }); return }
  if (current.value?.ID) {
    await api.updateFood({ ID: current.value.ID, ...form.value })
  } else {
    await api.addFood(form.value)
  }
  close(); load()
}

const remove = (item) => {
  uni.showModal({ title: '删除确认', content: `确定删除“${item.name}”吗？`, success: async (res) => { if (res.confirm) { await api.deleteFood({ id: item.ID }); load() } } })
}
</script>

<style lang="scss" scoped>
.container {
  min-height: 100vh;
  padding: 24rpx;
  background: linear-gradient(135deg, #FFE4F0 0%, #F3E8FF 50%, #EDE7FF 100%);
}
.header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24rpx; }
.title { font-weight: 700; font-size: 34rpx; color: #6A4C93; }
.add { background: linear-gradient(135deg, #FF7EB3 0%, #FF758C 100%); color:#fff; border:none; border-radius: 28rpx; padding: 16rpx 26rpx; font-size: 26rpx; box-shadow: 0 6rpx 16rpx rgba(255, 117, 140, 0.35); }
.row { background: rgba(255,255,255,0.9); padding: 26rpx; border-radius: 18rpx; display:flex; justify-content: space-between; align-items:center; margin-bottom: 18rpx; box-shadow: 0 8rpx 24rpx rgba(140, 82, 255, 0.12); }
.left { display:flex; align-items:center; }
.thumb { width: 120rpx; height: 120rpx; border-radius: 12rpx; margin-right: 16rpx; }
.meta { .name{display:block; font-size:28rpx; font-weight:600; color:#3C2A4D;} .desc{color:#8c8c8c; margin-top:6rpx;} }
.ops { display:flex; gap: 12rpx; }
.op-btn { border:none; padding: 12rpx 20rpx; border-radius: 22rpx; font-size: 24rpx; color:#fff; }
.op-btn.edit { background: linear-gradient(135deg, #8A63F3 0%, #B089FF 100%); box-shadow: 0 4rpx 12rpx rgba(138,99,243,.3); }
.op-btn.delete { background: linear-gradient(135deg, #FF8FA3 0%, #FF6B9D 100%); box-shadow: 0 4rpx 12rpx rgba(255,107,157,.3); }
.dialog { background:#fff; padding: 30rpx; border-radius: 16rpx; width: 620rpx; }
.dialog-title { font-size: 30rpx; font-weight: 700; margin-bottom: 20rpx; display:block; color:#6A4C93; }
.uploader { margin: 16rpx 0; }
.uploader-title { color:#6A4C93; font-size: 26rpx; margin-bottom: 10rpx; }
.uploader-box { width: 100%; height: 200rpx; border: 2rpx dashed #d8c7ff; border-radius: 14rpx; display:flex; align-items:center; justify-content:center; background:#faf7ff; }
.uploader-placeholder { display:flex; align-items:center; gap: 10rpx; color:#999; }
.uploader-preview { width: 100%; height: 100%; border-radius: 12rpx; }
.uploader-actions { display:flex; gap: 12rpx; justify-content:flex-end; margin-top: 10rpx; }
.picker { padding: 20rpx 0; color:#666; }
.dialog-actions { display:flex; justify-content:flex-end; gap: 12rpx; margin-top: 20rpx; }
</style> 