// tools/integrate-pm.ts — Integration with Jira/Linear/GitHub Projects/Trello/Notion
// SPEC-023b: Real PM platform integrations via fetch() + API key validation
import { t, ti } from '../i18n/index.js';
import { knowledgeStore, specStore, readJson, globalDataDir } from '../storage/index.js';
import { validateApiKey, generateLabels, createIssueJira, createIssueLinear, createIssueGithubProjects, createTaskTrello, createPageNotion, syncSpecStatus, linkSpecToIssue, mapSpecStatus, } from '../engine/pm-integrator.js';
// === Supported platforms for SPEC-023b ===
const SUPPORTED_PLATFORMS = ['jira', 'linear', 'github-projects', 'trello', 'notion'];
function pmConfigFile() {
    return `${globalDataDir()}/pm-config.json`;
}
/**
 * Load PM configuration from data/global/pm-config.json.
 * Returns an empty store when the file does not exist.
 */
async function loadPMConfig() {
    const defaultStore = { platforms: {} };
    return readJson(pmConfigFile(), defaultStore);
}
export async function handleIntegratePM(args) {
    const { projectId, platform, action, specId, config: legacyConfig = {} } = args;
    // Validate project exists
    const knowledge = await knowledgeStore.getKnowledge(projectId);
    if (!knowledge) {
        return {
            content: [{ type: 'text', text: ti('errors.projectNotFound', { projectId }) }],
            isError: true,
        };
    }
    // Normalize platform alias: 'github' → 'github-projects'
    const normalizedPlatform = platform === 'github' ? 'github-projects' : platform;
    const pm = normalizedPlatform;
    if (!SUPPORTED_PLATFORMS.includes(pm)) {
        return {
            content: [
                {
                    type: 'text',
                    text: `Unsupported PM platform: ${platform}. Supported: ${SUPPORTED_PLATFORMS.join(', ')}`,
                },
            ],
            isError: true,
        };
    }
    // Criteria 9: validate API key configured by user
    const pmConfigStore = await loadPMConfig();
    const configOrError = validateApiKey(pmConfigStore, pm);
    if (typeof configOrError === 'string') {
        return {
            content: [{ type: 'text', text: configOrError }],
            isError: true,
        };
    }
    const pmConfig = configOrError;
    // Dispatch to action handlers
    switch (action) {
        case 'create-issue':
            return handleCreateIssue(projectId, pm, specId, pmConfig);
        case 'sync-spec':
            return handleSyncSpec(projectId, pm, specId, legacyConfig, pmConfig);
        case 'link-spec':
            return handleLinkSpec(projectId, pm, specId, legacyConfig, pmConfig);
        case 'update-status':
            return handleUpdateStatus(projectId, pm, specId, legacyConfig, pmConfig);
        default:
            return {
                content: [{ type: 'text', text: `Unknown action: ${String(action)}` }],
                isError: true,
            };
    }
}
// === Action handlers ===
async function handleCreateIssue(projectId, platform, specId, pmConfig) {
    if (!specId) {
        return {
            content: [{ type: 'text', text: 'specId is required for create-issue action.' }],
            isError: true,
        };
    }
    const spec = await specStore.getSpec(projectId, specId);
    if (!spec) {
        return {
            content: [{ type: 'text', text: ti('errors.specNotFound', { specId }) }],
            isError: true,
        };
    }
    try {
        let syncResult;
        if (platform === 'jira') {
            syncResult = await createIssueJira(spec, pmConfig);
        }
        else if (platform === 'linear') {
            syncResult = await createIssueLinear(spec, pmConfig);
        }
        else if (platform === 'github-projects') {
            syncResult = await createIssueGithubProjects(spec, pmConfig);
        }
        else if (platform === 'trello') {
            syncResult = await createTaskTrello(spec, pmConfig);
        }
        else {
            syncResult = await createPageNotion(spec, pmConfig);
        }
        const result = {
            platform,
            action: 'create-issue',
            externalId: syncResult.issueId,
            externalUrl: syncResult.issueUrl,
            message: `Issue created on ${platform}: ${syncResult.issueId} — Labels: ${syncResult.labels.join(', ')}`,
        };
        return formatResult(result);
    }
    catch (err) {
        const message = err instanceof Error ? err.message : String(err);
        return {
            content: [
                { type: 'text', text: `Failed to create issue on ${platform}: ${message}` },
            ],
            isError: true,
        };
    }
}
async function handleSyncSpec(projectId, platform, specId, legacyConfig, pmConfig) {
    if (!specId) {
        return {
            content: [{ type: 'text', text: 'specId is required for sync-spec action.' }],
            isError: true,
        };
    }
    const spec = await specStore.getSpec(projectId, specId);
    if (!spec) {
        return {
            content: [{ type: 'text', text: ti('errors.specNotFound', { specId }) }],
            isError: true,
        };
    }
    const issueId = legacyConfig.externalId;
    if (!issueId) {
        // No external ID → generate payload preview (non-API path)
        const mappedStatus = mapSpecStatus(platform, spec.status);
        const labels = generateLabels(spec);
        const result = {
            platform,
            action: 'sync-spec',
            message: `Sync payload for spec ${spec.id} → ${platform}. Mapped status: ${spec.status} → ${mappedStatus}. Labels: ${labels.join(', ')}. Provide externalId in config to apply the sync.`,
        };
        return formatResult(result);
    }
    try {
        const syncResult = await syncSpecStatus(spec, issueId, platform, pmConfig);
        const result = {
            platform,
            action: 'sync-spec',
            externalId: syncResult.issueId,
            externalUrl: syncResult.issueUrl,
            message: `Spec ${spec.id} synced with ${platform} issue ${syncResult.issueId}. Status updated.`,
        };
        return formatResult(result);
    }
    catch (err) {
        const message = err instanceof Error ? err.message : String(err);
        return {
            content: [{ type: 'text', text: `Failed to sync spec on ${platform}: ${message}` }],
            isError: true,
        };
    }
}
async function handleLinkSpec(projectId, platform, specId, legacyConfig, pmConfig) {
    if (!specId) {
        return {
            content: [{ type: 'text', text: 'specId is required for link-spec action.' }],
            isError: true,
        };
    }
    const spec = await specStore.getSpec(projectId, specId);
    if (!spec) {
        return {
            content: [{ type: 'text', text: ti('errors.specNotFound', { specId }) }],
            isError: true,
        };
    }
    const issueId = legacyConfig.externalId ?? '{EXTERNAL_ID}';
    const syncResult = linkSpecToIssue(spec, issueId, platform, pmConfig);
    const result = {
        platform,
        action: 'link-spec',
        externalId: syncResult.issueId,
        externalUrl: syncResult.issueUrl,
        message: `Spec ${spec.id} linked to ${platform} issue ${syncResult.issueId}. Labels: ${syncResult.labels.join(', ')}`,
    };
    return formatResult(result);
}
async function handleUpdateStatus(projectId, platform, specId, legacyConfig, pmConfig) {
    if (!specId) {
        return {
            content: [{ type: 'text', text: 'specId is required for update-status action.' }],
            isError: true,
        };
    }
    const spec = await specStore.getSpec(projectId, specId);
    if (!spec) {
        return {
            content: [{ type: 'text', text: ti('errors.specNotFound', { specId }) }],
            isError: true,
        };
    }
    const issueId = legacyConfig.externalId;
    if (!issueId) {
        const mappedStatus = mapSpecStatus(platform, spec.status);
        const result = {
            platform,
            action: 'update-status',
            message: `Status update: ${spec.status} → ${mappedStatus} on ${platform}. Provide externalId in config to apply.`,
        };
        return formatResult(result);
    }
    try {
        const syncResult = await syncSpecStatus(spec, issueId, platform, pmConfig);
        const result = {
            platform,
            action: 'update-status',
            externalId: syncResult.issueId,
            externalUrl: syncResult.issueUrl,
            message: `Status updated for ${platform} issue ${syncResult.issueId}.`,
        };
        return formatResult(result);
    }
    catch (err) {
        const message = err instanceof Error ? err.message : String(err);
        return {
            content: [
                { type: 'text', text: `Failed to update status on ${platform}: ${message}` },
            ],
            isError: true,
        };
    }
}
// === Output formatting ===
function formatResult(result) {
    const lines = [
        `## ${t('tools.integrate_pm.description')}`,
        '',
        `**Platform:** ${result.platform}`,
        `**Action:** ${result.action}`,
        '',
        `**${result.message}**`,
        '',
    ];
    if (result.externalId) {
        lines.push(`**External ID:** ${result.externalId}`);
    }
    if (result.externalUrl) {
        lines.push(`**URL:** [${result.externalUrl}](${result.externalUrl})`);
    }
    return { content: [{ type: 'text', text: lines.join('\n') }] };
}
//# sourceMappingURL=integrate-pm.js.map