import { TaskRunner } from '../../task/index.js';
import { validateSystemEffectPayload } from '../../../core/workflow/system/system-step-effect-runner.js';
import { fetchExistingPr, fetchIssueContext, fetchPrContext, resolveCurrentBranch, } from './system-git-context.js';
import { commentPrEffect, closePrEffect, mergePrEffect, } from './system-pr-effects.js';
import { enqueueTaskEffect } from './system-enqueue-effect.js';
import { resolveConflictsWithAiEffect, syncWithRootEffect } from './system-sync-effects.js';
import { resolveIssueListInput, resolveIssueSelectionInput } from './system-issue-input-resolver.js';
import { resolvePrListInput, resolvePrSelectionInput } from './system-pr-input-resolver.js';
function listQueueTasks(projectCwd) {
    return new TaskRunner(projectCwd).listAllTaskItems();
}
function buildTaskQueueContext(tasks) {
    const counts = {
        pending_count: 0,
        running_count: 0,
        completed_count: 0,
        failed_count: 0,
        exceeded_count: 0,
        pr_failed_count: 0,
    };
    for (const task of tasks) {
        const key = `${task.kind}_count`;
        if (key in counts) {
            counts[key] += 1;
        }
    }
    return {
        exists: tasks.length > 0,
        total_count: tasks.length,
        ...counts,
        items: tasks.map((task) => ({
            task_name: task.name,
            kind: task.kind,
            issue: task.issueNumber,
            pr: task.prNumber,
        })),
    };
}
function resolveTaskQueueInput(input, options) {
    const tasks = listQueueTasks(options.projectCwd);
    if (input.exclude_current_task !== true) {
        return buildTaskQueueContext(tasks);
    }
    const runSlug = options.taskContext?.runSlug;
    if (!runSlug) {
        throw new Error('task_queue_context.exclude_current_task requires current task run slug');
    }
    return buildTaskQueueContext(tasks.filter((task) => task.runSlug !== runSlug));
}
function resolveInput(options, input, state, stepName, resolutionContext) {
    switch (input.type) {
        case 'task_context':
            return options.task.length > 0
                ? { exists: true, body: options.task }
                : { exists: false };
        case 'branch_context': {
            const resolvedBranch = resolveCurrentBranch(options.cwd);
            if (resolvedBranch.error) {
                throw new Error(`Failed to resolve current branch: ${resolvedBranch.error}`);
            }
            return resolvedBranch.branch ? { exists: true, name: resolvedBranch.branch } : { exists: false };
        }
        case 'pr_context': {
            const resolvedBranch = resolveCurrentBranch(options.cwd);
            if (resolvedBranch.error) {
                throw new Error(`Failed to resolve current branch: ${resolvedBranch.error}`);
            }
            if (!resolvedBranch.branch) {
                return { exists: false };
            }
            const existingPr = fetchExistingPr(options.projectCwd, resolvedBranch.branch);
            if (!existingPr) {
                return { exists: false, branch: resolvedBranch.branch };
            }
            const pr = fetchPrContext(options.projectCwd, existingPr.number);
            return {
                exists: true,
                number: pr.number,
                url: pr.url,
                branch: pr.headRefName,
                baseBranch: pr.baseRefName,
                title: pr.title,
                body: pr.body,
            };
        }
        case 'issue_context': {
            const issueNumber = options.taskContext?.issueNumber;
            if (issueNumber == null) {
                return { exists: false };
            }
            const issue = fetchIssueContext(options.projectCwd, issueNumber);
            return {
                exists: true,
                number: issue.number,
                title: issue.title,
                body: issue.body,
                labels: issue.labels,
                comments: issue.comments,
            };
        }
        case 'task_queue_context': {
            return resolveTaskQueueInput(input, options);
        }
        case 'issue_list':
            return resolveIssueListInput(input, options.projectCwd, resolutionContext);
        case 'issue_selection':
            return resolveIssueSelectionInput(input, options.projectCwd, state, stepName, resolutionContext);
        case 'pr_list':
            return resolvePrListInput(input, options.projectCwd, resolutionContext);
        case 'pr_selection':
            return resolvePrSelectionInput(input, options.projectCwd, state, stepName, resolutionContext);
    }
}
async function runEffect(options, effect, payload) {
    switch (effect.type) {
        case 'enqueue_task':
            return enqueueTaskEffect(options, payload);
        case 'comment_pr':
            return commentPrEffect(options, payload);
        case 'sync_with_root':
            return syncWithRootEffect(options, payload);
        case 'resolve_conflicts_with_ai':
            return resolveConflictsWithAiEffect(options, payload);
        case 'merge_pr':
            return mergePrEffect(options, payload);
        case 'close_pr':
            return closePrEffect(options, payload);
    }
}
export class DefaultSystemStepServices {
    options;
    constructor(options) {
        this.options = options;
    }
    resolveSystemInput = (input, state, stepName, resolutionContext) => {
        return resolveInput(this.options, input, state, stepName, resolutionContext);
    };
    executeEffect = async (effect, payload, _state) => {
        validateSystemEffectPayload(effect, payload);
        return runEffect(this.options, effect, payload);
    };
}
export function createDefaultSystemStepServices(options) {
    return new DefaultSystemStepServices(options);
}
//# sourceMappingURL=DefaultSystemStepServices.js.map