<template>
  <div class="inventory-page">
    <!-- Login prompt -->
    <div v-if="!auth.isLoggedIn" class="login-prompt">
      <p>登录后可管理个人库存</p>
      <button class="btn-primary" @click="ui.openLogin()">登录 / 注册</button>
    </div>
    <template v-else>
    <!-- Search + direct add -->
    <div class="search-box">
      <input
        class="search-input"
        v-model="searchQuery"
        placeholder="搜索精油名称，回车添加..."
        @keydown.enter="addFromSearch"
      />
      <button v-if="searchQuery" class="search-clear-btn" @click="searchQuery = ''">✕</button>
    </div>
    <!-- Search results for direct add -->
    <div v-if="searchQuery && searchResults.length" class="search-results">
      <div v-for="name in searchResults" :key="name" class="search-result-item" @click="addOil(name)">
        <span class="pick-dot" :class="{ active: ownedSet.has(name) }">{{ ownedSet.has(name) ? '✓' : '+' }}</span>
        {{ name }}
      </div>
    </div>

    <!-- Quick add kits -->
    <div class="kit-bar">
      <button class="kit-btn" @click="addKit('family')">家庭医生</button>
      <button class="kit-btn" @click="addKit('home3988')">居家呵护(3988)</button>
      <button class="kit-btn" @click="addKit('aroma')">芳香调理</button>
      <button class="kit-btn" @click="addKit('full')">全精油</button>
    </div>

    <!-- Owned Oils Section -->
    <div class="section-header">
      <span>🧴 已有精油 ({{ ownedOils.length }})</span>
      <button v-if="ownedOils.length" class="btn-sm btn-outline" @click="clearAll">清空</button>
    </div>
    <div v-if="ownedOils.length" class="owned-grid">
      <div v-for="name in ownedOils" :key="name" class="owned-chip" @click="toggleOil(name)">
        {{ name }} ✕
      </div>
    </div>
    <div v-else class="empty-hint">搜索添加精油，或点击上方套装快捷添加</div>

    <!-- Oil Picker Grid (collapsed by default) -->
    <div class="section-header clickable" @click="showPicker = !showPicker">
      <span>📦 全部精油</span>
      <span class="toggle-icon">{{ showPicker ? '▾' : '▸' }}</span>
    </div>
    <div v-if="showPicker" class="oil-picker-grid">
      <div
        v-for="name in oils.oilNames"
        :key="name"
        class="oil-pick-chip"
        :class="{ owned: ownedSet.has(name) }"
        @click="toggleOil(name)"
      >
        <span class="pick-dot" :class="{ active: ownedSet.has(name) }">{{ ownedSet.has(name) ? '✓' : '+' }}</span>
        <span class="pick-name">{{ name }}</span>
      </div>
    </div>

    <!-- Matching Recipes Section -->
    <div class="section-header" style="margin-top:20px">
      <span>📋 可做的配方 ({{ matchingRecipes.length }})</span>
    </div>
    <div v-if="matchingRecipes.length" class="matching-list">
      <div v-for="r in matchingRecipes" :key="r._id" class="match-card">
        <div class="match-name">{{ r.name }}</div>
        <div class="match-ings">
          <span
            v-for="ing in r.ingredients"
            :key="ing.oil"
            class="match-ing"
            :class="{ missing: !ownedSet.has(ing.oil) }"
          >
            {{ ing.oil }} {{ ing.drops }}滴
          </span>
        </div>
        <div class="match-meta">
          <span class="match-coverage">覆盖 {{ coveragePercent(r) }}%</span>
          <span v-if="missingOils(r).length" class="match-missing">
            缺少: {{ missingOils(r).join(', ') }}
          </span>
        </div>
      </div>
    </div>
    <div v-else class="empty-hint">
      {{ ownedOils.length ? '暂无完全匹配的配方' : '添加精油后自动推荐配方' }}
    </div>
    </template>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch } from 'vue'
import { useAuthStore } from '../stores/auth'
import { useOilsStore } from '../stores/oils'
import { useRecipesStore } from '../stores/recipes'
import { useUiStore } from '../stores/ui'
import { api } from '../composables/useApi'

const auth = useAuthStore()
const oils = useOilsStore()
const recipeStore = useRecipesStore()
const ui = useUiStore()

const searchQuery = ref('')
const ownedOils = ref([])
const loading = ref(false)
const showPicker = ref(false)

const ownedSet = computed(() => new Set(ownedOils.value))

const searchResults = computed(() => {
  if (!searchQuery.value.trim()) return []
  const q = searchQuery.value.trim().toLowerCase()
  return oils.oilNames.filter(n => n.toLowerCase().includes(q)).slice(0, 15)
})

