/**
 * V3 CLI Task Command
 * Task management for KynjalFlow
 */
import { output } from '../output.js';
import { select, confirm, input, multiSelect } from '../prompt.js';
import { callMCPTool, MCPClientError } from '../mcp-client.js';
// Task types
const TASK_TYPES = [
    { value: 'implementation', label: 'Implementation', hint: 'Feature implementation' },
    { value: 'bug-fix', label: 'Bug Fix', hint: 'Fix a bug or issue' },
    { value: 'refactoring', label: 'Refactoring', hint: 'Code refactoring' },
    { value: 'testing', label: 'Testing', hint: 'Write or update tests' },
    { value: 'documentation', label: 'Documentation', hint: 'Documentation updates' },
    { value: 'research', label: 'Research', hint: 'Research and analysis' },
    { value: 'review', label: 'Review', hint: 'Code review' },
    { value: 'optimization', label: 'Optimization', hint: 'Performance optimization' },
    { value: 'security', label: 'Security', hint: 'Security audit or fix' },
    { value: 'custom', label: 'Custom', hint: 'Custom task type' }
];
// Task priorities
const TASK_PRIORITIES = [
    { value: 'critical', label: 'Critical', hint: 'Highest priority' },
    { value: 'high', label: 'High', hint: 'Important task' },
    { value: 'normal', label: 'Normal', hint: 'Standard priority' },
    { value: 'low', label: 'Low', hint: 'Lower priority' }
];
// Format task status with color
function formatStatus(status) {
    switch (status) {
        case 'completed':
            return output.success(status);
        case 'running':
        case 'in_progress':
            return output.info(status);
        case 'pending':
        case 'queued':
            return output.warning(status);
        case 'failed':
        case 'cancelled':
            return output.error(status);
        default:
            return status;
    }
}
// Format priority with color
function formatPriority(priority) {
    switch (priority) {
        case 'critical':
            return output.error(priority);
        case 'high':
            return output.warning(priority);
        case 'normal':
            return priority;
        case 'low':
            return output.dim(priority);
        default:
            return priority;
    }
}
// Create subcommand
const createCommand = {
    name: 'create',
    aliases: ['new', 'add'],
    description: 'Create a new task',
    options: [
        {
            name: 'type',
            short: 't',
            description: 'Task type',
            type: 'string',
            choices: TASK_TYPES.map(t => t.value)
        },
        {
            name: 'description',
            short: 'd',
            description: 'Task description',
            type: 'string'
        },
        {
            name: 'priority',
            short: 'p',
            description: 'Task priority',
            type: 'string',
            choices: TASK_PRIORITIES.map(p => p.value),
            default: 'normal'
        },
        {
            name: 'assign',
            short: 'a',
            description: 'Assign to agent(s)',
            type: 'string'
        },
        {
            name: 'tags',
            description: 'Comma-separated tags',
            type: 'string'
        },
        {
            name: 'parent',
            description: 'Parent task ID',
            type: 'string'
        },
        {
            name: 'dependencies',
            description: 'Comma-separated task IDs that must complete first',
            type: 'string'
        },
        {
            name: 'timeout',
            description: 'Task timeout in seconds',
            type: 'number',
            default: 300
        }
    ],
    action: async (ctx) => {
        let taskType = ctx.flags.type;
        let description = ctx.flags.description;
        let priority = ctx.flags.priority;
        // Interactive mode
        if (!taskType && ctx.interactive) {
            taskType = await select({
                message: 'Select task type:',
                options: TASK_TYPES
            });
        }
        if (!description && ctx.interactive) {
            description = await input({
                message: 'Task description:',
                validate: (v) => v.length > 0 || 'Description is required'
            });
        }
        if (!taskType || !description) {
            output.printError('Task type and description are required');
            output.printInfo('Use --type and --description flags, or run in interactive mode');
            return { success: false, exitCode: 1 };
        }
        if (!priority && ctx.interactive) {
            priority = await select({
                message: 'Select priority:',
                options: TASK_PRIORITIES,
                default: 'normal'
            });
        }
        // Parse tags and dependencies
        const tags = ctx.flags.tags ? ctx.flags.tags.split(',').map(t => t.trim()) : [];
        const dependencies = ctx.flags.dependencies
            ? ctx.flags.dependencies.split(',').map(d => d.trim())
            : [];
        output.writeln();
        output.printInfo(`Creating ${taskType} task...`);
        try {
            const result = await callMCPTool('task_create', {
                type: taskType,
                description,
                priority: priority || 'normal',
                assignedTo: ctx.flags.assign ? [ctx.flags.assign] : undefined,
                parentId: ctx.flags.parent,
                dependencies,
                tags,
                timeout: ctx.flags.timeout,
                metadata: {
                    source: 'cli',
                    createdBy: 'user'
                }
            });
            output.writeln();
            output.printSuccess(`Task created: ${result.taskId}`);
            output.writeln();
            output.printTable({
                columns: [
                    { key: 'property', header: 'Property', width: 15 },
                    { key: 'value', header: 'Value', width: 40 }
                ],
                data: [
                    { property: 'ID', value: result.taskId },
                    { property: 'Type', value: result.type },
                    { property: 'Description', value: result.description },
                    { property: 'Priority', value: formatPriority(result.priority) },
                    { property: 'Status', value: formatStatus(result.status) },
                    { property: 'Assigned To', value: result.assignedTo?.join(', ') || 'Unassigned' },
                    { property: 'Tags', value: result.tags.join(', ') || 'None' },
                    { property: 'Created', value: new Date(result.createdAt).toLocaleString() }
                ]
            });
            if (ctx.flags.format === 'json') {
                output.printJson(result);
            }
            return { success: true, data: result };
        }
        catch (error) {
            if (error instanceof MCPClientError) {
                output.printError(`Failed to create task: ${error.message}`);
            }
            else {
                output.printError(`Unexpected error: ${String(error)}`);
            }
            return { success: false, exitCode: 1 };
        }
    }
};
// List subcommand
const listCommand = {
    name: 'list',
    aliases: ['ls'],
    description: 'List tasks',
    options: [
        {
            name: 'status',
            short: 's',
            description: 'Filter by status',
            type: 'string',
            choices: ['pending', 'running', 'completed', 'failed', 'cancelled', 'all']
        },
        {
            name: 'type',
            short: 't',
            description: 'Filter by task type',
            type: 'string'
        },
        {
            name: 'priority',
            short: 'p',
            description: 'Filter by priority',
            type: 'string'
        },
        {
            name: 'agent',
            short: 'a',
            description: 'Filter by assigned agent',
            type: 'string'
        },
        {
            name: 'limit',
            short: 'l',
            description: 'Maximum number of tasks to show',
            type: 'number',
            default: 20
        },
        {
            name: 'all',
            description: 'Show all tasks including completed',
            type: 'boolean',
            default: false
        }
    ],
    action: async (ctx) => {
        const status = ctx.flags.all ? 'all' : ctx.flags.status || 'pending,running';
        const limit = ctx.flags.limit;
        try {
            const result = await callMCPTool('task_list', {
                status,
                type: ctx.flags.type,
                priority: ctx.flags.priority,
                agentId: ctx.flags.agent,
                limit,
                offset: 0
            });
            if (ctx.flags.format === 'json') {
                output.printJson(result);
                return { success: true, data: result };
            }
            output.writeln();
            output.writeln(output.bold('Tasks'));
            output.writeln();
            if (result.tasks.length === 0) {
                output.printInfo('No tasks found matching criteria');
                return { success: true, data: result };
            }
            output.printTable({
                columns: [
                    { key: 'id', header: 'ID', width: 15 },
                    { key: 'type', header: 'Type', width: 15 },
                    { key: 'description', header: 'Description', width: 30 },
                    { key: 'priority', header: 'Priority', width: 10 },
                    { key: 'status', header: 'Status', width: 12 },
                    { key: 'progress', header: 'Progress', width: 10 }
                ],
                data: result.tasks.map(t => ({
                    id: t.id,
                    type: t.type,
                    description: t.description.length > 27
                        ? t.description.slice(0, 27) + '...'
                        : t.description,
                    priority: formatPriority(t.priority),
                    status: formatStatus(t.status),
                    progress: `${t.progress}%`
                }))
            });
            output.writeln();
            output.printInfo(`Showing ${result.tasks.length} of ${result.total} tasks`);
            return { success: true, data: result };
        }
        catch (error) {
            if (error instanceof MCPClientError) {
                output.printError(`Failed to list tasks: ${error.message}`);
            }
            else {
                output.printError(`Unexpected error: ${String(error)}`);
            }
            return { success: false, exitCode: 1 };
        }
    }
};
// Status subcommand (get task details)
const statusCommand = {
    name: 'status',
    aliases: ['info', 'get'],
    description: 'Get task status and details',
    options: [
        {
            name: 'id',
            description: 'Task ID',
            type: 'string'
        },
        {
            name: 'logs',
            description: 'Include execution logs',
            type: 'boolean',
            default: false
        }
    ],
    action: async (ctx) => {
        let taskId = ctx.args[0] || ctx.flags.id;
        if (!taskId && ctx.interactive) {
            taskId = await input({
                message: 'Enter task ID:',
                validate: (v) => v.length > 0 || 'Task ID is required'
            });
        }
        if (!taskId) {
            output.printError('Task ID is required');
            return { success: false, exitCode: 1 };
        }
        try {
            const result = await callMCPTool('task_status', {
                taskId,
                includeLogs: ctx.flags.logs,
                includeMetrics: true
            });
            if (ctx.flags.format === 'json') {
                output.printJson(result);
                return { success: true, data: result };
            }
            output.writeln();
            output.printBox([
                `Type:        ${result.type}`,
                `Status:      ${formatStatus(result.status)}`,
                `Priority:    ${formatPriority(result.priority)}`,
                `Progress:    ${result.progress}%`,
                '',
                `Description: ${result.description}`
            ].join('\n'), `Task: ${result.id}`);
            // Assignment info
            output.writeln();
            output.writeln(output.bold('Assignment'));
            output.printTable({
                columns: [
                    { key: 'property', header: 'Property', width: 15 },
                    { key: 'value', header: 'Value', width: 40 }
                ],
                data: [
                    { property: 'Assigned To', value: result.assignedTo?.join(', ') || 'Unassigned' },
                    { property: 'Parent Task', value: result.parentId || 'None' },
                    { property: 'Dependencies', value: result.dependencies.join(', ') || 'None' },
                    { property: 'Dependents', value: result.dependents.join(', ') || 'None' },
                    { property: 'Tags', value: result.tags.join(', ') || 'None' }
                ]
            });
            // Timeline
            output.writeln();
            output.writeln(output.bold('Timeline'));
            output.printTable({
                columns: [
                    { key: 'event', header: 'Event', width: 15 },
                    { key: 'time', header: 'Time', width: 30 }
                ],
                data: [
                    { event: 'Created', time: new Date(result.createdAt).toLocaleString() },
                    { event: 'Started', time: result.startedAt ? new Date(result.startedAt).toLocaleString() : '-' },
                    { event: 'Completed', time: result.completedAt ? new Date(result.completedAt).toLocaleString() : '-' }
                ]
            });
            // Metrics
            if (result.metrics) {
                output.writeln();
                output.writeln(output.bold('Metrics'));
                output.printTable({
                    columns: [
                        { key: 'metric', header: 'Metric', width: 20 },
                        { key: 'value', header: 'Value', width: 20, align: 'right' }
                    ],
                    data: [
                        { metric: 'Execution Time', value: `${(result.metrics.executionTime / 1000).toFixed(2)}s` },
                        { metric: 'Retries', value: result.metrics.retries },
                        { metric: 'Tokens Used', value: result.metrics.tokensUsed.toLocaleString() }
                    ]
                });
            }
            // Error if failed
            if (result.status === 'failed' && result.error) {
                output.writeln();
                output.printError(`Error: ${result.error}`);
            }
            // Logs if requested
            if (ctx.flags.logs && result.logs && result.logs.length > 0) {
                output.writeln();
                output.writeln(output.bold('Execution Logs'));
                for (const log of result.logs.slice(-20)) {
                    const time = new Date(log.timestamp).toLocaleTimeString();
                    const level = log.level === 'error' ? output.error(`[${log.level}]`) :
                        log.level === 'warn' ? output.warning(`[${log.level}]`) :
                            output.dim(`[${log.level}]`);
                    output.writeln(`  ${output.dim(time)} ${level} ${log.message}`);
                }
            }
            return { success: true, data: result };
        }
        catch (error) {
            if (error instanceof MCPClientError) {
                output.printError(`Failed to get task status: ${error.message}`);
            }
            else {
                output.printError(`Unexpected error: ${String(error)}`);
            }
            return { success: false, exitCode: 1 };
        }
    }
};
// Cancel subcommand
const cancelCommand = {
    name: 'cancel',
    aliases: ['abort', 'stop'],
    description: 'Cancel a running task',
    options: [
        {
            name: 'force',
            short: 'f',
            description: 'Force cancel without confirmation',
            type: 'boolean',
            default: false
        },
        {
            name: 'reason',
            short: 'r',
            description: 'Cancellation reason',
            type: 'string'
        }
    ],
    action: async (ctx) => {
        const taskId = ctx.args[0];
        const force = ctx.flags.force;
        const reason = ctx.flags.reason;
        if (!taskId) {
            output.printError('Task ID is required');
            return { success: false, exitCode: 1 };
        }
        if (!force && ctx.interactive) {
            const confirmed = await confirm({
                message: `Are you sure you want to cancel task ${taskId}?`,
                default: false
            });
            if (!confirmed) {
                output.printInfo('Operation cancelled');
                return { success: true };
            }
        }
        try {
            const result = await callMCPTool('task_cancel', {
                taskId,
                reason: reason || 'Cancelled by user via CLI'
            });
            output.writeln();
            output.printSuccess(`Task ${taskId} cancelled`);
            output.printInfo(`Previous status: ${result.previousStatus}`);
            if (ctx.flags.format === 'json') {
                output.printJson(result);
            }
            return { success: true, data: result };
        }
        catch (error) {
            if (error instanceof MCPClientError) {
                output.printError(`Failed to cancel task: ${error.message}`);
            }
            else {
                output.printError(`Unexpected error: ${String(error)}`);
            }
            return { success: false, exitCode: 1 };
        }
    }
};
// Assign subcommand
const assignCommand = {
    name: 'assign',
    description: 'Assign a task to agent(s)',
    options: [
        {
            name: 'agent',
            short: 'a',
            description: 'Agent ID(s) to assign (comma-separated)',
            type: 'string'
        },
        {
            name: 'unassign',
            description: 'Remove current assignment',
            type: 'boolean',
            default: false
        }
    ],
    action: async (ctx) => {
        const taskId = ctx.args[0];
        const agentIds = ctx.flags.agent;
        const unassign = ctx.flags.unassign;
        if (!taskId) {
            output.printError('Task ID is required');
            return { success: false, exitCode: 1 };
        }
        if (!agentIds && !unassign) {
            // Interactive agent selection
            if (ctx.interactive) {
                try {
                    const agents = await callMCPTool('agent_list', { status: 'active,idle' });
                    if (agents.agents.length === 0) {
                        output.printWarning('No available agents');
                        return { success: false, exitCode: 1 };
                    }
                    const selectedAgents = await multiSelect({
                        message: 'Select agent(s) to assign:',
                        options: agents.agents.map(a => ({
                            value: a.id,
                            label: a.id,
                            hint: `${a.type} - ${a.status}`
                        })),
                        required: true
                    });
                    if (selectedAgents.length === 0) {
                        output.printInfo('No agents selected');
                        return { success: true };
                    }
                    // Continue with assignment
                    const result = await callMCPTool('task_assign', {
                        taskId,
                        agentIds: selectedAgents
                    });
                    output.writeln();
                    output.printSuccess(`Task ${taskId} assigned to ${result.assignedTo.join(', ')}`);
                    return { success: true, data: result };
                }
                catch (error) {
                    if (error instanceof Error && error.message === 'User cancelled') {
                        output.printInfo('Operation cancelled');
                        return { success: true };
                    }
                    throw error;
                }
            }
            output.printError('Agent ID is required. Use --agent flag or run in interactive mode');
            return { success: false, exitCode: 1 };
        }
        try {
            const result = await callMCPTool('task_assign', {
                taskId,
                agentIds: unassign ? [] : agentIds.split(',').map(id => id.trim()),
                unassign
            });
            output.writeln();
            if (unassign) {
                output.printSuccess(`Task ${taskId} unassigned`);
            }
            else {
                output.printSuccess(`Task ${taskId} assigned to ${result.assignedTo.join(', ')}`);
            }
            if (ctx.flags.format === 'json') {
                output.printJson(result);
            }
            return { success: true, data: result };
        }
        catch (error) {
            if (error instanceof MCPClientError) {
                output.printError(`Failed to assign task: ${error.message}`);
            }
            else {
                output.printError(`Unexpected error: ${String(error)}`);
            }
            return { success: false, exitCode: 1 };
        }
    }
};
// Retry subcommand
const retryCommand = {
    name: 'retry',
    aliases: ['rerun'],
    description: 'Retry a failed task',
    options: [
        {
            name: 'reset-state',
            description: 'Reset task state completely',
            type: 'boolean',
            default: false
        }
    ],
    action: async (ctx) => {
        const taskId = ctx.args[0];
        const resetState = ctx.flags['reset-state'];
        if (!taskId) {
            output.printError('Task ID is required');
            return { success: false, exitCode: 1 };
        }
        try {
            const result = await callMCPTool('task_retry', {
                taskId,
                resetState
            });
            output.writeln();
            output.printSuccess(`Task ${taskId} retried`);
            output.printInfo(`New task ID: ${result.newTaskId}`);
            output.printInfo(`Status: ${formatStatus(result.status)}`);
            if (ctx.flags.format === 'json') {
                output.printJson(result);
            }
            return { success: true, data: result };
        }
        catch (error) {
            if (error instanceof MCPClientError) {
                output.printError(`Failed to retry task: ${error.message}`);
            }
            else {
                output.printError(`Unexpected error: ${String(error)}`);
            }
            return { success: false, exitCode: 1 };
        }
    }
};
// Main task command
export const taskCommand = {
    name: 'task',
    description: 'Task management commands',
    subcommands: [createCommand, listCommand, statusCommand, cancelCommand, assignCommand, retryCommand],
    options: [],
    examples: [
        { command: 'claude-flow task create -t implementation -d "Add user auth"', description: 'Create a task' },
        { command: 'claude-flow task list', description: 'List pending/running tasks' },
        { command: 'claude-flow task list --all', description: 'List all tasks' },
        { command: 'claude-flow task status task-123', description: 'Get task details' },
        { command: 'claude-flow task cancel task-123', description: 'Cancel a task' },
        { command: 'claude-flow task assign task-123 --agent coder-1', description: 'Assign task to agent' },
        { command: 'claude-flow task retry task-123', description: 'Retry a failed task' }
    ],
    action: async (ctx) => {
        // Show help if no subcommand
        output.writeln();
        output.writeln(output.bold('Task Management Commands'));
        output.writeln();
        output.writeln('Usage: claude-flow task <subcommand> [options]');
        output.writeln();
        output.writeln('Subcommands:');
        output.printList([
            `${output.highlight('create')}  - Create a new task`,
            `${output.highlight('list')}    - List tasks`,
            `${output.highlight('status')}  - Get task details`,
            `${output.highlight('cancel')}  - Cancel a running task`,
            `${output.highlight('assign')}  - Assign task to agent(s)`,
            `${output.highlight('retry')}   - Retry a failed task`
        ]);
        output.writeln();
        output.writeln('Run "claude-flow task <subcommand> --help" for subcommand help');
        return { success: true };
    }
};
export default taskCommand;
//# sourceMappingURL=task.js.map