<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { api, type ActiveBookState, type WordBook } from '../api/request'

const router = useRouter()

const books = ref<WordBook[]>([])
const active = ref<ActiveBookState | null>(null)
const selectedBookId = ref<number | null>(null)
const dailyTarget = ref(12)
const masterRequired = ref(3)
const weakThreshold = ref(2)
const loading = ref(true)
const saveState = ref<'idle' | 'saving' | 'success' | 'error'>('idle')
const toast = ref<{ text: string; type: 'success' | 'error' } | null>(null)

let toastTimer: ReturnType<typeof setTimeout> | null = null
let successTimer: ReturnType<typeof setTimeout> | null = null

const LEVEL_GROUPS = [
  { key: 'primary', label: '小学（按年级）' },
  { key: 'junior', label: '初中（按年级）' },
  { key: 'senior', label: '高中（按年级）' },
  { key: 'business', label: '商务' },
] as const

const groupedBooks = computed(() =>
  LEVEL_GROUPS.map((g) => ({
    ...g,
    books: books.value.filter((b) => b.level === g.key),
  })).filter((g) => g.books.length > 0)
)

const selectedBook = computed(() =>
  books.value.find((b) => b.id === selectedBookId.value) ?? null
)

const saveLabel = computed(() => {
  if (saveState.value === 'saving') return '保存中...'
  if (saveState.value === 'success') return '已保存 ✓'
  return '保存设置'
})

function applyParamsFromBook(book: WordBook) {
  dailyTarget.value = book.daily_target
  masterRequired.value = book.master_required_count
  weakThreshold.value = book.weak_wrong_threshold
}

function applyActive(data: ActiveBookState) {
  active.value = data
  if (data.book) {
    selectedBookId.value = data.book.id
  }
  if (data.settings) {
    dailyTarget.value = data.settings.daily_target
    masterRequired.value = data.settings.master_required_count
    weakThreshold.value = data.settings.weak_wrong_threshold
  }
}

function showToast(text: string, type: 'success' | 'error') {
  if (toastTimer) clearTimeout(toastTimer)
  toast.value = { text, type }
  toastTimer = setTimeout(() => {
    toast.value = null
  }, 2800)
}

function syncParamsForSelection(bookId: number | null) {
  if (!bookId) return
  const book = books.value.find((b) => b.id === bookId)
  if (!book) return
  if (active.value?.book?.id === bookId && active.value.settings) {
    dailyTarget.value = active.value.settings.daily_target
    masterRequired.value = active.value.settings.master_required_count
    weakThreshold.value = active.value.settings.weak_wrong_threshold
  } else {
    applyParamsFromBook(book)
  }
}

watch(selectedBookId, (id) => {
  if (loading.value) return
  syncParamsForSelection(id)
})

onMounted(async () => {
  try {
    const [booksRes, activeRes] = await Promise.all([api.listBooks(), api.getActiveBook()])
    books.value = booksRes.data
    applyActive(activeRes.data)
    if (!selectedBookId.value && books.value.length) {
      selectedBookId.value = books.value[0].id
      syncParamsForSelection(selectedBookId.value)
    }
  } finally {
    loading.value = false
  }
})

async function save() {
  if (!selectedBookId.value || saveState.value === 'saving') return
  saveState.value = 'saving'
  try {
    const { data } = await api.updateBookSettings({
      book_id: selectedBookId.value,
      daily_target: dailyTarget.value,
      master_required_count: masterRequired.value,
      weak_wrong_threshold: weakThreshold.value,
    })
    applyActive(data)
    saveState.value = 'success'
    const title = data.book?.title ?? '词书'
    showToast(`「${title}」设置已生效`, 'success')
    if (successTimer) clearTimeout(successTimer)
    successTimer = setTimeout(() => {
      if (saveState.value === 'success') saveState.value = 'idle'
    }, 2200)
  } catch {
    saveState.value = 'error'
    showToast('保存失败，请检查网络后重试', 'error')
    setTimeout(() => {
      if (saveState.value === 'error') saveState.value = 'idle'
    }, 2200)
  }
}
</script>

