import { defineStore } from 'pinia'
import { ref } from 'vue'
import { useFetch } from '@/composables/useFetch.ts'
import type { Project } from '@/stores/projects.ts'
import { type Status } from '@/stores/statuses.ts'

export interface Issue {
  id: number
  name: string
  description: string
  created: string
  position: number
  status_id: number
  status: Status
  project_id: number
  project: Project
}

export type CreateIssueDto = Partial<Pick<Issue, 'name' | 'description' | 'status_id' | 'project_id' | 'position'>>

export interface PositionsDto {
  status_id: number
  positions: number[]
}

export const useIssuesStore = defineStore('issues', () => {
  const issues = ref<Issue[]>([])
  const issuesObj = ref<Map<number, Issue[]>>(new Map())
  const { GET, POST, DELETE } = useFetch('/api/issues')

  async function findAll() {
    const response = await GET<Issue[]>()
    if (response) issues.value = response.data
  }

  function genIssuesObj(statuses: Status[]) {
    const map = new Map<number, Issue[]>()
    statuses.forEach((s) => map.set(s.id, filterIssue(s.id)))
    issuesObj.value = map
  }

  function filterIssue(status_id: number) {
    return issues.value.filter((i) => i.status_id === status_id).sort((a, b) => a.position - b.position)
  }

  async function create(body: CreateIssueDto) {
    if (!body.name || !body.project_id || !body.status_id) return false
    const arr = issuesObj.value.get(body.status_id)
    if (arr) {
      const el = arr[arr.length - 1]
      if (el) body.position = el?.position + 1
    }

    const response = await POST<Issue>({ body })
    if (response?.data) issues.value.push(response.data)
    return true
  }

  async function updatePositions(body: PositionsDto) {
    await POST({ param: 'positions', body: { status_id: body.status_id, positions: body.positions } })
    await findAll()
  }

  async function remove(id: number) {
    const response = await DELETE<{ res: number }>({ param: id })
    if (response?.data) {
      const index = issues.value.findIndex((el) => el.id === id)
      issues.value.splice(index, 1)
    }
  }

  return { issues, issuesObj, findAll, create, genIssuesObj, updatePositions, remove }
})