// Kit definitions
const KITS = {
  family: ['乳香', '茶树', '薰衣草', '柠檬', '椒样薄荷', '保卫', '牛至', '乐活', '顺畅呼吸', '舒缓'],
  home3988: ['乳香', '野橘', '柠檬', '薰衣草', '椒样薄荷', '冬青', '茶树', '生姜', '柠檬草', '西班牙牛至',
    '西洋蓍草石榴籽', '乐活', '保卫', '新瑞活力', '舒缓', '安定情绪', '安宁神气', '顺畅呼吸', '柑橘清新', '芳香调理', '元气焕能'],
  aroma: ['薰衣草', '舒缓', '安定情绪', '芳香调理', '野橘', '椒样薄荷', '保卫', '茶树'],
  full: ['侧柏', '乳香', '雪松', '芫荽', '丝柏', '圆柚', '红橘', '冬青', '没药', '扁柏', '檀香', '姜黄', '玫瑰',
    '绿薄荷', '薰衣草', '永久花', '香蜂草', '迷迭香', '麦卢卡', '天竺葵', '蓝艾菊', '小茴香',
    '古巴香脂', '依兰依兰', '丁香花蕾', '柠檬尤加利', '藿香', '西班牙牛至尾草',
    '罗勒', '莱姆', '生姜', '柠檬', '茶树', '野橘', '香茅', '枫香',
    '芹菜籽', '岩兰草', '苦橙叶', '柠檬草', '山鸡椒', '黑云杉',
    '马郁兰', '佛手柑', '黑胡椒', '小豆蔻', '尤加利', '百里香',
    '椒样薄荷', '杜松浆果', '加州白鼠尾草',
    '快乐鼠尾草', '西伯利亚冷杉',
    '西班牙牛至', '斯里兰卡肉桂']
}

function addKit(kitName) {
  const kit = KITS[kitName]
  if (!kit) return
  let added = 0
  for (const name of kit) {
    // Match existing oil names (fuzzy)
    const match = oils.oilNames.find(n => n === name) || oils.oilNames.find(n => n.includes(name) || name.includes(n))
    if (match && !ownedOils.value.includes(match)) {
      ownedOils.value.push(match)
      added++
    }
  }
  ownedOils.value.sort((a, b) => a.localeCompare(b, 'zh'))
  saveInventory()
  ui.showToast(`已添加 ${added} 种精油`)
}

function addFromSearch() {
  if (searchResults.value.length > 0) {
    addOil(searchResults.value[0])
  }
}

function addOil(name) {
  if (!ownedOils.value.includes(name)) {
    ownedOils.value.push(name)
    ownedOils.value.sort((a, b) => a.localeCompare(b, 'zh'))
    saveInventory()
  }
  searchQuery.value = ''
}

const matchingRecipes = computed(() => {
  if (ownedOils.value.length === 0) return []
  return recipeStore.recipes
    .filter(r => {
      // Exclude coconut oil from matching
      const needed = r.ingredients.filter(i => i.oil !== '椰子油').map(i => i.oil)
      if (needed.length === 0) return false
      const coverage = needed.filter(o => ownedSet.value.has(o)).length
      // Show if at least 1 oil matches
      return coverage >= 1
    })
    .sort((a, b) => {
      const aCov = coverageRatio(a)
      const bCov = coverageRatio(b)
      if (bCov !== aCov) return bCov - aCov
      return a.name.localeCompare(b.name, 'zh')
    })
})

function coverageRatio(recipe) {
  const needed = recipe.ingredients.filter(i => i.oil !== '椰子油').map(i => i.oil)
  if (needed.length === 0) return 0
  return needed.filter(o => ownedSet.value.has(o)).length / needed.length
}

function coveragePercent(recipe) {
  return Math.round(coverageRatio(recipe) * 100)
}

function missingOils(recipe) {
  return recipe.ingredients
    .map(i => i.oil)
    .filter(o => !ownedSet.value.has(o))
}

async function loadInventory() {
  loading.value = true
  try {
    const res = await api('/api/inventory')
    if (res.ok) {
      const data = await res.json()
      ownedOils.value = data.oils || data || []
    }
  } catch {
    // inventory may not exist yet
  }
  loading.value = false
}

async function saveInventory() {
  try {
    await api('/api/inventory', {
      method: 'PUT',
      body: JSON.stringify({ oils: ownedOils.value }),
    })
  } catch {
    // silent save
  }
}

async function toggleOil(name) {
  const idx = ownedOils.value.indexOf(name)
  if (idx >= 0) {
    ownedOils.value.splice(idx, 1)
  } else {
    ownedOils.value.push(name)
    ownedOils.value.sort((a, b) => a.localeCompare(b, 'zh'))
  }
  await saveInventory()
}

