"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MondayProvider = void 0;
const logger_1 = require("../logger");
const MONDAY_API_URL = 'https://api.monday.com/v2';
function getStatusFromColumnValues(columnValues, statusColumnId) {
    if (!columnValues)
        return '';
    const col = columnValues.find((c) => c.id === statusColumnId);
    if (!col)
        return '';
    if (col.text)
        return col.text;
    try {
        const parsed = JSON.parse(col.value || '{}');
        return parsed.label || '';
    }
    catch {
        return col.value || '';
    }
}
class MondayProvider {
    constructor(config) {
        this.apiToken = config.mondayApiToken;
        this.boardId = config.mondayBoardId;
        this.statusColumnId = config.mondayStatusColumnId;
        this.groupId = config.mondayGroupId || null;
        this.pendingStatus = config.clickupPendingStatus || 'pending';
        this.inReviewStatus = config.clickupInReviewStatus || 'review';
    }
    async graphql(query, variables) {
        const res = await fetch(MONDAY_API_URL, {
            method: 'POST',
            headers: {
                Authorization: this.apiToken,
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ query, variables }),
        });
        if (!res.ok) {
            const body = await res.text();
            throw new Error(`Monday API HTTP ${res.status}: ${body}`);
        }
        const json = (await res.json());
        if (json.errors && json.errors.length > 0) {
            const msg = json.errors.map((e) => e.message).join('; ');
            throw new Error(`Monday API GraphQL error: ${msg}`);
        }
        if (json.data === undefined) {
            throw new Error('Monday API returned no data');
        }
        return json.data;
    }
    async fetchTasks(_options) {
        logger_1.logger.debug(`Fetching items from Monday board ${this.boardId}`);
        const query = `
      query ($boardId: ID!, $limit: Int!) {
        boards(ids: [$boardId]) {
          items_page(limit: $limit) {
            cursor
            items {
              id
              name
              url
              description { description }
              column_values { id value text }
            }
          }
        }
      }
    `;
        const data = await this.graphql(query, {
            boardId: this.boardId,
            limit: 100,
        });
        const page = data.boards?.[0]?.items_page;
        if (!page?.items)
            return [];
        const pending = this.pendingStatus.toLowerCase();
        const inReview = this.inReviewStatus.toLowerCase();
        const tasks = [];
        for (const item of page.items) {
            const statusText = getStatusFromColumnValues(item.column_values, this.statusColumnId);
            const statusNorm = statusText.toLowerCase();
            if (statusNorm !== pending && statusNorm !== inReview)
                continue;
            tasks.push({
                id: String(item.id),
                name: item.name,
                description: item.description?.description ?? '',
                status: statusText,
                url: item.url || `https://${this.boardId}.monday.com`,
                tags: [],
                sourceListId: this.boardId,
            });
        }
        return tasks;
    }
    async fetchTasksByStatus(statuses, _options) {
        const normalized = statuses.map((s) => s.toLowerCase());
        const all = await this.fetchTasks();
        return all.filter((t) => normalized.includes(t.status.toLowerCase()));
    }
    async postComment(taskId, text) {
        logger_1.logger.debug(`Posting update to Monday item ${taskId}`);
        const mutation = `
      mutation ($itemId: ID!, $body: String!) {
        create_update(item_id: $itemId, body: $body) { id }
      }
    `;
        await this.graphql(mutation, {
            itemId: taskId,
            body: text,
        });
    }
    async getComments(taskId) {
        logger_1.logger.debug(`Fetching updates for Monday item ${taskId}`);
        const query = `
      query ($itemId: ID!) {
        items(ids: [$itemId]) {
          updates(limit: 100) {
            id
            text_body
            body
            created_at
            creator { id name }
          }
        }
      }
    `;
        const data = await this.graphql(query, { itemId: taskId });
        const item = data.items?.[0];
        const updates = item?.updates ?? [];
        const comments = updates.map((u) => ({
            id: u.id,
            text: u.text_body || stripHtml(u.body || ''),
            author: u.creator?.name || 'Unknown',
            authorId: u.creator?.id || '',
            date: u.created_at ? new Date(u.created_at).getTime() : 0,
        }));
        comments.sort((a, b) => a.date - b.date);
        return comments;
    }
    async fetchAvailableStatuses() {
        const query = `
      query ($boardId: ID!) {
        boards(ids: [$boardId]) {
          columns { id settings_str }
        }
      }
    `;
        const data = await this.graphql(query, { boardId: this.boardId });
        const col = data.boards?.[0]?.columns?.find((c) => c.id === this.statusColumnId);
        if (!col?.settings_str)
            return [];
        try {
            const parsed = JSON.parse(col.settings_str);
            return Object.values(parsed.labels || {});
        }
        catch {
            return [];
        }
    }
    async updateStatus(taskId, status) {
        logger_1.logger.debug(`Updating Monday item ${taskId} status to "${status}"`);
        const mutation = `
      mutation ($boardId: ID!, $itemId: ID!, $columnId: String!, $value: String!) {
        change_column_value(board_id: $boardId, item_id: $itemId, column_id: $columnId, value: $value) { id }
      }
    `;
        const value = JSON.stringify({ label: status });
        await this.graphql(mutation, {
            boardId: this.boardId,
            itemId: taskId,
            columnId: this.statusColumnId,
            value,
        });
    }
    async createTask(params) {
        const groupId = this.groupId || 'topics';
        const mutation = `
      mutation ($boardId: ID!, $groupId: String!, $itemName: String!, $columnValues: JSON) {
        create_item(board_id: $boardId, group_id: $groupId, item_name: $itemName, column_values: $columnValues) { id }
      }
    `;
        const columnValues = {};
        if (this.statusColumnId) {
            columnValues[this.statusColumnId] = { label: this.pendingStatus };
        }
        const data = await this.graphql(mutation, {
            boardId: this.boardId,
            groupId,
            itemName: params.title,
            columnValues: Object.keys(columnValues).length > 0 ? JSON.stringify(columnValues) : undefined,
        });
        const id = String(data.create_item.id);
        return { id, url: `https://monday.com/boards/${this.boardId}/pulses/${id}` };
    }
}
exports.MondayProvider = MondayProvider;
function stripHtml(html) {
    return html
        .replace(/<[^>]+>/g, ' ')
        .replace(/&nbsp;/g, ' ')
        .replace(/&amp;/g, '&')
        .replace(/&lt;/g, '<')
        .replace(/&gt;/g, '>')
        .replace(/\s+/g, ' ')
        .trim();
}
//# sourceMappingURL=monday.js.map