<script setup lang="ts">
// 프로젝트 목록 — 검색/정렬은 서버에서 처리(페이지네이션과 일관)
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { RouterLink } from 'vue-router'
import AppShell from '@/layouts/AppShell.vue'
import UserAvatar from '@/components/UserAvatar.vue'
import DropdownSelect from '@/components/DropdownSelect.vue'
import { useProjectStore } from '@/stores/project.store'
import type { ProjectListQuery, ProjectSort } from '@/types/project'

const keyword = ref('')
const sort = ref<ProjectSort>('recent')
const SORT_OPTIONS: { value: ProjectSort; label: string }[] = [
  { value: 'recent', label: '최근 업데이트순' },
  { value: 'name', label: '이름순' },
  { value: 'created', label: '최근 생성순' },
]

const projectStore = useProjectStore()
const { projects, loading, total, hasMore, loadingMore } = storeToRefs(projectStore)

// 현재 검색/정렬 조건 → 목록 쿼리(서버에서 필터·정렬)
function currentQuery(): ProjectListQuery {
  const q = keyword.value.trim()
  return { sort: sort.value, ...(q ? { q } : {}) }
}
function loadList() {
  void projectStore.fetchList(currentQuery())
}

onMounted(loadList)

// 정렬 변경 시 즉시 재조회
watch(sort, loadList)

// 검색어는 디바운스 후 재조회(연속 입력 시 호출 폭주 방지)
let searchTimer: ReturnType<typeof setTimeout> | null = null
watch(keyword, () => {
  if (searchTimer) clearTimeout(searchTimer)
  searchTimer = setTimeout(loadList, 250)
})
onBeforeUnmount(() => {
  if (searchTimer) clearTimeout(searchTimer)
})

// 검색어가 있으면 '검색 결과 없음', 없으면 '프로젝트 없음' 문구 분기
const isFiltered = computed(() => keyword.value.trim() !== '')
</script>

<template>
  <AppShell>
    <div class="page">
      <div class="crumb">
        <b>프로젝트</b>
      </div>

      <div class="pagehead">
        <h1>프로젝트</h1>
        <span class="count-pill">{{ total }}</span>
      </div>
      <p class="lede">
        프로젝트를 열어 업무를 작성하고 담당자에게 전달하세요.
      </p>

      <!-- 툴바 -->
      <div class="toolbar">
        <div class="search">
          <svg
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
          >
            <circle
              cx="11"
              cy="11"
              r="7"
            />
            <path d="m21 21-4-4" />
          </svg>
          <input
            v-model="keyword"
            type="text"
            placeholder="프로젝트 검색…"
          >
        </div>
        <DropdownSelect
          v-model="sort"
          :options="SORT_OPTIONS"
          push-right
          align="right"
          aria-label="정렬"
        >
          <template #icon>
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <path d="M11 5h10M11 9h7M11 13h4M3 17l3 3 3-3M6 18V4" />
            </svg>
          </template>
        </DropdownSelect>
        <RouterLink
          class="btn primary"
          to="/projects/new"
        >
          <svg
            width="15"
            height="15"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2.2"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <path d="M5 12h14M12 5v14" />
          </svg>
          새 프로젝트
        </RouterLink>
      </div>

      <!-- 목록 -->
      <div class="list">
        <RouterLink
          v-for="repo in projects"
          :key="repo.id"
          class="repo-row"
          :to="`/projects/${repo.id}`"
        >
          <div class="repo-ico">
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" />
              <path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" />
            </svg>
          </div>

          <div class="repo-main">
            <div class="repo-title">
              <span class="repo-name">{{ repo.name }}</span>
            </div>
            <div
              v-if="repo.desc"
              class="repo-desc"
            >
              {{ repo.desc }}
            </div>
            <div class="repo-meta">
              <span class="mi avstack">
                <span
                  v-for="m in repo.members"
                  :key="m.id"
                  class="avatar"
                ><UserAvatar
                  :url="m.avatarUrl"
                  :name="m.name"
                /></span>
                <span
                  v-if="repo.moreCount > 0"
                  class="avatar av-more"
                >+{{ repo.moreCount }}</span>
              </span>
              <span class="mi">{{ repo.updatedAgo }}</span>
            </div>
          </div>

          <div class="repo-stat">
            <div class="stat-top">
              <b>{{ repo.doneCount }}</b> / {{ repo.totalCount }} 업무
            </div>
            <div class="pbar">
              <i
                :class="repo.progressLevel === 'mid' ? 'mid' : repo.progressLevel === 'low' ? 'low' : ''"
                :style="{ width: repo.progressPct + '%' }"
              />
            </div>
          </div>

          <span class="chev">
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <path d="m9 18 6-6-6-6" />
            </svg>
          </span>
        </RouterLink>

        <!-- 로딩 / 빈 상태 -->
        <div
          v-if="loading && projects.length === 0"
          class="list-empty"
        >
          불러오는 중…
        </div>
        <div
          v-else-if="projects.length === 0"
          class="list-empty"
        >
          {{ isFiltered ? '검색 결과가 없습니다.' : '아직 프로젝트가 없습니다. 새 프로젝트를 만들어 보세요.' }}
        </div>
      </div>

      <!-- 더보기 -->
      <button
        v-if="hasMore"
        class="load-more"
        type="button"
        :disabled="loadingMore"
        @click="projectStore.loadMore()"
      >
        {{ loadingMore ? '불러오는 중…' : '더보기' }}
      </button>
    </div>
  </AppShell>
