/**
 * Monday.com task adapter — tasks-board-engine. 1-way sync.
 *
 * Credentials shape: { apiToken: string }
 * Uses the Monday.com GraphQL API to fetch items from all boards.
 */
import type { ExternalTask, AdapterCredentials, TaskAdapter } from './types'
import type { TaskObject } from '@zync/types'

interface MondayItem {
  id: string
  name: string
  column_values: Array<{ id: string; title: string; text: string }>
}

interface MondayBoard {
  id: string
  items_page: { items: MondayItem[] }
}

const GQL_ENDPOINT = 'https://api.monday.com/v2'

const BOARDS_QUERY = `
  query {
    boards(limit: 20) {
      id
      items_page(limit: 100) {
        items {
          id
          name
          column_values {
            id
            title
            text
          }
        }
      }
    }
  }
`

async function mondayGql<T>(query: string, token: string): Promise<T> {
  const res = await fetch(GQL_ENDPOINT, {
    method: 'POST',
    headers: {
      Authorization: token,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ query }),
  })
  if (!res.ok) throw new Error(`Monday API error: ${res.status}`)
  const json = await res.json() as { data: T }
  return json.data
}

export const mondayAdapter: TaskAdapter = {
  id: 'monday',
  name: 'Monday.com',

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

    const data = await mondayGql<{ boards: MondayBoard[] }>(BOARDS_QUERY, token)
    const allTasks: ExternalTask[] = []

    for (const board of data.boards) {
      for (const item of board.items_page.items) {
        const statusCol = item.column_values.find((c) => c.id === 'status' || c.title.toLowerCase() === 'status')
        const dateCol = item.column_values.find((c) => c.id === 'date' || c.title.toLowerCase().includes('due'))

        allTasks.push({
          externalId: item.id,
          title: item.name,
          status: statusCol?.text,
          dueDate: dateCol?.text || undefined,
        })
      }
    }

    return allTasks
  },

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