<script setup>
import AdminNavPrimaryBranch from './AdminNavPrimaryBranch.vue'

const props = defineProps({
  /** buildNavigationEditorTree 결과 */
  wraps: {
    type: Array,
    required: true
  },
  /** 들여쓰기 단계 */
  depth: {
    type: Number,
    default: 0
  },
  /** 루트면 `'root'`, 아니면 부모 항목 id */
  parentKey: {
    type: String,
    default: 'root'
  },
  /** 드래그 중인 항목 id */
  draggingId: {
    type: String,
    default: ''
  },
  /** 드롭 대상 위에 올린 항목 id */
  dragOverId: {
    type: String,
    default: ''
  }
})

const emit = defineEmits([
  'drag-start',
  'drag-over',
  'drag-end',
  'drop',
  'add-child',
  'remove'
])

/**
 * 입력·버튼 위에서는 행 드래그를 시작하지 않는다.
 * @param {DragEvent} event - 이벤트
 * @returns {boolean} true면 드래그를 막는다
 */
const shouldBlockRowDrag = (event) => {
  const el = event.target
  if (!el || typeof el.closest !== 'function') {
    return false
  }
  return Boolean(el.closest('input, button, textarea, select, a'))
}

/**
 * 드래그 시작
 * @param {DragEvent} event - 이벤트
 * @param {string} itemId - 항목 id
 * @returns {void}
 */
const onDragStart = (event, itemId) => {
  if (shouldBlockRowDrag(event)) {
    event.preventDefault()
    return
  }
  if (!event.dataTransfer) {
    return
  }
  emit('drag-start', { parentKey: props.parentKey, itemId })
  event.dataTransfer.effectAllowed = 'move'
}

/**
 * 드래그 오버
 * @param {DragEvent} event - 이벤트
 * @param {string} itemId - 항목 id
 * @returns {void}
 */
const onDragOver = (event, itemId) => {
  event.preventDefault()
  emit('drag-over', itemId)
}

/**
 * 드롭
 * @param {DragEvent} event - 이벤트
 * @param {string} itemId - 대상 id
 * @returns {void}
 */
const onDrop = (event, itemId) => {
  event.preventDefault()
  emit('drop', { parentKey: props.parentKey, targetId: itemId })
}

/**
 * 드래그 종료
 * @returns {void}
 */
const onDragEnd = () => {
  emit('drag-end')
}

/**
 * 행 하이라이트 클래스(태그 관리 메인 태그 테이블과 동일 톤)
 * @param {string} itemId - 항목 id
 * @returns {string}
 */
const rowStateClass = (itemId) => {
  const id = String(itemId)
  if (props.dragOverId === id) {
    return 'bg-[#f9f9f7]'
  }
  if (props.draggingId === id) {
    return 'opacity-50'
  }
  return ''
}
</script>

<template>
  <div class="admin-nav-primary-branch" :class="depth ? 'mt-2 border-l border-line pl-3' : ''">
    <div class="admin-nav-primary-branch__shell overflow-hidden rounded border border-line">
      <table class="admin-nav-primary-branch__table w-full border-collapse text-left text-sm">
        <thead v-if="depth === 0" class="admin-nav-primary-branch__head bg-[#f5f5f2] text-xs uppercase text-muted">
          <tr>
            <th class="admin-nav-primary-branch__cell px-4 py-3">
              #
            </th>
            <th class="admin-nav-primary-branch__cell px-4 py-3">
              라벨
            </th>
            <th class="admin-nav-primary-branch__cell px-4 py-3">
              URL
            </th>
            <th class="admin-nav-primary-branch__cell px-4 py-3">
              관리
            </th>
          </tr>
        </thead>
        <tbody class="admin-nav-primary-branch__body divide-y divide-line bg-white">
          <template v-for="(wrap, index) in wraps" :key="wrap.item.id">
            <tr
              class="admin-nav-primary-branch__row cursor-move"
              :class="rowStateClass(wrap.item.id)"
              draggable="true"
              @dragstart="onDragStart($event, wrap.item.id)"
              @dragover="onDragOver($event, wrap.item.id)"
              @drop="onDrop($event, wrap.item.id)"
              @dragend="onDragEnd"
            >
              <td class="admin-nav-primary-branch__cell px-4 py-3 align-middle text-muted">
                {{ index + 1 }}
              </td>
              <td class="admin-nav-primary-branch__cell px-4 py-3 align-middle">
                <input
                  v-model="wrap.item.label"
                  class="admin-nav-primary-branch__label w-full min-w-[8rem] rounded border border-line px-3 py-2 text-sm outline-none focus:border-[#8e9cac]"
                  type="text"
                  placeholder="라벨"
                  required
                >
              </td>
              <td class="admin-nav-primary-branch__cell px-4 py-3 align-middle">
                <input
                  v-model="wrap.item.url"
                  class="admin-nav-primary-branch__url w-full min-w-[10rem] rounded border border-line px-3 py-2 font-mono text-sm outline-none focus:border-[#8e9cac]"
                  type="text"
                  placeholder="URL (# 또는 /경로)"
                  required
                >
              </td>
              <td class="admin-nav-primary-branch__cell px-4 py-3 align-middle">
                <div class="admin-nav-primary-branch__actions flex flex-wrap gap-2">
                  <button
                    class="admin-nav-primary-branch__add-child rounded border border-line px-3 py-1.5 text-xs font-semibold"
                    type="button"
                    @click="emit('add-child', wrap.item.id)"
                  >
                    하위
                  </button>
                  <button
                    class="admin-nav-primary-branch__remove rounded border border-red-200 px-3 py-1.5 text-xs font-semibold text-red-700"
                    type="button"
                    @click="emit('remove', wrap.item.id)"
                  >
                    삭제
                  </button>
                </div>
              </td>
            </tr>
            <tr v-if="wrap.children.length" class="admin-nav-primary-branch__nest bg-white">
              <td class="p-0" colspan="4">
                <div class="admin-nav-primary-branch__nest-inner border-t border-line bg-[#fafaf8] px-2 py-3">
                  <AdminNavPrimaryBranch
                    :wraps="wrap.children"
                    :depth="depth + 1"
                    :parent-key="String(wrap.item.id)"
                    :dragging-id="draggingId"
                    :drag-over-id="dragOverId"
                    @drag-start="emit('drag-start', $event)"
                    @drag-over="emit('drag-over', $event)"
                    @drag-end="emit('drag-end')"
                    @drop="emit('drop', $event)"
                    @add-child="emit('add-child', $event)"
                    @remove="emit('remove', $event)"
                  />
                </div>
              </td>
            </tr>
          </template>
        </tbody>
      </table>
    </div>
  </div>
</template>
