import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { projectService, type ProjectMember } from '@/services/project'

interface CachedProjectMembers {
  data: ProjectMember[]
  lastFetched: number
}

export const useProjectMembersStore = defineStore('projectMembers', () => {
  const membersByProject = ref<Map<number, CachedProjectMembers>>(new Map())
  const loading = ref<Set<number>>(new Set())

  // In-flight request de-dup: concurrent callers for the same project share one promise
  const inFlightRequests = new Map<number, Promise<ProjectMember[]>>()

  const CACHE_DURATION = 5 * 60 * 1000

  const getMembers = computed(() => {
    return (projectId: number): ProjectMember[] | null => {
      const cached = membersByProject.value.get(projectId)
      if (!cached) return null

      const now = Date.now()
      if (now - cached.lastFetched > CACHE_DURATION) {
        membersByProject.value.delete(projectId)
        return null
      }

      return cached.data
    }
  })

  const isLoading = computed(() => {
    return (projectId: number): boolean => {
      return loading.value.has(projectId)
    }
  })

  async function fetchProjectMembers(projectId: number, force = false): Promise<ProjectMember[]> {
    if (!force) {
      const cached = getMembers.value(projectId)
      if (cached) {
        return cached
      }
    }

    const existing = inFlightRequests.get(projectId)
    if (existing) {
      return existing
    }

    loading.value.add(projectId)

    const request = (async () => {
      try {
        const data = await projectService.getProjectMembers(projectId)
        membersByProject.value.set(projectId, { data, lastFetched: Date.now() })
        return data
      } finally {
        loading.value.delete(projectId)
        inFlightRequests.delete(projectId)
      }
    })()

    inFlightRequests.set(projectId, request)
    return request
  }

  function invalidateProject(projectId: number) {
    membersByProject.value.delete(projectId)
  }

  return {
    getMembers,
    isLoading,
    fetchProjectMembers,
    invalidateProject
  }
})
