import { randomUUID } from 'node:crypto';
import { getDataDir, ensureDir, readJsonFile, writeJsonFile, deleteFile } from './json-store.js';
import path from 'node:path';
import { existsSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
function chatDir() {
    return path.join(getDataDir(), 'chat');
}
function chatTemplatesDir() {
    return path.join(getDataDir(), 'chat-templates');
}
export function agentDir(agentId) {
    return path.join(chatTemplatesDir(), agentId);
}
function agentFile(agentId) {
    return path.join(agentDir(agentId), 'agent.json');
}
function mcpFile(agentId) {
    return path.join(agentDir(agentId), 'mcp.json');
}
function skillsDir(agentId) {
    return path.join(agentDir(agentId), 'skills');
}
export function chatSessionDir(chatId) {
    return path.join(chatDir(), chatId);
}
export function chatWorkspaceDir(chatId) {
    return path.join(chatSessionDir(chatId), 'workspaces');
}
function chatWorkspaceSkillsDir(chatId) {
    return path.join(chatWorkspaceDir(chatId), 'skills');
}
export function messageHistoryDir(agentId) {
    return chatSessionDir(agentId);
}
function messagesFile(chatId) {
    return path.join(chatSessionDir(chatId), 'messages.json');
}
// --- Agent functions ---
export function listAgents() {
    ensureDir(chatTemplatesDir());
    return readdirSync(chatTemplatesDir(), { withFileTypes: true })
        .filter(entry => entry.isDirectory())
        .flatMap(entry => {
        const agent = readJsonFile(agentFile(entry.name));
        return agent ? [agent] : [];
    })
        .sort((a, b) => a.createdAt.localeCompare(b.createdAt));
}
export function saveAgent(agent, skillInputs) {
    const dir = agentDir(agent.id);
    ensureDir(dir);
    ensureDir(skillsDir(agent.id));
    ensureDir(chatWorkspaceDir(agent.id));
    ensureDir(chatWorkspaceSkillsDir(agent.id));
    const storedAgent = toStoredChatAgent(agent);
    writeJsonFile(agentFile(agent.id), storedAgent);
    writeJsonFile(mcpFile(agent.id), storedAgent.mcps ?? {});
    writeSkills(agent.id, skillInputs, agent.skills ?? []);
}
export function findAgent(id) {
    return readJsonFile(agentFile(id)) ?? undefined;
}
function toStoredChatAgent(agent) {
    const { apiKey: _apiKey, baseURL: _baseURL, apiBase: _apiBase, provider: _provider, ...stored } = agent;
    void _apiKey;
    void _baseURL;
    void _apiBase;
    void _provider;
    return stored;
}
export function deleteAgent(id) {
    rmSync(agentDir(id), { recursive: true, force: true });
    rmSync(chatSessionDir(id), { recursive: true, force: true });
}
// --- Message functions ---
export function listMessages(agentId, limit, before) {
    ensureDir(chatSessionDir(agentId));
    let messages = readJsonFile(messagesFile(agentId)) ?? [];
    messages = messages.filter(msg => msg.agentId === agentId);
    // Sort descending by timestamp
    messages.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
    // Cursor pagination: skip messages at or after 'before' timestamp
    if (before) {
        const idx = messages.findIndex(m => m.timestamp <= before);
        if (idx === -1) {
            messages = [];
        }
        else {
            messages = messages.slice(idx);
        }
    }
    // Apply limit
    if (limit && limit > 0) {
        messages = messages.slice(0, limit);
    }
    // Return ascending order
    messages.reverse();
    return messages;
}
export function saveMessage(msg) {
    const messages = readJsonFile(messagesFile(msg.agentId)) ?? [];
    messages.push(msg);
    writeJsonFile(messagesFile(msg.agentId), messages);
}
export function deleteMessagesByAgent(agentId) {
    deleteFile(messagesFile(agentId));
}
export function getRecentMessages(agentId, limit = 50) {
    return listMessages(agentId, limit);
}
function writeSkills(agentId, skillInputs, skillNames) {
    const dir = skillsDir(agentId);
    if (skillInputs?.some(skill => typeof skill !== 'string')) {
        rmSync(dir, { recursive: true, force: true });
        ensureDir(dir);
        for (const skill of skillInputs) {
            if (typeof skill === 'string' || !skill.name.trim())
                continue;
            const filename = sanitizeMarkdownFilename(skill.name);
            const content = skill.content ?? readSkillContent(skill.name) ?? '';
            writeJsonSkillFile(path.join(dir, filename), content);
            writeJsonSkillFile(path.join(chatWorkspaceSkillsDir(agentId), filename), content);
        }
        return;
    }
    for (const name of skillNames.map(skill => typeof skill === 'string' ? skill : skill.name)) {
        const filename = sanitizeMarkdownFilename(name);
        const content = readSkillContent(name) ?? '';
        const filePath = path.join(dir, filename);
        if (content || !existsSync(filePath))
            writeJsonSkillFile(filePath, content);
        const workspaceSkillPath = path.join(chatWorkspaceSkillsDir(agentId), filename);
        if (content || !existsSync(workspaceSkillPath))
            writeJsonSkillFile(workspaceSkillPath, content);
    }
}
function writeJsonSkillFile(filePath, content) {
    ensureDir(path.dirname(filePath));
    writeFileSync(filePath, content, 'utf-8');
}
function sanitizeMarkdownFilename(name) {
    const base = name.trim().replace(/[/\\:*?"<>|]+/g, '-');
    return base.toLowerCase().endsWith('.md') ? base : `${base}.md`;
}
function readSkillContent(name) {
    const skillName = name.trim().replace(/\.md$/i, '');
    if (!skillName)
        return undefined;
    const candidates = [
        path.join(getDataDir(), 'skills', skillName, 'SKILL.md'),
        path.join(getDataDir(), 'skills', `${skillName}.md`),
        path.join(process.cwd(), 'skills', skillName, 'SKILL.md'),
        path.join(process.cwd(), 'skills', `${skillName}.md`),
    ];
    const source = candidates.find(file => existsSync(file));
    if (!source)
        return undefined;
    const content = readFileSync(source, 'utf-8');
    return content.trim() ? content : undefined;
}
// --- Workspace functions ---
function workspacesFile() {
    return path.join(chatDir(), 'workspaces.json');
}
function workspaceDir(wsId) {
    return path.join(chatDir(), 'workspaces', wsId);
}
function workspaceStateFile(wsId) {
    return path.join(workspaceDir(wsId), 'state.json');
}
function sessionsFile(wsId) {
    return path.join(workspaceDir(wsId), 'sessions.json');
}
function sessionDir(wsId, sessionId) {
    return path.join(workspaceDir(wsId), 'sessions', sessionId);
}
function sessionMessagesFile(wsId, sessionId) {
    return path.join(sessionDir(wsId, sessionId), 'messages.json');
}
export function listWorkspaces() {
    ensureDir(chatDir());
    return readJsonFile(workspacesFile()) ?? [];
}
function saveWorkspaces(workspaces) {
    writeJsonFile(workspacesFile(), workspaces);
}
export function findWorkspace(id) {
    return listWorkspaces().find(ws => ws.id === id);
}
export function createWorkspace(data) {
    const workspaces = listWorkspaces();
    const ws = {
        id: randomUUID(),
        name: data.name,
        agentIds: data.agentIds ?? [],
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
    };
    workspaces.push(ws);
    saveWorkspaces(workspaces);
    ensureDir(workspaceDir(ws.id));
    return ws;
}
export function updateWorkspace(id, data) {
    const workspaces = listWorkspaces();
    const idx = workspaces.findIndex(ws => ws.id === id);
    if (idx === -1)
        return null;
    workspaces[idx] = {
        ...workspaces[idx],
        ...(data.name !== undefined && { name: data.name }),
        ...(data.agentIds !== undefined && { agentIds: data.agentIds }),
        updatedAt: new Date().toISOString(),
    };
    saveWorkspaces(workspaces);
    return workspaces[idx];
}
export function deleteWorkspace(id) {
    const workspaces = listWorkspaces();
    const idx = workspaces.findIndex(ws => ws.id === id);
    if (idx === -1)
        return false;
    workspaces.splice(idx, 1);
    saveWorkspaces(workspaces);
    rmSync(workspaceDir(id), { recursive: true, force: true });
    return true;
}
// --- Session functions ---
export function listSessions(workspaceId) {
    const sessions = readJsonFile(sessionsFile(workspaceId)) ?? [];
    return sessions.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
}
export function findSession(workspaceId, sessionId) {
    return listSessions(workspaceId).find(s => s.id === sessionId);
}
export function createSession(workspaceId, agentId) {
    if (!findWorkspace(workspaceId))
        return null;
    if (!findAgent(agentId))
        return null;
    const sessions = readJsonFile(sessionsFile(workspaceId)) ?? [];
    const session = {
        id: randomUUID(),
        workspaceId,
        agentId,
        title: undefined,
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
    };
    sessions.push(session);
    writeJsonFile(sessionsFile(workspaceId), sessions);
    ensureDir(sessionDir(workspaceId, session.id));
    return session;
}
export function updateSession(workspaceId, sessionId, data) {
    const sessions = readJsonFile(sessionsFile(workspaceId)) ?? [];
    const idx = sessions.findIndex(s => s.id === sessionId);
    if (idx === -1)
        return null;
    sessions[idx] = {
        ...sessions[idx],
        ...(data.title !== undefined && { title: data.title }),
        ...(data.archived !== undefined && { archived: data.archived }),
        updatedAt: new Date().toISOString(),
    };
    writeJsonFile(sessionsFile(workspaceId), sessions);
    return sessions[idx];
}
export function deleteSession(workspaceId, sessionId) {
    const sessions = readJsonFile(sessionsFile(workspaceId)) ?? [];
    const idx = sessions.findIndex(s => s.id === sessionId);
    if (idx === -1)
        return false;
    sessions.splice(idx, 1);
    writeJsonFile(sessionsFile(workspaceId), sessions);
    rmSync(sessionDir(workspaceId, sessionId), { recursive: true, force: true });
    return true;
}
// --- Session Message functions ---
export function listSessionMessages(workspaceId, sessionId) {
    const messages = readJsonFile(sessionMessagesFile(workspaceId, sessionId)) ?? [];
    messages.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
    return messages;
}
export function saveSessionMessage(workspaceId, sessionId, msg) {
    const messages = readJsonFile(sessionMessagesFile(workspaceId, sessionId)) ?? [];
    messages.push(msg);
    writeJsonFile(sessionMessagesFile(workspaceId, sessionId), messages);
}
export function clearSessionMessages(workspaceId, sessionId) {
    deleteFile(sessionMessagesFile(workspaceId, sessionId));
}
export function getRecentSessionMessages(workspaceId, sessionId, limit = 50) {
    const messages = listSessionMessages(workspaceId, sessionId);
    return messages.slice(-limit);
}
export function getWorkspaceState(wsId) {
    const state = readJsonFile(workspaceStateFile(wsId));
    return state ?? { openSessionTabIds: [], openFileTabs: [], activeTab: null };
}
export function saveWorkspaceState(wsId, state) {
    ensureDir(workspaceDir(wsId));
    writeJsonFile(workspaceStateFile(wsId), state);
}
// --- Migration ---
export function migrateToWorkspaces() {
    ensureDir(chatDir());
    const existing = readJsonFile(workspacesFile());
    if (existing && existing.length > 0)
        return;
    const agents = listAgents();
    const ws = {
        id: randomUUID(),
        name: 'Default',
        agentIds: agents.map(a => a.id),
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
    };
    saveWorkspaces([ws]);
    ensureDir(workspaceDir(ws.id));
    for (const agent of agents) {
        const oldMessages = readJsonFile(messagesFile(agent.id)) ?? [];
        if (oldMessages.length === 0)
            continue;
        const session = {
            id: randomUUID(),
            workspaceId: ws.id,
            agentId: agent.id,
            title: undefined,
            createdAt: oldMessages[0].timestamp,
            updatedAt: oldMessages[oldMessages.length - 1].timestamp,
        };
        const sessions = readJsonFile(sessionsFile(ws.id)) ?? [];
        sessions.push(session);
        writeJsonFile(sessionsFile(ws.id), sessions);
        ensureDir(sessionDir(ws.id, session.id));
        writeJsonFile(sessionMessagesFile(ws.id, session.id), oldMessages);
    }
}
//# sourceMappingURL=chat-store.js.map