// Мини-клиент API. Ошибки авторизации редиректят на вход.

export interface Tag {
  id: number
  name: string
}

export interface Project {
  id: number
  name: string
  relevance_status: string
  priority: number | null
  note: string
}

export interface Task {
  id: number
  title: string
  description: string
  task_type: string
  status: string
  detail_state: string
  parent_task_id: number | null
  project: Project | null
  priority: number | null
  tags: Tag[]
  created_at: string
  approved_at: string | null
  done_at: string | null
}

export interface TaskUpdateInput {
  title?: string
  description?: string
  project_id?: number | null
  tag_ids?: number[]
  priority?: number | null
  status?: string
}

export class ApiError extends Error {
  status: number
  constructor(status: number, message: string) {
    super(message)
    this.status = status
  }
}

async function request<T>(path: string, options: RequestInit = {}): Promise<T> {
  const res = await fetch(path, {
    headers: { 'Content-Type': 'application/json' },
    ...options,
  })
  if (res.status === 401) {
    window.location.href = '/auth/login'
    throw new ApiError(401, 'Not authenticated')
  }
  if (!res.ok) {
    const body = await res.json().catch(() => ({ detail: res.statusText }))
    throw new ApiError(res.status, body.detail ?? 'Ошибка запроса')
  }
  return res.json() as Promise<T>
}

export const api = {
  // tasks
  listTasks: (params: Record<string, string | number> = {}) =>
    request<Task[]>('/api/tasks?' + new URLSearchParams(
      Object.entries(params).map(([k, v]) => [k, String(v)]),
    )),
  getTask: (id: number) => request<Task>(`/api/tasks/${id}`),
  createTask: (title: string, description = '') =>
    request<{ id: number }>('/api/tasks', {
      method: 'POST',
      body: JSON.stringify({ title, description }),
    }),
  updateTask: (id: number, patch: TaskUpdateInput) =>
    request<Task>(`/api/tasks/${id}`, { method: 'PATCH', body: JSON.stringify(patch) }),
  approveTask: (id: number) => request<Task>(`/api/tasks/${id}/approve`, { method: 'POST' }),
  deleteTask: (id: number) => request<{ ok: boolean }>(`/api/tasks/${id}`, { method: 'DELETE' }),
  // projects
  listProjects: () => request<Project[]>('/api/projects'),
  createProject: (name: string) =>
    request<Project>('/api/projects', { method: 'POST', body: JSON.stringify({ name }) }),
  // tags
  listTags: () => request<Tag[]>('/api/tags'),
  createTag: (name: string) =>
    request<Tag>('/api/tags', { method: 'POST', body: JSON.stringify({ name }) }),
}