</template>

<style scoped>
.pagehead {
  display: flex;
  align-items: center;
  gap: 0.6875rem;
  padding: 0.5625rem 0 0.25rem;
}
.pagehead h1 {
  font-size: 1.375rem;
  font-weight: 700;
  letter-spacing: -0.025rem;
  white-space: nowrap;
}
.lede {
  color: var(--text-2);
  font-size: 0.844rem;
  margin: 0.25rem 0 1.125rem;
}
.lede b {
  color: var(--text-2);
}

/* 프로젝트 행 */
.repo-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-top: 1px solid var(--border);
  cursor: pointer;
  text-decoration: none;
  color: inherit;
}
.repo-row:first-child {
  border-top: none;
}
.repo-row:hover {
  background: #fafbfc;
}
.repo-ico {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.5625rem;
  background: var(--accent-weak);
  color: var(--accent);
  display: grid;
  place-items: center;
  flex-shrink: 0;
  align-self: flex-start;
  margin-top: 0.125rem;
}
.repo-ico svg {
  width: 1.3125rem;
  height: 1.3125rem;
}
.repo-main {
  flex: 1;
  min-width: 0;
}
.repo-title {
  display: flex;
  align-items: center;
  column-gap: 0.5625rem;
  row-gap: 0.125rem;
  flex-wrap: wrap;
}
.repo-name {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
.repo-slug {
  order: 2;
  flex-basis: 100%;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-3);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.repo-row:hover .repo-name {
  color: var(--accent);
}
.repo-desc {
  font-size: 0.8125rem;
  color: var(--text-2);
  margin-top: 0.25rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 30rem;
}
.repo-meta {
  display: flex;
  align-items: center;
  gap: 0.9375rem;
  margin-top: 0.625rem;
  font-size: 0.75rem;
  color: var(--text-3);
}
.repo-meta .mi {
  display: flex;
  align-items: center;
  gap: 0.3125rem;
  white-space: nowrap;
}
.repo-meta .mi svg {
  width: 0.8125rem;
  height: 0.8125rem;
}
.repo-stat {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.375rem;
  width: 10.5rem;
  flex-shrink: 0;
}
.stat-top {
  font-size: 0.781rem;
  color: var(--text-2);
  font-weight: 600;
  white-space: nowrap;
}
.stat-top b {
  color: var(--text);
}
.repo-stat .pbar {
  width: 9.75rem;
}
.chev {
  color: var(--text-3);
  flex-shrink: 0;
  display: grid;
  place-items: center;
}
.chev svg {
  width: 1.125rem;
  height: 1.125rem;
}
.list-empty {
  padding: 2.5rem 1.25rem;
  text-align: center;
  color: var(--text-3);
  font-size: 0.844rem;
}
</style>
