// tools/spec-visual-diff-handler.ts — SPEC-362: Visual Spec Diff & 3-way Merge
import * as fs from 'node:fs/promises';
import { hashProjectPath } from '../storage/base-store.js';
import { specStore } from '../storage/index.js';
import { computeVisualDiff, formatDiffText, threeWayMerge, smartMergeConflictResolver, buildMergePreview, } from '../engine/spec-diff-engine.js';
import { compactResult } from './output-formatter.js';
// eslint-disable-next-line @typescript-eslint/require-await -- sync logic, async signature required by safe() wrapper
export async function handleVisualSpecDiff(args) {
    const labelA = args.labelA ?? 'A';
    const labelB = args.labelB ?? 'B';
    const format = args.outputFormat ?? 'html';
    const result = computeVisualDiff(args.textA, args.textB, labelA, labelB);
    const summary = `Diff summary: +${String(result.added)} lines, -${String(result.removed)} lines, ` +
        `${String(result.unchanged)} unchanged (${String(result.linesA)} → ${String(result.linesB)} lines)`;
    if (format === 'html') {
        return {
            content: [
                { type: 'text', text: summary },
                { type: 'text', text: result.htmlOutput },
            ],
        };
    }
    // text format
    const text = formatDiffText(result.diffLines, labelA, labelB);
    return { content: [{ type: 'text', text: `${summary}\n\n${text}` }] };
}
// eslint-disable-next-line @typescript-eslint/require-await -- sync logic, async signature required by safe() wrapper
export async function handleThreeWayMerge(args) {
    const labelA = args.labelA ?? 'A';
    const labelB = args.labelB ?? 'B';
    const result = threeWayMerge(args.base, args.textA, args.textB, labelA, labelB);
    const status = result.hasConflicts
        ? `Merge completed with ${String(result.conflictCount)} conflict(s). Resolve manually or use \`smart_merge_conflict_resolver\`.`
        : 'Merge completed successfully with no conflicts.';
    return compactResult(JSON.stringify({
        hasConflicts: result.hasConflicts,
        conflictCount: result.conflictCount,
        mergedText: result.mergedText,
        status,
    }, null, 2));
}
// eslint-disable-next-line @typescript-eslint/require-await -- sync logic, async signature required by safe() wrapper
export async function handleSmartMergeConflictResolver(args) {
    const result = smartMergeConflictResolver(args.mergedText);
    const status = result.remainingConflicts === 0
        ? `All ${String(result.resolvedCount)} conflict(s) resolved automatically.`
        : `Resolved ${String(result.resolvedCount)} conflict(s). ${String(result.remainingConflicts)} conflict(s) require manual resolution.`;
    return compactResult(JSON.stringify({
        resolvedCount: result.resolvedCount,
        remainingConflicts: result.remainingConflicts,
        mergedText: result.mergedText,
        status,
    }, null, 2));
}
// eslint-disable-next-line @typescript-eslint/require-await -- sync logic, async signature required by safe() wrapper
export async function handleMergePreview(args) {
    const result = buildMergePreview(args.base, args.textA, args.textB);
    return compactResult(JSON.stringify({
        canAutoMerge: result.canAutoMerge,
        conflictCount: result.mergeResult.conflictCount,
        mergedText: result.mergeResult.mergedText,
        status: result.canAutoMerge
            ? 'This merge can be applied automatically.'
            : `${String(result.mergeResult.conflictCount)} conflict(s) need resolution before applying.`,
    }, null, 2));
}
export async function handleApplyMerge(args) {
    // Check for unresolved conflict markers
    if (args.mergedText.includes('<<<<<<<')) {
        return {
            content: [
                {
                    type: 'text',
                    text: 'Cannot apply merge: unresolved conflict markers found. Resolve all conflicts first.',
                },
            ],
            isError: true,
        };
    }
    const projectId = hashProjectPath(args.projectPath);
    const spec = await specStore.getSpec(projectId, args.specId);
    if (spec === null) {
        return {
            content: [
                {
                    type: 'text',
                    text: `Spec ${args.specId} not found in project at ${args.projectPath}.`,
                },
            ],
            isError: true,
        };
    }
    try {
        const specPath = spec.specPath;
        await fs.writeFile(specPath, args.mergedText, 'utf-8');
        return {
            content: [
                {
                    type: 'text',
                    text: `Merged content applied to spec ${args.specId} at ${specPath}`,
                },
            ],
        };
    }
    catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        return { content: [{ type: 'text', text: `Error applying merge: ${msg}` }], isError: true };
    }
}
//# sourceMappingURL=spec-visual-diff-handler.js.map