/**
 * Core export-tasks logic — export tasks to portable cross-project packages.
 *
 * Extracted from CLI export-tasks command for dispatch layer access.
 *
 * @task T5323, T5328
 * @epic T4545
 */
import { writeFile } from 'node:fs/promises';
import { getAccessor } from '../store/data-accessor.js';
import { buildExportPackage } from '../store/export.js';
function parseFilter(filter) {
    const eqIdx = filter.indexOf('=');
    if (eqIdx < 1)
        return null;
    return { key: filter.substring(0, eqIdx), value: filter.substring(eqIdx + 1) };
}
function applyFilters(tasks, filters) {
    let result = tasks;
    for (const filter of filters) {
        switch (filter.key) {
            case 'status': {
                const values = filter.value.split(',').map((s) => s.trim());
                result = result.filter((t) => values.includes(t.status));
                break;
            }
            case 'phase':
                result = result.filter((t) => t.phase === filter.value);
                break;
            case 'priority': {
                const values = filter.value.split(',').map((s) => s.trim());
                result = result.filter((t) => values.includes(t.priority));
                break;
            }
            case 'labels': {
                const values = filter.value.split(',').map((s) => s.trim());
                result = result.filter((t) => t.labels?.some((l) => values.includes(l)) ?? false);
                break;
            }
            case 'type': {
                const values = filter.value.split(',').map((s) => s.trim());
                result = result.filter((t) => values.includes(t.type ?? 'task'));
                break;
            }
        }
    }
    return result;
}
function collectSubtree(rootIds, allTasks) {
    const collected = new Map();
    const queue = [...rootIds];
    while (queue.length > 0) {
        const id = queue.shift();
        if (collected.has(id))
            continue;
        const task = allTasks.find((t) => t.id === id);
        if (!task)
            continue;
        collected.set(id, task);
        const children = allTasks.filter((t) => t.parentId === id);
        queue.push(...children.map((c) => c.id));
    }
    return [...collected.values()];
}
function expandDependencies(selectedIds, allTasks) {
    const expanded = new Set(selectedIds);
    const queue = [...selectedIds];
    while (queue.length > 0) {
        const id = queue.shift();
        const task = allTasks.find((t) => t.id === id);
        if (!task)
            continue;
        for (const dep of task.depends ?? []) {
            if (!expanded.has(dep)) {
                expanded.add(dep);
                queue.push(dep);
            }
        }
    }
    return allTasks.filter((t) => expanded.has(t.id));
}
/**
 * Export tasks to a portable cross-project package.
 */
export async function exportTasksPackage(params) {
    const accessor = await getAccessor(params.cwd);
    const { tasks: allTasks } = await accessor.queryTasks({});
    const subtreeMode = params.subtree ?? false;
    const includeDeps = params.includeDeps ?? false;
    const filterStrs = params.filter;
    const parsedIds = (params.taskIds ?? [])
        .flatMap((id) => id.split(',').map((s) => s.trim()))
        .filter(Boolean);
    const filters = [];
    if (filterStrs) {
        for (const f of filterStrs) {
            const parsed = parseFilter(f);
            if (parsed)
                filters.push(parsed);
        }
    }
    let selectedTasks;
    let exportMode;
    if (parsedIds.length > 0) {
        for (const id of parsedIds) {
            if (!allTasks.find((t) => t.id === id)) {
                throw new Error(`Task not found: ${id}`);
            }
        }
        if (subtreeMode) {
            exportMode = 'subtree';
            selectedTasks = collectSubtree(parsedIds, allTasks);
        }
        else {
            exportMode = 'single';
            selectedTasks = allTasks.filter((t) => parsedIds.includes(t.id));
        }
    }
    else if (filters.length > 0) {
        exportMode = 'filter';
        selectedTasks = applyFilters(allTasks, filters);
        if (subtreeMode) {
            const rootIds = selectedTasks.map((t) => t.id);
            selectedTasks = collectSubtree(rootIds, allTasks);
        }
    }
    else {
        exportMode = 'full';
        selectedTasks = allTasks;
    }
    if (includeDeps && selectedTasks.length > 0) {
        const selectedIds = new Set(selectedTasks.map((t) => t.id));
        selectedTasks = expandDependencies(selectedIds, allTasks);
    }
    if (selectedTasks.length === 0) {
        throw new Error('No tasks match selection criteria');
    }
    if (params.dryRun) {
        return {
            dryRun: true,
            exportMode,
            taskCount: selectedTasks.length,
            taskIds: selectedTasks.map((t) => t.id),
        };
    }
    const projectMeta = await accessor.getMetaValue('project');
    const pkg = buildExportPackage(selectedTasks, {
        mode: exportMode,
        rootTaskIds: parsedIds.length > 0 ? parsedIds : selectedTasks.map((t) => t.id),
        includeChildren: subtreeMode,
        filters: filters.length > 0 ? filters : undefined,
        projectName: projectMeta?.name,
    });
    const content = JSON.stringify(pkg, null, 2);
    if (params.output) {
        await writeFile(params.output, content);
        return {
            exportMode,
            taskCount: selectedTasks.length,
            taskIds: selectedTasks.map((t) => t.id),
            outputPath: params.output,
        };
    }
    return {
        exportMode,
        taskCount: selectedTasks.length,
        taskIds: selectedTasks.map((t) => t.id),
        content,
    };
}
//# sourceMappingURL=export-tasks.js.map