import { computed, ref } from 'vue'
import { defineStore } from 'pinia'
import { useProject } from '@/composables/useProject'
import { DEFAULT_PAGE_SIZE } from '@/types/pagination'
import { progressOf, relativeTimeKo } from '@/shared/utils/format'
import type { ApiMember } from '@/types/repo'
import type {
  ApiProject,
  CreateProjectPayload,
  ProjectListQuery,
  UpdateProjectPayload,
} from '@/types/project'
import type { Project as ProjectView, User as UserView } from '@/mock/relay.mock'

// 아바타 스택에 노출할 멤버 수(초과분은 +N 으로 표기)
const AVATAR_LIMIT = 3

function toUserView(member: ApiMember): UserView {
  return {
    id: member.id,
    name: member.name,
    role: member.role ?? '',
    avatarUrl: member.avatarUrl,
  }
}

// API 프로젝트 → 화면용 Project(진행률/상대시간/아바타 파생)
function toProjectView(api: ApiProject): ProjectView {
  const prog = progressOf(api.doneCount, api.totalCount)
  const shown = api.members.slice(0, AVATAR_LIMIT).map(toUserView)
  return {
    id: api.id,
    name: api.name,
    desc: api.description ?? '',
    members: shown,
    moreCount: Math.max(0, api.memberCount - shown.length),
    updatedAgo: `${relativeTimeKo(api.updatedAt)} 업데이트`,
    doneCount: api.doneCount,
    totalCount: api.totalCount,
    progressPct: prog.pct,
    progressLevel: prog.level,
    progressLabel: prog.label,
    canManage: api.canManage,
    isOwner: api.isOwner,
  }
}

// 프로젝트 스토어 — 목록/현재 프로젝트 상태 + CRUD 액션
export const useProjectStore = defineStore('project', () => {
  const projects = ref<ProjectView[]>([])
  const current = ref<ProjectView | null>(null)
  const loading = ref(false)
  const total = ref(0)
  const page = ref(0)
  const loadingMore = ref(false)
  const hasMore = computed(() => projects.value.length < total.value)

  const projectApi = useProject()

  // 검색/정렬 조건을 보관 — 더보기에서 같은 조건으로 다음 페이지를 잇기 위함
  const query = ref<ProjectListQuery>({})

  async function fetchList(q: ProjectListQuery = {}): Promise<void> {
    query.value = q
    loading.value = true
    try {
      const res = await projectApi.list(1, DEFAULT_PAGE_SIZE, query.value)
      projects.value = res.items.map(toProjectView)
      total.value = res.total
      page.value = 1
    } finally {
      loading.value = false
    }
  }

  async function loadMore(): Promise<void> {
    if (loadingMore.value || !hasMore.value) return
    loadingMore.value = true
    try {
      const res = await projectApi.list(page.value + 1, DEFAULT_PAGE_SIZE, query.value)
      projects.value.push(...res.items.map(toProjectView))
      total.value = res.total
      page.value += 1
    } finally {
      loadingMore.value = false
    }
  }

  async function fetchOne(id: string): Promise<ProjectView | null> {
    loading.value = true
    try {
      current.value = toProjectView(await projectApi.get(id))
      return current.value
    } finally {
      loading.value = false
    }
  }

  async function create(payload: CreateProjectPayload): Promise<ProjectView> {
    return toProjectView(await projectApi.create(payload))
  }

  async function update(
    id: string,
    payload: UpdateProjectPayload,
  ): Promise<ProjectView> {
    const view = toProjectView(await projectApi.update(id, payload))
    current.value = view
    return view
  }

  async function remove(id: string): Promise<void> {
    await projectApi.remove(id)
    projects.value = projects.value.filter((p) => p.id !== id)
    total.value = Math.max(0, total.value - 1)
    if (current.value?.id === id) current.value = null
  }

  return {
    projects,
    current,
    loading,
    total,
    hasMore,
    loadingMore,
    fetchList,
    loadMore,
    fetchOne,
    create,
    update,
    remove,
  }
})
