import { config } from '../config.js';
import { intakeService } from './intake.service.js';
import type { IngestInput } from '../types.js';

interface MondayItem {
  id: string;
  name: string;
  created_at: string;
  url: string;
  column_values: Array<{
    id: string;
    text: string | null;
    value: string | null;
    type: string;
  }>;
  creator?: { id: string; name: string; email?: string };
  board?: { id: string; name: string };
}

export class MondayService {
  private async graphql<T>(query: string, variables?: Record<string, unknown>): Promise<T> {
    if (!config.monday.apiToken) throw new Error('Monday API not configured');

    const res = await fetch('https://api.monday.com/v2', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: config.monday.apiToken,
      },
      body: JSON.stringify({ query, variables }),
    });

    if (!res.ok) {
      throw new Error(`Monday API HTTP ${res.status}`);
    }

    const json = (await res.json()) as { data?: T; errors?: Array<{ message: string }> };
    if (json.errors?.length) {
      throw new Error(json.errors.map((e) => e.message).join('; '));
    }
    return json.data as T;
  }

  getStatus(): { enabled: boolean; boardIds: string[] } {
    return { enabled: config.monday.enabled(), boardIds: config.monday.boardIds };
  }

  async poll(): Promise<{ imported: number; duplicates: number; errors: string[] }> {
    if (!config.monday.enabled()) {
      return { imported: 0, duplicates: 0, errors: ['Monday API not configured'] };
    }

    let imported = 0;
    let duplicates = 0;
    const errors: string[] = [];

    for (const boardId of config.monday.boardIds) {
      try {
        const data = await this.graphql<{ boards: Array<{ items_page: { items: MondayItem[] } }> }>(
          `query ($boardId: [ID!]) {
            boards(ids: $boardId) {
              items_page(limit: 25) {
                items {
                  id name created_at url
                  creator { id name email }
                  board { id name }
                  column_values { id text value type }
                }
              }
            }
          }`,
          { boardId: [boardId] },
        );

        const items = data.boards?.[0]?.items_page?.items ?? [];
        for (const item of items) {
          const input = this.normalizeItem(item);
          const result = intakeService.ingest(input);
          if (result.duplicate) duplicates++;
          else imported++;
        }
      } catch (err) {
        errors.push(`Board ${boardId}: ${err instanceof Error ? err.message : String(err)}`);
      }
    }

    return { imported, duplicates, errors };
  }

  private normalizeItem(item: MondayItem): IngestInput {
    const description =
      item.column_values.find((c) => c.type === 'long_text' || c.id === 'text')?.text ?? '';
    const clientProject = item.board?.name ?? null;

    return {
      source_type: 'monday_api',
      source_account: item.board?.id ?? null,
      source_external_id: item.board?.id ? `monday-${item.board.id}-${item.id}` : item.id,
      source_url: item.url,
      sender_id: item.creator?.id ?? null,
      sender_name: item.creator?.name ?? null,
      sender_email: item.creator?.email ?? null,
      client_project: clientProject,
      title: item.name,
      body: description,
      metadata: {
        board_id: item.board?.id,
        board_name: item.board?.name,
        column_values: item.column_values,
      },
      raw_payload: item,
      received_at: item.created_at,
    };
  }
}

export const mondayService = new MondayService();

let pollTimer: ReturnType<typeof setInterval> | null = null;

export function startMondayPoller(): void {
  if (!config.monday.enabled() || pollTimer) return;
  console.log('[monday] poller started');
  pollTimer = setInterval(() => {
    mondayService.poll().catch((err) => {
      console.error('[monday] poll error:', err instanceof Error ? err.message : err);
    });
  }, config.monday.pollIntervalMs);
}

export function stopMondayPoller(): void {
  if (pollTimer) {
    clearInterval(pollTimer);
    pollTimer = null;
    console.log('[monday] poller stopped');
  }
}
