import { v4 as uuid } from 'uuid';
import { listIssues, getIssue, createIssue, updateIssue, deleteIssue } from '../storage/issue-store.js';
import * as channelService from '../services/channel.js';
import * as taskService from '../services/task.js';
function ensureChannel(workspaceId, issue) {
    ensureRetryDefaults(workspaceId, issue);
    const existingChannel = issue.channelId ? channelService.getChannel(workspaceId, issue.channelId) : undefined;
    const issueMembers = issue.members || [];
    const fallbackChannelMembers = existingChannel?.members ?? [];
    const channelMembers = issueMembers.length > 0 ? issueMembers : fallbackChannelMembers;
    if (issueMembers.length === 0 && fallbackChannelMembers.length > 0) {
        issue.members = [...fallbackChannelMembers];
        updateIssue(issue);
    }
    if (issue.channelId) {
        channelService.updateChannel(workspaceId, issue.channelId, { type: 'issue', issueId: issue.id, members: channelMembers });
        return;
    }
    const { channel } = channelService.createChannel(workspaceId, {
        name: issue.title,
        type: 'issue',
        issueId: issue.id,
        members: channelMembers,
    });
    issue.channelId = channel.id;
    updateIssue(issue);
}
function ensureRetryDefaults(workspaceId, issue) {
    let changed = false;
    if (issue.retryCount === undefined) {
        issue.retryCount = 0;
        changed = true;
    }
    if (issue.maxRetries === undefined) {
        issue.maxRetries = 3;
        changed = true;
    }
    if (issue.continuousRun === undefined) {
        issue.continuousRun = true;
        changed = true;
    }
    if (changed)
        updateIssue({ ...issue, workspaceId });
}
export function list(workspaceId, status) {
    const all = listIssues(workspaceId);
    for (const issue of all)
        ensureChannel(workspaceId, issue);
    return status ? all.filter((i) => i.status === status) : all;
}
export function getById(workspaceId, issueId) {
    const issue = getIssue(workspaceId, issueId);
    if (issue)
        ensureChannel(workspaceId, issue);
    return issue;
}
export function create(workspaceId, input) {
    const now = new Date().toISOString();
    const issueId = uuid();
    const channelMembers = input.members || [];
    const { channel } = channelService.createChannel(workspaceId, {
        name: input.title,
        type: 'issue',
        issueId,
        members: channelMembers,
    });
    const issue = {
        id: issueId,
        workspaceId,
        channelId: channel.id,
        title: input.title,
        description: input.description,
        status: input.status ?? 'draft',
        tasks: [],
        members: input.members || [],
        workflowId: input.workflowId,
        continuousRun: true,
        retryCount: 0,
        maxRetries: 3,
        createdAt: now,
        updatedAt: now,
    };
    createIssue(issue);
    return issue;
}
export function createForChannel(workspaceId, channelId, input) {
    const channel = channelService.getChannel(workspaceId, channelId);
    if (!channel)
        return null;
    const now = new Date().toISOString();
    const issueId = uuid();
    const issueMembers = input.members ?? channel.members ?? [];
    const issue = {
        id: issueId,
        workspaceId,
        channelId,
        title: input.title,
        description: input.description,
        status: input.status ?? 'draft',
        tasks: [],
        members: [...issueMembers],
        continuousRun: true,
        retryCount: 0,
        maxRetries: 3,
        createdAt: now,
        updatedAt: now,
    };
    createIssue(issue);
    channelService.updateChannel(workspaceId, channelId, {
        name: input.title,
        type: 'issue',
        issueId,
        members: issueMembers,
    });
    return issue;
}
export function updateStatus(workspaceId, issueId, status, extra) {
    const issue = getIssue(workspaceId, issueId);
    if (!issue)
        return null;
    issue.status = status;
    issue.updatedAt = new Date().toISOString();
    if (extra)
        Object.assign(issue, extra);
    updateIssue(issue);
    return issue;
}
export function markError(workspaceId, issueId, error) {
    return updateStatus(workspaceId, issueId, 'error', {
        lastError: error,
    });
}
export function prepareRetry(workspaceId, issueId, options = {}) {
    const issue = getIssue(workspaceId, issueId);
    if (!issue)
        return null;
    if (options.manual) {
        issue.retryCount = 0;
        issue.retryPaused = false;
    }
    else {
        const retryCount = issue.retryCount ?? 0;
        const maxRetries = issue.maxRetries ?? 3;
        if (retryCount >= maxRetries) {
            issue.retryPaused = true;
            issue.updatedAt = new Date().toISOString();
            updateIssue(issue);
            return issue;
        }
        issue.retryCount = retryCount + 1;
    }
    issue.status = 'in_progress';
    issue.lastError = undefined;
    issue.updatedAt = new Date().toISOString();
    updateIssue(issue);
    return issue;
}
export function save(workspaceId, issue) {
    if (issue.workspaceId !== workspaceId)
        throw new Error('issue workspace mismatch');
    issue.updatedAt = new Date().toISOString();
    updateIssue(issue);
    return issue;
}
export function addTask(workspaceId, issueId, taskId) {
    const issue = getIssue(workspaceId, issueId);
    if (!issue)
        return null;
    if (!issue.tasks.includes(taskId))
        issue.tasks.push(taskId);
    issue.updatedAt = new Date().toISOString();
    updateIssue(issue);
    return issue;
}
export function replaceTasks(workspaceId, issueId, taskIds) {
    const issue = getIssue(workspaceId, issueId);
    if (!issue)
        return null;
    issue.tasks = [...new Set(taskIds.map((id) => id.trim()).filter(Boolean))];
    issue.updatedAt = new Date().toISOString();
    updateIssue(issue);
    return issue;
}
export function addAgent(workspaceId, issueId, agentId) {
    const issue = getIssue(workspaceId, issueId);
    if (!issue)
        return null;
    if (!issue.members.includes(agentId)) {
        issue.members.push(agentId);
        issue.updatedAt = new Date().toISOString();
        updateIssue(issue);
    }
    return issue;
}
export function remove(workspaceId, issueId) {
    const issue = getIssue(workspaceId, issueId);
    if (!issue)
        return false;
    // 删除关联的 tasks
    const tasks = taskService.list(workspaceId, issueId);
    for (const task of tasks) {
        taskService.remove(workspaceId, task.id);
    }
    // 删除绑定的 channel
    if (issue.channelId) {
        channelService.deleteChannel(workspaceId, issue.channelId);
    }
    deleteIssue(workspaceId, issueId);
    return true;
}
//# sourceMappingURL=issue.js.map