<script setup>
import { onMounted, ref, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { boardApi } from '@/api/boardApi'
import { useAuthStore } from '@/stores/auth'
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 auth = useAuthStore()

const category = route.params.category || DEFAULT_BOARD
const editId = route.params.id || null
const isEdit = computed(() => !!editId)
// 공지: 관리자가 커뮤니티 게시판 글을 작성/수정할 때 체크박스로 설정
const isAdmin = computed(() => auth.user?.role === 'ADMIN')
const canNotice = computed(() => isAdmin.value && category === 'community')

const title = ref('')
const content = ref('')
const notice = ref(false)
const tagGroups = ref([])
const selectedTagIds = ref([])
// 이 게시판 매핑엔 없지만 글이 이미 가진 태그(수정 시 보존용)
const extraTags = ref([])
const loading = ref(false)
const error = ref(null)

// 이 게시판 그룹의 태그 + 글이 이미 가진 추가 태그(중복 제거)
const allTags = computed(() => tagGroups.value.flatMap((g) => g.tags))
const displayTags = computed(() => {
  const seen = new Set(allTags.value.map((t) => t.id))
  return [...allTags.value, ...extraTags.value.filter((t) => !seen.has(t.id))]
})

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(category)
  } catch {
    tagGroups.value = []
  }
}

async function loadForEdit() {
  loading.value = true
  try {
    const p = await boardApi.get(editId)
    title.value = p.title
    content.value = p.content
    notice.value = !!p.notice
    // 전체 그룹에서 이름→id 해석 (이 게시판에 안 보이는 기존 태그도 보존)
    const all = await boardApi.tagGroups('')
    const nameToId = {}
    const idToName = {}
    all.forEach((c) => c.tags.forEach((t) => { nameToId[t.name] = t.id; idToName[t.id] = t.name }))
    selectedTagIds.value = (p.tags || []).map((n) => nameToId[n]).filter(Boolean)
    // 이 게시판 그룹에 없는 선택 태그만 별도 배지로 노출(보존)
    const shown = new Set(allTags.value.map((t) => t.id))
    extraTags.value = selectedTagIds.value
      .filter((id) => !shown.has(id))
      .map((id) => ({ id, name: idToName[id] }))
  } 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,
    notice: canNotice.value ? notice.value : false,
    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">

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

      <!-- 공지 등록 (관리자, 커뮤니티 새 글) -->
      <label v-if="canNotice" class="notice-check">
        <input v-model="notice" type="checkbox" :disabled="loading" />
        📌 공지로 등록 (목록 최상단 고정)
      </label>

      <!-- 태그 선택 (DB 등록 태그를 뱃지로 토글) -->
      <div class="tag-select">
        <div v-if="!displayTags.length" class="hint">
          이 게시판에 사용할 태그가 없습니다. (관리자가 [태그 관리]에서 게시판에 매핑할 수 있습니다)
        </div>
        <button
          v-for="t in displayTags"
          :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;
}
.notice-check {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9rem;
  cursor: pointer;
}
.notice-check input {
  width: auto;
  cursor: pointer;
}
.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>
