import { v4 as uuid } from 'uuid';
import { join } from 'node:path';
import { readJsonFile, writeJsonFile, ensureDir, getDataDir } from '../storage/json-store.js';
import { existsSync, renameSync, rmSync } from 'node:fs';
import * as agentService from '../services/agent.js';
function workspaceDir(workspaceId) {
    return join(getDataDir(), 'workspaces', workspaceId);
}
function channelsPath(workspaceId) {
    return join(workspaceDir(workspaceId), 'channels', 'index.json');
}
function messagesPath(workspaceId, channelId) {
    return join(workspaceDir(workspaceId), 'channels', channelId, 'messages.json');
}
export function listChannels(workspaceId) {
    return readJsonFile(channelsPath(workspaceId)) || [];
}
export function getChannel(workspaceId, channelId) {
    return listChannels(workspaceId).find((c) => c.id === channelId);
}
export function createChannel(workspaceId, data) {
    const channels = listChannels(workspaceId);
    const requestedId = normalizeRequestedId(data.id);
    if (requestedId) {
        const existingById = channels.find((c) => c.id === requestedId);
        if (existingById)
            return { channel: existingById, created: false };
    }
    if (!data.overwrite) {
        const existing = channels.find((c) => c.name === data.name && c.type === data.type && !c.archived);
        if (existing) {
            const channel = requestedId ? migrateChannelId(workspaceId, channels, existing, requestedId) : existing;
            return { channel, created: false };
        }
    }
    const channel = {
        id: requestedId ?? uuid(),
        workspaceId,
        name: data.name,
        type: data.type,
        issueId: data.issueId,
        members: normalizeMembers(workspaceId, data.members),
        createdAt: new Date().toISOString(),
    };
    channels.push(channel);
    writeJsonFile(channelsPath(workspaceId), channels);
    ensureDir(join(workspaceDir(workspaceId), 'channels', channel.id));
    return { channel, created: true };
}
function normalizeRequestedId(id) {
    const trimmed = id?.trim();
    if (!trimmed)
        return undefined;
    return /^[A-Za-z0-9_-]+$/.test(trimmed) ? trimmed : undefined;
}
function migrateChannelId(workspaceId, channels, channel, nextId) {
    if (channel.id === nextId)
        return channel;
    if (channels.some((item) => item.id === nextId))
        return channel;
    const previousId = channel.id;
    channel.id = nextId;
    writeJsonFile(channelsPath(workspaceId), channels);
    const previousDir = join(workspaceDir(workspaceId), 'channels', previousId);
    const nextDir = join(workspaceDir(workspaceId), 'channels', nextId);
    if (existsSync(previousDir) && !existsSync(nextDir)) {
        renameSync(previousDir, nextDir);
    }
    else {
        ensureDir(nextDir);
    }
    const messages = readJsonFile(messagesPath(workspaceId, nextId));
    if (messages) {
        writeJsonFile(messagesPath(workspaceId, nextId), messages.map((message) => ({ ...message, channelId: nextId })));
    }
    return channel;
}
export function updateChannel(workspaceId, channelId, data) {
    const channels = listChannels(workspaceId);
    const idx = channels.findIndex((c) => c.id === channelId);
    if (idx === -1)
        return null;
    if (data.name !== undefined)
        channels[idx].name = data.name;
    if (data.type !== undefined)
        channels[idx].type = data.type;
    if (Object.hasOwn(data, 'issueId'))
        channels[idx].issueId = data.issueId;
    if (data.members !== undefined)
        channels[idx].members = normalizeMembers(workspaceId, data.members);
    if (Object.hasOwn(data, 'pinnedMentionId'))
        channels[idx].pinnedMentionId = data.pinnedMentionId;
    if (Object.hasOwn(data, 'draft'))
        channels[idx].draft = data.draft;
    if (Object.hasOwn(data, 'todos'))
        channels[idx].todos = data.todos;
    if (Object.hasOwn(data, 'notifyOnComplete'))
        channels[idx].notifyOnComplete = data.notifyOnComplete;
    if (Object.hasOwn(data, 'archived'))
        channels[idx].archived = data.archived;
    writeJsonFile(channelsPath(workspaceId), channels);
    return channels[idx];
}
function normalizeMembers(workspaceId, members = []) {
    const agentIds = new Set(agentService.listPresets(workspaceId).map((agent) => agent.id));
    const normalized = [];
    const seen = new Set();
    for (const member of members) {
        if (!agentIds.has(member))
            continue;
        if (seen.has(member))
            continue;
        seen.add(member);
        normalized.push(member);
    }
    return normalized;
}
export function deleteChannel(workspaceId, channelId) {
    const channels = listChannels(workspaceId);
    const idx = channels.findIndex((c) => c.id === channelId);
    if (idx === -1)
        return false;
    channels.splice(idx, 1);
    writeJsonFile(channelsPath(workspaceId), channels);
    const channelDir = join(workspaceDir(workspaceId), 'channels', channelId);
    rmSync(channelDir, { recursive: true, force: true });
    return true;
}
export function ensureGeneralChannel(workspaceId) {
    const channels = listChannels(workspaceId);
    if (!channels.some((c) => c.name === 'general')) {
        createChannel(workspaceId, { name: 'general', type: 'general', overwrite: true });
    }
}
//# sourceMappingURL=channel.js.map