/**
 * Slack task adapter — tasks-board-engine. 1-way sync (no pushUpdate).
 *
 * Credentials shape: { botToken: string }
 * Fetches starred/bookmarked items or messages from a dedicated task channel.
 * In practice, Slack is primarily used as an inbound source via the
 * comms.inbound queue — this adapter provides the batch-fetch path.
 *
 * Note: Slack does not have a native "tasks" concept; we read messages from
 * a configured channel (#tasks or similar) and treat them as external tasks.
 */
import type { ExternalTask, AdapterCredentials, TaskAdapter } from './types'
import type { TaskObject } from '@zync/types'

interface SlackMessage {
  client_msg_id?: string
  ts: string
  text: string
  user?: string
}

interface SlackConversationsHistoryResponse {
  ok: boolean
  messages: SlackMessage[]
}

const BASE = 'https://slack.com/api'

async function slackPost<T>(
  method: string,
  token: string,
  body: Record<string, string>,
): Promise<T> {
  const res = await fetch(`${BASE}/${method}`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams(body).toString(),
  })
  if (!res.ok) throw new Error(`Slack API error: ${res.status} ${method}`)
  const json = await res.json() as T & { ok: boolean; error?: string }
  if (!(json as { ok: boolean }).ok)
    throw new Error(`Slack API error: ${(json as { error?: string }).error ?? 'unknown'}`)
  return json
}

export const slackAdapter: TaskAdapter = {
  id: 'slack',
  name: 'Slack',

  async fetchTasks(credentials: AdapterCredentials): Promise<ExternalTask[]> {
    const token = String(credentials['botToken'] ?? '')
    const channelId = String(credentials['channelId'] ?? '')
    if (!token) throw new Error('Slack: missing botToken')
    if (!channelId) return [] // No channel configured → no tasks to fetch

    const res = await slackPost<SlackConversationsHistoryResponse>(
      'conversations.history',
      token,
      { channel: channelId, limit: '100' },
    )

    return res.messages.map((msg) => ({
      externalId: msg.client_msg_id ?? `${channelId}:${msg.ts}`,
      title: msg.text.slice(0, 500),
    }))
  },

  mapToTask(external: ExternalTask, tenantId: string, projectId: string): Partial<TaskObject> {
    return {
      title: external.title,
      source: 'slack',
      external_id: external.externalId,
      tenant_id: tenantId,
      project_id: projectId || null,
      priority: 'medium',
      labels: [],
    }
  },
  // No pushUpdate — Slack is 1-way
}
