import chalk from 'chalk';
import { APIClient, } from '../utils/api.js';
import { ProjectMemoryService } from '../utils/project-memory.js';
export class WorkflowCommand {
    config;
    logger;
    api;
    constructor(config, logger) {
        this.config = config;
        this.logger = logger;
        this.api = new APIClient(config, logger);
    }
    ensureAuthenticated(json = false) {
        if (this.config.isAuthenticated()) {
            return;
        }
        const message = 'Not authenticated. Run vigthoria login first.';
        if (json) {
            console.log(JSON.stringify({ success: false, error: message }, null, 2));
        }
        else {
            this.logger.error(message);
        }
        throw new Error(message);
    }
    parseJsonOption(rawValue, fieldName) {
        if (!rawValue) {
            return {};
        }
        try {
            const parsed = JSON.parse(rawValue);
            if (!parsed || Array.isArray(parsed) || typeof parsed !== 'object') {
                throw new Error(`${fieldName} must be a JSON object.`);
            }
            return parsed;
        }
        catch (error) {
            throw new Error(`Invalid ${fieldName} JSON: ${error.message}`);
        }
    }
    printJson(payload) {
        console.log(JSON.stringify(payload, null, 2));
    }
    createProjectMemory() {
        return new ProjectMemoryService(process.cwd());
    }
    buildBrainPayload(workflowId, data) {
        const memory = this.createProjectMemory();
        const prompt = [workflowId, JSON.stringify(data || {})].join(' ');
        const context = memory.buildContextForPrompt(prompt);
        const status = memory.getStatus();
        if (!context && status.itemCount === 0) {
            return undefined;
        }
        return {
            schema: 'vigthoria.project-brain.v1',
            source: 'vigthoria-cli.workflow',
            memoryDir: status.memoryDir,
            itemCount: status.itemCount,
            updatedAt: status.updatedAt,
            context,
        };
    }
    rememberWorkflowEvent(type, text) {
        try {
            this.createProjectMemory().remember(type, text, { source: 'vigflow', mode: 'workflow' });
        }
        catch {
            // Project Brain should never break workflow execution.
        }
    }
    async templates(options) {
        this.ensureAuthenticated(Boolean(options.json));
        let templates;
        try {
            templates = await this.api.listVigFlowTemplates({
                category: options.category,
                search: options.search,
            });
        }
        catch (error) {
            const raw = error.message || 'Unknown error';
            const msg = /not available|not reachable|not deployed/i.test(raw)
                ? raw
                : `Workflow service is not reachable: ${raw}`;
            if (options.json) {
                this.printJson({ success: false, error: msg, templates: [] });
            }
            else {
                this.logger.error(msg);
            }
            return;
        }
        if (options.json) {
            this.printJson({ success: true, templates });
            return;
        }
        this.logger.section('Workflow Templates');
        if (templates.length === 0) {
            console.log(chalk.yellow('No templates matched your filters.'));
            return;
        }
        this.logger.table(['ID', 'Name', 'Category', 'Tags'], templates.map((template) => [
            template.id,
            template.name,
            template.category,
            (template.tags || []).slice(0, 3).join(', '),
        ]));
    }
    async list(options) {
        this.ensureAuthenticated(Boolean(options.json));
        let workflows;
        try {
            workflows = await this.api.listVigFlowWorkflows();
        }
        catch (error) {
            const raw = error.message || 'Unknown error';
            const msg = /not available|not reachable|not deployed/i.test(raw)
                ? raw
                : `Workflow service is not reachable: ${raw}`;
            if (options.json) {
                this.printJson({ success: false, error: msg, workflows: [] });
            }
            else {
                this.logger.error(msg);
            }
            return;
        }
        if (options.json) {
            this.printJson({ success: true, workflows });
            return;
        }
        this.logger.section('Workflows');
        if (workflows.length === 0) {
            console.log(chalk.yellow('No workflows found for this account.'));
            return;
        }
        this.logger.table(['ID', 'Name', 'Nodes', 'Runs', 'Updated'], workflows.map((workflow) => [
            workflow.id,
            workflow.name,
            String(workflow.nodeCount),
            String(workflow.executionCount),
            workflow.updatedAt ? new Date(workflow.updatedAt).toLocaleString() : '-',
        ]));
    }
    async useTemplate(templateId, options) {
        this.ensureAuthenticated(Boolean(options.json));
        const variables = this.parseJsonOption(options.variables, 'variables');
        const workflow = await this.api.useVigFlowTemplate(templateId, {
            name: options.name,
            variables,
        });
        if (options.json) {
            this.printJson({ success: true, workflow });
            return;
        }
        this.logger.success(`Created workflow ${workflow.name}`);
        console.log(chalk.gray(`Workflow ID: ${workflow.id}`));
        if (workflow.fromTemplate) {
            console.log(chalk.gray(`Template: ${workflow.fromTemplate}`));
        }
    }
    async run(workflowId, options) {
        this.ensureAuthenticated(Boolean(options.json));
        const data = this.parseJsonOption(options.data, 'data');
        const executionData = { ...data };
        if (options.brain !== false) {
            const brainPayload = this.buildBrainPayload(workflowId, data);
            if (brainPayload) {
                executionData.vigthoriaBrain = brainPayload;
            }
        }
        this.rememberWorkflowEvent('task', `VigFlow workflow ${workflowId} started with Project Brain context: ${options.brain !== false ? 'enabled' : 'disabled'}.`);
        const execution = await this.api.runVigFlowWorkflow(workflowId, { data: executionData });
        this.rememberWorkflowEvent(execution.error ? 'issue' : 'validation', `VigFlow workflow ${workflowId} execution ${execution.executionId || 'unknown'} finished with status ${execution.status}; nodes executed ${execution.nodesExecuted ?? 0}${execution.error ? `; error: ${execution.error}` : ''}.`);
        if (options.json) {
            this.printJson({ success: true, execution });
            return;
        }
        this.logger.success(`Workflow execution ${execution.status}`);
        console.log(chalk.gray(`Execution ID: ${execution.executionId}`));
        console.log(chalk.gray(`Nodes executed: ${execution.nodesExecuted ?? 0}`));
        if (execution.error) {
            console.log(chalk.red(execution.error));
        }
    }
    async status(executionId, options) {
        this.ensureAuthenticated(Boolean(options.json));
        const execution = await this.api.getVigFlowExecutionStatus(executionId);
        if (options.brain !== false) {
            this.rememberWorkflowEvent(execution.status === 'failed' ? 'issue' : 'validation', `VigFlow execution ${execution.id} for workflow ${execution.workflowId} status ${execution.status}; nodes ${execution.nodesExecuted ?? 0}/${execution.totalNodes ?? '-'}.`);
        }
        if (options.json) {
            this.printJson({ success: true, execution });
            return;
        }
        this.logger.box([
            `Execution: ${execution.id}`,
            `Workflow: ${execution.workflowId}`,
            `Status: ${execution.status}`,
            `Nodes: ${execution.nodesExecuted ?? 0}/${execution.totalNodes ?? '-'}`,
            `Started: ${execution.startedAt || '-'}`,
            `Completed: ${execution.completedAt || '-'}`,
        ].join('\n'), 'Workflow Status');
    }
}