async function clearAll() {
  ownedOils.value = []
  await saveInventory()
  ui.showToast('已清空库存')
}

onMounted(() => {
  loadInventory()
})
</script>

<style scoped>
.inventory-page {
  padding: 0 12px 24px;
}

.search-box {
  display: flex;
  align-items: center;
  background: #f8f7f5;
  border-radius: 10px;
  padding: 2px 8px;
  border: 1.5px solid #e5e4e7;
  margin-bottom: 14px;
}

.search-input {
  flex: 1;
  border: none;
  background: transparent;
  padding: 8px 6px;
  font-size: 14px;
  outline: none;
  font-family: inherit;
}

.search-clear-btn {
  border: none;
  background: transparent;
  cursor: pointer;
  color: #999;
  padding: 4px;
}

.search-results {
  margin-bottom: 10px; max-height: 200px; overflow-y: auto;
  border: 1.5px solid #e5e4e7; border-radius: 10px; background: #fff;
}
.search-result-item {
  padding: 8px 12px; cursor: pointer; font-size: 13px; display: flex; align-items: center; gap: 6px;
  border-bottom: 1px solid #f5f5f5;
}
.search-result-item:hover { background: #f0faf5; }
.search-result-item:last-child { border-bottom: none; }

.kit-bar { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.kit-btn {
  padding: 5px 12px; border: 1.5px solid #e5e4e7; border-radius: 20px; background: #fff;
  font-size: 12px; cursor: pointer; font-family: inherit; color: #6b6375;
}
.kit-btn:hover { border-color: #7ec6a4; color: #4a9d7e; }

.clickable { cursor: pointer; }
.toggle-icon { font-size: 12px; color: #999; margin-left: auto; }

.section-label {
  font-size: 12px;
  color: #b0aab5;
  margin-bottom: 8px;
  padding: 0 4px;
}

.oil-picker-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 20px;
}

.oil-pick-chip {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  border-radius: 20px;
  background: #f8f7f5;
  border: 1.5px solid #e5e4e7;
  cursor: pointer;
  font-size: 13px;
  transition: all 0.15s;
  color: #3e3a44;
}

.oil-pick-chip:hover {
  border-color: #d4cfc7;
  background: #f0eeeb;
}

.oil-pick-chip.owned {
  background: #e8f5e9;
  border-color: #7ec6a4;
  color: #2e7d5a;
}

.pick-dot {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #e5e4e7;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  color: #999;
}

.pick-dot.active {
  background: #4a9d7e;
  color: #fff;
}

.pick-name {
  font-size: 13px;
}

.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 4px;
  font-size: 14px;
  font-weight: 600;
  color: #3e3a44;
  margin-bottom: 8px;
}

.owned-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
}

.owned-chip {
  padding: 6px 12px;
  border-radius: 20px;
  background: #e8f5e9;
  border: 1.5px solid #7ec6a4;
  font-size: 13px;
  color: #2e7d5a;
  cursor: pointer;
  transition: all 0.15s;
}

.owned-chip:hover {
  background: #ffebee;
  border-color: #ef9a9a;
  color: #c62828;
}

.matching-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.match-card {
  padding: 12px 14px;
  background: #fff;
  border: 1.5px solid #e5e4e7;
  border-radius: 12px;
}

.match-name {
  font-weight: 600;
  font-size: 14px;
  color: #3e3a44;
  margin-bottom: 6px;
}

.match-ings {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 6px;
}

.match-ing {
  padding: 2px 8px;
  border-radius: 10px;
  background: #e8f5e9;
  font-size: 12px;
  color: #2e7d5a;
}

.match-ing.missing {
  background: #fff3e0;
  color: #e65100;
}

.match-meta {
  display: flex;
  gap: 10px;
  align-items: center;
  font-size: 12px;
}

.match-coverage {
  color: #4a9d7e;
  font-weight: 600;
}

.match-missing {
  color: #999;
}

.btn-sm {
  padding: 5px 12px;
  font-size: 12px;
  border-radius: 8px;
}

.btn-outline {
  background: #fff;
  color: #6b6375;
  border: 1.5px solid #d4cfc7;
  cursor: pointer;
  font-family: inherit;
}

.btn-outline:hover {
  background: #f8f7f5;
}

.empty-hint {
  text-align: center;
  color: #b0aab5;
  font-size: 13px;
  padding: 24px 0;
}

.login-prompt { text-align: center; padding: 60px 20px; color: #6b6375; }
.login-prompt p { margin-bottom: 16px; font-size: 15px; }
</style>
