import { ref } from 'vue';

export interface Attachment {
    file: File;
    preview: string;
    base64: string;
    mimeType: string;
    fileName: string;
}

export interface AttachmentPayload {
    type: string;
    mimeType: string;
    content: string;
    fileName: string;
}

const ACCEPTED_TYPES = [
    'image/jpeg', 'image/png', 'image/gif', 'image/webp',
    'application/pdf',
    'audio/webm', 'audio/mp4', 'audio/ogg', 'audio/mpeg', 'audio/wav', 'audio/x-m4a',
];
const MAX_BYTES = 10 * 1024 * 1024; // 10MB

function readAsBase64(file: File): Promise<string> {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => {
            const result = reader.result as string;
            // Strip data URL prefix: "data:image/png;base64,..."
            const idx = result.indexOf(',');
            resolve(idx >= 0 ? result.slice(idx + 1) : result);
        };
        reader.onerror = () => reject(reader.error);
        reader.readAsDataURL(file);
    });
}

export function useAttachments() {
    const attachments = ref<Attachment[]>([]);

    async function addFiles(files: FileList | File[]) {
        for (const file of Array.from(files)) {
            // Exact match for non-audio, prefix match for audio (Chrome adds codecs like "audio/webm;codecs=opus")
            const baseType = file.type.split(';')[0];
            if (!ACCEPTED_TYPES.includes(baseType) && !ACCEPTED_TYPES.includes(file.type)) {
                console.warn(`[attachments] skipped ${file.name}: unsupported type ${file.type}`);
                continue;
            }
            if (file.size > MAX_BYTES) {
                console.warn(`[attachments] skipped ${file.name}: exceeds 5MB (${(file.size / 1024 / 1024).toFixed(1)}MB)`);
                continue;
            }
            const base64 = await readAsBase64(file);
            const preview = URL.createObjectURL(file);
            attachments.value.push({ file, preview, base64, mimeType: file.type, fileName: file.name });
        }
    }

    function removeAttachment(index: number) {
        const att = attachments.value[index];
        if (att) URL.revokeObjectURL(att.preview);
        attachments.value.splice(index, 1);
    }

    function clearAttachments() {
        for (const att of attachments.value) URL.revokeObjectURL(att.preview);
        attachments.value = [];
    }

    function toPayload(): AttachmentPayload[] {
        return attachments.value.map(a => ({
            type: a.mimeType.startsWith('image/') ? 'image'
                : a.mimeType.startsWith('audio/') ? 'audio'
                : 'document',
            mimeType: a.mimeType,
            content: a.base64,
            fileName: a.fileName,
        }));
    }

    function hasAttachments(): boolean {
        return attachments.value.length > 0;
    }

    return { attachments, addFiles, removeAttachment, clearAttachments, toPayload, hasAttachments };
}