<template>
  <div class="page">
    <div class="header-row">
      <button type="button" class="back-btn" @click="router.back()">返回</button>
      <h1 class="page-title">词书设置</h1>
    </div>
    <p class="page-sub">选择词书并调整每日练习量与学习规则</p>

    <p v-if="loading" class="muted">加载中...</p>
    <template v-else>
      <section class="block">
        <h2 class="block-title">选择词书</h2>
        <p class="block-hint">一次仅学一本；小学按年级选择</p>

        <div class="select-wrap">
          <select
            v-model.number="selectedBookId"
            class="book-select"
            aria-label="选择词书"
          >
            <option v-if="!selectedBookId" :value="null" disabled>请选择词书</option>
            <optgroup v-for="group in groupedBooks" :key="group.key" :label="group.label">
              <option v-for="book in group.books" :key="book.id" :value="book.id">
                {{ book.title }}
              </option>
            </optgroup>
          </select>
        </div>

        <div v-if="selectedBook" class="book-summary">
          <span>{{ selectedBook.word_count }} 词</span>
          <span class="dot">·</span>
          <span>{{ selectedBook.unit_count }} 单元</span>
          <span class="dot">·</span>
          <span>默认 {{ selectedBook.daily_target }} 词/天</span>
        </div>
      </section>

      <section class="block">
        <h2 class="block-title">练习参数</h2>
        <div class="field">
          <label>每日练习量</label>
          <input v-model.number="dailyTarget" type="range" min="5" max="40" step="1" />
          <span class="field-value">{{ dailyTarget }} 词/天</span>
        </div>
        <div class="field">
          <label>连续答对几次算掌握</label>
          <input v-model.number="masterRequired" type="range" min="2" max="8" step="1" />
          <span class="field-value">{{ masterRequired }} 次</span>
        </div>
        <div class="field">
          <label>答错几次标记易错</label>
          <input v-model.number="weakThreshold" type="range" min="1" max="5" step="1" />
          <span class="field-value">{{ weakThreshold }} 次</span>
        </div>
      </section>

      <button
        type="button"
        class="btn save-btn"
        :class="{
          'btn-primary': saveState === 'idle' || saveState === 'saving',
          'save-success': saveState === 'success',
          'save-error': saveState === 'error',
        }"
        :disabled="!selectedBookId || saveState === 'saving' || saveState === 'success'"
        @click="save"
      >
        {{ saveLabel }}
      </button>
    </template>

    <Transition name="toast">
      <div
        v-if="toast"
        class="toast"
        :class="toast.type"
        role="status"
        aria-live="polite"
      >
        <span class="toast-icon">{{ toast.type === 'success' ? '✓' : '!' }}</span>
        <span class="toast-text">{{ toast.text }}</span>
      </div>
    </Transition>
  </div>
</template>

<style scoped>
.header-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 4px;
}
.back-btn {
  border: none;
  background: none;
  color: var(--primary, #4f6ef7);
  font-size: 14px;
  cursor: pointer;
  padding: 0;
}
.page-sub {
  font-size: 13px;
  color: var(--muted);
  margin: 0 0 16px;
}
.muted { color: var(--muted); }
.block {
  margin-bottom: 20px;
}
.block-title {
  font-size: 16px;
  margin: 0 0 6px;
}
.block-hint {
  font-size: 12px;
  color: var(--muted);
  margin: 0 0 12px;
}
.select-wrap {
  position: relative;
}
.book-select {
  width: 100%;
  appearance: none;
  padding: 14px 40px 14px 14px;
  font-size: 15px;
  border-radius: 12px;
  border: 1px solid var(--border, #e5e7eb);
  background: var(--card, #fff)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%236b7280' d='M1.41 0L6 4.58 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E")
    no-repeat right 14px center;
  color: var(--text, #111);
  cursor: pointer;
}
.book-select:focus {
  outline: none;
  border-color: #0d9488;
  box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.15);
}
.book-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin-top: 10px;
  font-size: 13px;
  color: var(--muted);
}
.book-summary .dot {
  opacity: 0.5;
}
.field {
  margin-bottom: 16px;
}
.field label {
  display: block;
  font-size: 14px;
  margin-bottom: 8px;
}
.field input[type='range'] {
  width: 100%;
}
.field-value {
  display: block;
  font-size: 13px;
  color: var(--muted);
  margin-top: 4px;
}
.save-btn {
  width: 100%;
  transition: background 0.25s ease, transform 0.15s ease;
}
.save-btn.save-success {
  background: #0d9488;
  color: #fff;
  border: none;
}
.save-btn.save-error {
  background: #fef2f2;
  color: #b91c1c;
  border: 1px solid #fecaca;
}
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(360px, calc(100vw - 32px));
  padding: 14px 18px;
  border-radius: 14px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.14);
  z-index: 200;
  font-size: 14px;
}
.toast.success {
  background: #0f766e;
  color: #fff;
}
.toast.error {
  background: #fff;
  color: #b91c1c;
  border: 1px solid #fecaca;
}
.toast-icon {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
}
.toast.success .toast-icon {
  background: rgba(255, 255, 255, 0.2);
}
.toast.error .toast-icon {
  background: #fee2e2;
}
.toast-text {
  line-height: 1.4;
}
.toast-enter-active,
.toast-leave-active {
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.toast-enter-from,
.toast-leave-to {
  opacity: 0;
  transform: translateX(-50%) translateY(12px);
}
</style>
