/**
 * Trello task adapter — tasks-board-engine.
 * Supports 2-way sync (pushUpdate implemented).
 *
 * Credentials shape: { apiKey: string, token: string }
 * Fetches all cards from boards the token has access to.
 */
import type { ExternalTask, AdapterCredentials, TaskAdapter } from './types'
import type { TaskObject } from '@zync/types'

interface TrelloCard {
  id: string
  name: string
  desc: string
  idList: string
  due: string | null
  idMembers: string[]
}

interface TrelloList {
  id: string
  name: string
}

interface TrelloBoard {
  id: string
  name: string
}

const BASE = 'https://api.trello.com/1'

async function trelloGet<T>(path: string, apiKey: string, token: string): Promise<T> {
  const url = new URL(`${BASE}${path}`)
  url.searchParams.set('key', apiKey)
  url.searchParams.set('token', token)
  const res = await fetch(url.toString())
  if (!res.ok) throw new Error(`Trello API error: ${res.status} ${path}`)
  return res.json() as Promise<T>
}

export const trelloAdapter: TaskAdapter = {
  id: 'trello',
  name: 'Trello',

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

    const boards = await trelloGet<TrelloBoard[]>('/members/me/boards', apiKey, token)
    const allTasks: ExternalTask[] = []

    for (const board of boards) {
      const [cards, lists] = await Promise.all([
        trelloGet<TrelloCard[]>(`/boards/${board.id}/cards`, apiKey, token),
        trelloGet<TrelloList[]>(`/boards/${board.id}/lists`, apiKey, token),
      ])

      const listMap = new Map(lists.map((l) => [l.id, l.name]))

      for (const card of cards) {
        allTasks.push({
          externalId: card.id,
          title: card.name,
          description: card.desc || undefined,
          status: listMap.get(card.idList),
          dueDate: card.due ? card.due.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: String(external.description) }] }] } : null,
      source: 'trello',
      external_id: external.externalId,
      due_date: external.dueDate ?? null,
      tenant_id: tenantId,
      project_id: projectId || null,
      priority: 'medium',
      labels: [],
    }
  },

  async pushUpdate(task: TaskObject, credentials: AdapterCredentials): Promise<void> {
    const apiKey = String(credentials['apiKey'] ?? '')
    const token = String(credentials['token'] ?? '')
    if (!task.external_id) return

    const url = new URL(`${BASE}/cards/${task.external_id}`)
    url.searchParams.set('key', apiKey)
    url.searchParams.set('token', token)
    url.searchParams.set('name', task.title)
    if (task.due_date) url.searchParams.set('due', task.due_date)

    const res = await fetch(url.toString(), { method: 'PUT' })
    if (!res.ok) throw new Error(`Trello pushUpdate failed: ${res.status}`)
  },
}
