<template>
  <div class="inventory-page">
    <!-- Search -->
    <div class="search-box">
      <input
        class="search-input"
        v-model="searchQuery"
        placeholder="搜索精油..."
      />
      <button v-if="searchQuery" class="search-clear-btn" @click="searchQuery = ''">✕</button>
    </div>

    <!-- Oil Picker Grid -->
    <div class="section-label">点击添加到库存</div>
    <div class="oil-picker-grid">
      <div
        v-for="name in filteredOilNames"
        :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 v-if="filteredOilNames.length === 0" class="empty-hint">未找到精油</div>
    </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>

    <!-- 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>
  </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 ownedSet = computed(() => new Set(ownedOils.value))

const filteredOilNames = computed(() => {
  if (!searchQuery.value.trim()) return oils.oilNames
  const q = searchQuery.value.trim().toLowerCase()
  return oils.oilNames.filter(n => n.toLowerCase().includes(q))
})

const matchingRecipes = computed(() => {
  if (ownedOils.value.length === 0) return []
  return recipeStore.recipes
    .filter(r => {
      const needed = r.ingredients.map(i => i.oil)
      const coverage = needed.filter(o => ownedSet.value.has(o)).length
      return coverage >= Math.ceil(needed.length * 0.5)
    })
    .sort((a, b) => {
      const aCov = coverageRatio(a)
      const bCov = coverageRatio(b)
      return bCov - aCov
    })
})

function coverageRatio(recipe) {
  const needed = recipe.ingredients.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;
}

.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;
}
</style>
