/**
 * Asana task adapter — tasks-board-engine. 1-way sync (read only).
 *
 * Credentials shape: { personalAccessToken: string }
 * Fetches tasks from all workspaces accessible to the token.
 */
import type { ExternalTask, AdapterCredentials, TaskAdapter } from './types'
import type { TaskObject } from '@zync/types'

interface AsanaTask {
  gid: string
  name: string
  notes: string
  due_on: string | null
  assignee: { email: string } | null
  memberships: Array<{ section?: { name: string } }>
}

interface AsanaWorkspace {
  gid: string
}

const BASE = 'https://app.asana.com/api/1.0'

async function asanaGet<T>(
  path: string,
  token: string,
  params?: Record<string, string>,
): Promise<T> {
  const url = new URL(`${BASE}${path}`)
  if (params) {
    for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v)
  }
  const res = await fetch(url.toString(), {
    headers: { Authorization: `Bearer ${token}` },
  })
  if (!res.ok) throw new Error(`Asana API error: ${res.status} ${path}`)
  const json = await res.json() as { data: T }
  return json.data
}

export const asanaAdapter: TaskAdapter = {
  id: 'asana',
  name: 'Asana',

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

    const workspaces = await asanaGet<AsanaWorkspace[]>('/workspaces', token)
    const allTasks: ExternalTask[] = []

    for (const ws of workspaces) {
      const tasks = await asanaGet<AsanaTask[]>(`/workspaces/${ws.gid}/tasks`, token, {
        assignee: 'me',
        opt_fields: 'gid,name,notes,due_on,assignee.email,memberships.section.name',
        limit: '100',
      })

      for (const t of tasks) {
        allTasks.push({
          externalId: t.gid,
          title: t.name,
          description: t.notes || undefined,
          status: t.memberships[0]?.section?.name,
          assigneeEmail: t.assignee?.email,
          dueDate: t.due_on ?? 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: String(external.description) }] }] } : null,
      source: 'asana',
      external_id: external.externalId,
      due_date: external.dueDate ?? null,
      tenant_id: tenantId,
      project_id: projectId || null,
      priority: 'medium',
      labels: [],
    }
  },
}
