/**
 * Attachments Store - manages user attachments through Context.
 *
 * Attachments are persisted through Context.setAttachments() which ensures
 * they are included in Context serialization (toRecord/fromRecord).
 */
import { classifyAttachmentDelivery } from "@superblocksteam/shared";
import { getLogger } from "../../util/logger.js";
const isUploadedAttachment = (attachment) => {
    const candidate = attachment;
    return (candidate.type === "uploaded" &&
        typeof candidate.url === "string" &&
        typeof candidate.mediaType === "string");
};
/** Maximum length for the original message stored with attachments */
const MAX_MESSAGE_LENGTH = 300;
/**
 * Truncates a message to the max length, adding [...] if truncated.
 */
function truncateMessage(message) {
    if (!message)
        return undefined;
    const trimmed = message.trim();
    if (trimmed.length <= MAX_MESSAGE_LENGTH)
        return trimmed;
    return trimmed.slice(0, MAX_MESSAGE_LENGTH) + "[...]";
}
export class AttachmentsStore {
    getAttachments(context) {
        return (context.getAttachments() ?? {
            nextId: 1,
            attachments: [],
        });
    }
    appendAttachments(context, attachments, originalMessage) {
        if (attachments.length === 0) {
            return [];
        }
        const data = this.getAttachments(context);
        const now = Date.now();
        const truncatedMessage = truncateMessage(originalMessage);
        const newAttachments = [];
        for (const attachment of attachments) {
            const baseFields = {
                id: data.nextId++,
                fileName: attachment.fileName,
                label: attachment.label,
                insight: attachment.insight,
                originalMessage: truncatedMessage,
                createdAt: now,
                updatedAt: now,
            };
            let stored;
            if (attachment.type === "image") {
                stored = {
                    ...baseFields,
                    type: "image",
                    imageDataUrl: attachment.image,
                };
            }
            else if (attachment.type === "pdf") {
                stored = {
                    ...baseFields,
                    type: "pdf",
                    data: attachment.data,
                    size: attachment.size,
                };
            }
            else if (attachment.type === "archive") {
                stored = {
                    ...baseFields,
                    type: "archive",
                    data: attachment.data,
                    size: attachment.size,
                };
            }
            else if (attachment.type === "csv" ||
                attachment.type === "json" ||
                attachment.type === "yaml" ||
                attachment.type === "css" ||
                attachment.type === "txt") {
                stored = {
                    ...baseFields,
                    type: attachment.type,
                    content: attachment.content,
                    mimeType: attachment.mimeType,
                    size: attachment.size,
                };
            }
            else if (isUploadedAttachment(attachment)) {
                stored = {
                    ...baseFields,
                    type: "uploaded",
                    url: attachment.url,
                    signedUrl: attachment.signedUrl,
                    mediaType: attachment.mediaType,
                    storageKey: attachment.storageKey,
                    signedUrlExpiresAt: attachment.signedUrlExpiresAt,
                    scopeType: attachment.scopeType,
                    applicationId: attachment.applicationId,
                };
            }
            else {
                getLogger().warn(`[attachments-store] Skipping unknown attachment type: ${attachment.type}`);
                continue;
            }
            data.attachments.push(stored);
            newAttachments.push(stored);
        }
        context.setAttachments(data);
        getLogger().info(`[attachments-store] Persisted ${newAttachments.length} attachment(s)`, newAttachments.map((a) => ({
            id: a.id,
            type: a.type,
            fileName: a.fileName,
            label: a.label,
            insight: a.insight,
            originalMessage: a.originalMessage,
        })));
        return newAttachments;
    }
    listAttachments(context, options) {
        const data = this.getAttachments(context);
        const mediaTypeFilter = options?.mediaType?.trim().toLowerCase();
        const scopeTypeFilter = options?.scopeType;
        return data.attachments
            .map((a) => {
            const mediaType = this.getAttachmentMediaType(a);
            const classification = classifyAttachmentDelivery({
                fileName: a.fileName,
                mimeType: mediaType,
            });
            return {
                id: a.id,
                classification,
                type: a.type,
                fileName: a.fileName,
                label: a.label,
                insight: a.insight,
                mediaType,
                originalMessage: a.originalMessage,
                scopeType: a.type === "uploaded" ? a.scopeType : undefined,
                storageKey: a.type === "uploaded" ? a.storageKey : undefined,
            };
        })
            .filter((a) => {
            if (scopeTypeFilter && a.scopeType !== scopeTypeFilter) {
                return false;
            }
            if (mediaTypeFilter && a.mediaType.toLowerCase() !== mediaTypeFilter) {
                return false;
            }
            return true;
        });
    }
    getAttachmentMediaType(attachment) {
        if (attachment.type === "uploaded") {
            return attachment.mediaType;
        }
        if (attachment.type === "image") {
            return "image/*";
        }
        if (attachment.type === "pdf") {
            return "application/pdf";
        }
        if (attachment.type === "archive") {
            const match = attachment.data.match(/^data:([^;]+);base64,/);
            return match?.[1] ?? "application/octet-stream";
        }
        if (attachment.type === "csv") {
            return "text/csv";
        }
        if (attachment.type === "json") {
            return "application/json";
        }
        if (attachment.type === "yaml") {
            return "text/yaml";
        }
        if (attachment.type === "css") {
            return "text/css";
        }
        return "text/plain";
    }
    getAttachmentsByIds(context, ids) {
        const data = this.getAttachments(context);
        const idSet = new Set(ids);
        const found = [];
        const foundIds = new Set();
        for (const attachment of data.attachments) {
            if (idSet.has(attachment.id)) {
                found.push(attachment);
                foundIds.add(attachment.id);
            }
        }
        // Log any missing IDs
        const missingIds = ids.filter((id) => !foundIds.has(id));
        if (missingIds.length > 0) {
            getLogger().warn(`[attachments-store] Requested attachment IDs not found: ${missingIds.join(", ")}`);
        }
        return found;
    }
    getUploadedAttachmentsByStorageKeys(context, storageKeys) {
        const data = this.getAttachments(context);
        const normalizedInput = new Set(storageKeys
            .map((storageKey) => storageKey.trim())
            .filter((storageKey) => storageKey.length > 0));
        const found = [];
        const foundKeys = new Set();
        for (const attachment of data.attachments) {
            if (attachment.type !== "uploaded" || !attachment.storageKey) {
                continue;
            }
            const normalizedStorageKey = attachment.storageKey.trim();
            if (normalizedInput.has(normalizedStorageKey)) {
                found.push(attachment);
                foundKeys.add(normalizedStorageKey);
            }
        }
        const missingStorageKeys = Array.from(normalizedInput).filter((storageKey) => !foundKeys.has(storageKey));
        if (missingStorageKeys.length > 0) {
            getLogger().warn(`[attachments-store] Requested attachment storage keys not found: ${missingStorageKeys.join(", ")}`);
        }
        return found;
    }
    static toAttachments(stored) {
        return stored.map((s) => {
            if (s.type === "image") {
                return {
                    type: "image",
                    image: s.imageDataUrl,
                    fileName: s.fileName ?? "image.png",
                    label: s.label,
                    insight: s.insight,
                };
            }
            else if (s.type === "pdf") {
                return {
                    type: "pdf",
                    data: s.data,
                    fileName: s.fileName ?? "document.pdf",
                    size: s.size,
                    label: s.label,
                    insight: s.insight,
                };
            }
            else if (s.type === "archive") {
                return {
                    type: "archive",
                    data: s.data,
                    fileName: s.fileName ?? "archive.zip",
                    size: s.size,
                    label: s.label,
                    insight: s.insight,
                };
            }
            else if (s.type === "uploaded") {
                return {
                    type: "uploaded",
                    url: s.url,
                    signedUrl: s.signedUrl,
                    mediaType: s.mediaType,
                    fileName: s.fileName ?? "attachment",
                    label: s.label,
                    insight: s.insight,
                    storageKey: s.storageKey,
                    signedUrlExpiresAt: s.signedUrlExpiresAt,
                    scopeType: s.scopeType,
                    applicationId: s.applicationId,
                };
            }
            else {
                // Text attachments: csv, json, yaml, css, txt
                return {
                    type: s.type,
                    content: s.content,
                    fileName: s.fileName ?? `file.${s.type}`,
                    mimeType: s.mimeType,
                    size: s.size,
                    label: s.label,
                    insight: s.insight,
                };
            }
        });
    }
}
//# sourceMappingURL=store.js.map