<script setup>
import { onMounted, ref, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { boardApi } from '@/api/boardApi'
import MarkdownEditor from '@/components/editor/MarkdownEditor.vue'
import IconBtn from '@/components/ui/IconBtn.vue'
import { DEFAULT_BOARD } from '@/constants/boards'

const route = useRoute()
const router = useRouter()

const category = route.params.category || DEFAULT_BOARD
const editId = route.params.id || null
const isEdit = computed(() => !!editId)

const title = ref('')
const content = ref('')
const tagGroups = ref([])
const selectedTagIds = ref([])
const loading = ref(false)
const error = ref(null)

// 카테고리 구분 없이 태그만 평탄화
const allTags = computed(() => tagGroups.value.flatMap((g) => g.tags))

function toggleTag(id) {
  const i = selectedTagIds.value.indexOf(id)
  if (i >= 0) selectedTagIds.value.splice(i, 1)
  else selectedTagIds.value.push(id)
}

async function loadTagGroups() {
  try {
    tagGroups.value = await boardApi.tagGroups()
  } catch {
    tagGroups.value = []
  }
}

async function loadForEdit() {
  loading.value = true
  try {
    const p = await boardApi.get(editId)
    title.value = p.title
    content.value = p.content
    // 게시글의 태그(이름) → 현재 태그 목록에서 id 매핑
    const nameToId = {}
    tagGroups.value.forEach((c) => c.tags.forEach((t) => (nameToId[t.name] = t.id)))
    selectedTagIds.value = (p.tags || []).map((n) => nameToId[n]).filter(Boolean)
  } catch (e) {
    error.value = e.response?.data?.message || '게시글을 불러오지 못했습니다.'
  } finally {
    loading.value = false
  }
}

async function submit() {
  error.value = null
  if (!title.value.trim() || !content.value.trim()) {
    error.value = '제목과 내용을 입력하세요.'
    return
  }
  loading.value = true
  const payload = {
    title: title.value.trim(),
    content: content.value,
    category,
    tagIds: selectedTagIds.value,
  }
  try {
    const saved = isEdit.value
      ? await boardApi.update(editId, payload)
      : await boardApi.create(payload)
    router.replace(`/board/${category}/${saved.id}`)
  } catch (e) {
    error.value = e.response?.data?.message || '저장에 실패했습니다.'
  } finally {
    loading.value = false
  }
}

function cancel() {
  if (isEdit.value) router.replace(`/board/${category}/${editId}`)
  else router.replace(`/board/${category}`)
}

onMounted(async () => {
  await loadTagGroups()
  if (isEdit.value) await loadForEdit()
})
</script>

<template>
  <section class="write">
    <h1>{{ isEdit ? '글 수정' : '글쓰기' }}</h1>

    <form class="write-form" @submit.prevent="submit">
      <input v-model="title" type="text" placeholder="제목" maxlength="200" :disabled="loading" />

      <!-- 태그 선택 (DB 등록 태그를 뱃지로 토글) -->
      <div class="tag-select">
        <div v-if="!allTags.length" class="hint">
          등록된 태그가 없습니다. (관리자가 [태그 관리]에서 추가할 수 있습니다)
        </div>
        <button
          v-for="t in allTags"
          :key="t.id"
          type="button"
          class="tag-badge"
          :class="{ active: selectedTagIds.includes(t.id) }"
          @click="toggleTag(t.id)"
        >{{ t.name }}</button>
      </div>

      <MarkdownEditor v-model="content" height="420px" placeholder="내용을 입력하세요" />

      <p v-if="error" class="msg error">{{ error }}</p>

      <div class="buttons">
        <IconBtn icon="close" title="취소" @click="cancel" />
        <IconBtn icon="save" :title="isEdit ? '수정' : '등록'" variant="primary" type="submit" :disabled="loading" />
      </div>
    </form>
  </section>
</template>

<style scoped>
.write {
  max-width: 800px;
  margin: 0 auto;
}
h1 {
  font-size: 1.5rem;
  margin-bottom: 1rem;
}
.write-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.write-form input[type='text'] {
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-background-soft);
  color: var(--color-text);
  font-family: inherit;
}
.tag-select {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  padding: 0.75rem;
  background: var(--color-background-soft);
}
.tag-badge {
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-background);
  color: var(--color-text);
  font-size: 0.85rem;
  cursor: pointer;
  transition: all 0.15s;
}
.tag-badge:hover {
  border-color: var(--color-border-hover);
}
.tag-badge.active {
  border-color: hsla(160, 100%, 37%, 1);
  background: hsla(160, 100%, 37%, 0.12);
  color: hsla(160, 100%, 37%, 1);
  font-weight: 600;
}
.hint {
  font-size: 0.85rem;
  opacity: 0.65;
}
.buttons {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}
button {
  padding: 0.5rem 1.2rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-background-soft);
  color: var(--color-text);
  cursor: pointer;
}
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
button.primary {
  border-color: hsla(160, 100%, 37%, 1);
  color: hsla(160, 100%, 37%, 1);
}
.msg.error {
  color: #c0392b;
}
</style>
