/**
 * ClickUp task adapter — tasks-board-engine. 1-way sync.
 *
 * Credentials shape: { apiToken: string }
 * Fetches tasks from all spaces/lists accessible to the token.
 */
import type { ExternalTask, AdapterCredentials, TaskAdapter } from './types'
import type { TaskObject } from '@zync/types'

interface ClickUpTask {
  id: string
  name: string
  description?: string
  status: { status: string }
  due_date?: string | null
  assignees?: Array<{ email: string }>
  priority?: { priority: string } | null
}

interface ClickUpTeam {
  id: string
}

const BASE = 'https://api.clickup.com/api/v2'

async function clickupGet<T>(path: string, token: string): Promise<T> {
  const res = await fetch(`${BASE}${path}`, {
    headers: { Authorization: token },
  })
  if (!res.ok) throw new Error(`ClickUp API error: ${res.status} ${path}`)
  return res.json() as Promise<T>
}

const PRIORITY_MAP: Record<string, 'low' | 'medium' | 'high' | 'urgent'> = {
  urgent: 'urgent',
  high: 'high',
  normal: 'medium',
  low: 'low',
}

export const clickupAdapter: TaskAdapter = {
  id: 'clickup',
  name: 'ClickUp',

  async fetchTasks(credentials: AdapterCredentials): Promise<ExternalTask[]> {
    const token = String(credentials['apiToken'] ?? '')
    if (!token) throw new Error('ClickUp: missing apiToken')

    const teams = await clickupGet<{ teams: ClickUpTeam[] }>('/team', token)
    const allTasks: ExternalTask[] = []

    for (const team of teams.teams) {
      // Get tasks assigned to the user from the team (simplified: use team tasks endpoint)
      const tasksRes = await clickupGet<{ tasks: ClickUpTask[] }>(
        `/team/${team.id}/task?assignee=me&include_closed=false&page=0`,
        token,
      )

      for (const t of tasksRes.tasks) {
        allTasks.push({
          externalId: t.id,
          title: t.name,
          description: t.description || undefined,
          status: t.status.status,
          assigneeEmail: t.assignees?.[0]?.email,
          dueDate: t.due_date
            ? new Date(Number(t.due_date)).toISOString().slice(0, 10)
            : undefined,
        })
      }
    }

    return allTasks
  },

  mapToTask(external: ExternalTask, tenantId: string, projectId: string): Partial<TaskObject> {
    return {
      title: external.title,
      description: external.description
        ? { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: external.description }] }] }
        : null,
      source: 'clickup',
      external_id: external.externalId,
      due_date: external.dueDate ?? null,
      tenant_id: tenantId,
      project_id: projectId || null,
      priority: 'medium',
      labels: [],
    }
  },
}
