/**
 * JIRA Items Adapter - OPTIMIZED FOR SCALE
 *
 * Three-tier fetching:
 * 1. getOpenCount() - Single API call, returns total (for status)
 * 2. getOpenItems(filter) - Paginated, filtered (for details)
 *
 * Requires JIRA_BASE_URL, JIRA_EMAIL, JIRA_API_TOKEN in environment
 */
import { STALE_THRESHOLD_DAYS, DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE, calculateAgeDays, emptyPaginatedResult, filterByStale, } from '../types.js';
import { consoleLogger } from '../../../utils/logger.js';
export class JiraItemsAdapter {
    constructor(options) {
        this.baseUrl = options.baseUrl.replace(/\/$/, ''); // Remove trailing slash
        this.email = options.email;
        this.apiToken = options.apiToken;
        this.projectKey = options.projectKey;
        this.logger = options.logger ?? consoleLogger;
    }
    static fromEnv(options) {
        const baseUrl = process.env.JIRA_BASE_URL;
        const email = process.env.JIRA_EMAIL;
        const apiToken = process.env.JIRA_API_TOKEN;
        const projectKey = options?.projectKey || process.env.JIRA_PROJECT_KEY;
        if (!baseUrl || !email || !apiToken) {
            return null;
        }
        return new JiraItemsAdapter({
            baseUrl,
            email,
            apiToken,
            projectKey: projectKey || '',
            logger: options?.logger,
        });
    }
    getProviderName() {
        return 'jira';
    }
    async isConfigured() {
        return !!(this.baseUrl && this.email && this.apiToken);
    }
    /**
     * TIER 1: Fast count - single API call with maxResults=0
     * JIRA returns total even when maxResults=0, so we get count without fetching items
     */
    async getOpenCount() {
        if (!await this.isConfigured()) {
            return 0;
        }
        try {
            const jql = this.projectKey
                ? `project = "${this.projectKey}" AND status NOT IN (Done, Closed)`
                : 'status NOT IN (Done, Closed)';
            const encodedJql = encodeURIComponent(jql);
            // maxResults=0 returns just the total count without fetching items
            const url = `${this.baseUrl}/rest/api/3/search?jql=${encodedJql}&maxResults=0`;
            const authString = Buffer.from(`${this.email}:${this.apiToken}`).toString('base64');
            const response = await fetch(url, {
                headers: {
                    'Authorization': `Basic ${authString}`,
                    'Accept': 'application/json',
                },
            });
            if (!response.ok) {
                this.logger.error(`JIRA count error: ${response.status} ${response.statusText}`);
                return 0;
            }
            const data = await response.json();
            return data.total || 0;
        }
        catch (error) {
            this.logger.error(`JIRA count failed: ${error}`);
            return 0;
        }
    }
    /**
     * TIER 3: Paginated items - on-demand with filters
     */
    async getOpenItems(filter) {
        if (!await this.isConfigured()) {
            return emptyPaginatedResult(1, DEFAULT_PAGE_SIZE);
        }
        const limit = Math.min(filter?.limit || DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE);
        const offset = filter?.offset || 0;
        const page = Math.floor(offset / limit) + 1;
        try {
            const jql = this.projectKey
                ? `project = "${this.projectKey}" AND status NOT IN (Done, Closed) ORDER BY created DESC`
                : 'status NOT IN (Done, Closed) ORDER BY created DESC';
            const url = `${this.baseUrl}/rest/api/3/search?jql=${encodeURIComponent(jql)}&startAt=${offset}&maxResults=${limit}&fields=key,summary,created,labels,status`;
            const authString = Buffer.from(`${this.email}:${this.apiToken}`).toString('base64');
            const response = await fetch(url, {
                headers: {
                    'Authorization': `Basic ${authString}`,
                    'Accept': 'application/json',
                },
            });
            if (!response.ok) {
                this.logger.error(`JIRA API error: ${response.status} ${response.statusText}`);
                return emptyPaginatedResult(page, limit);
            }
            const data = await response.json();
            const total = data.total;
            const totalPages = Math.ceil(total / limit);
            const items = data.issues.map(issue => {
                const ageDays = calculateAgeDays(issue.fields.created);
                return {
                    id: issue.key,
                    title: issue.fields.summary,
                    url: `${this.baseUrl}/browse/${issue.key}`,
                    createdAt: issue.fields.created,
                    age: ageDays,
                    labels: issue.fields.labels || [],
                    provider: 'jira',
                    project: this.projectKey || 'default',
                    state: issue.fields.status.name,
                    isStale: ageDays >= STALE_THRESHOLD_DAYS,
                };
            });
            return {
                items: filterByStale(items, filter?.staleOnly),
                total,
                page,
                pageSize: limit,
                totalPages,
                hasMore: page < totalPages,
            };
        }
        catch (error) {
            this.logger.error(`Failed to fetch JIRA issues: ${error}`);
            return emptyPaginatedResult(page, limit);
        }
    }
}
//# sourceMappingURL=jira-items-adapter.js.map