/**
 * `File → ChatAttachment` — the engine-side producer that was missing.
 *
 * Before this, every host re-implemented the conversion (see the fake
 * stub in `apps/storybook/.../SpeechAndAttachments`). It lives here so
 * the picker, drag-drop and paste paths all mint identical attachments.
 */

import { createId } from '../core/ids';
import { getAssetTypeFromMime } from '../../forms/Uploader';
import type { ChatAttachment } from '../types';

/** Map a MIME type to the `ChatAttachment.type` discriminant. */
function attachmentTypeFromMime(mime: string): ChatAttachment['type'] {
  if (mime.startsWith('image/')) return 'image';
  if (mime.startsWith('audio/')) return 'audio';
  if (mime.startsWith('video/')) return 'video';
  // getAssetTypeFromMime returns 'document' for everything else; the
  // ChatAttachment union has no 'document' member — collapse to 'file'.
  const asset = getAssetTypeFromMime(mime);
  return asset === 'document' ? 'file' : asset;
}

/**
 * Convert a picked/dropped/pasted `File` into a `ChatAttachment`.
 *
 * The `url` is an object-URL (`URL.createObjectURL`) — instantly usable
 * for previews. When a host uploads the file via `uploadFn`, it replaces
 * `url` with the remote URL and flips `status` to `'ready'`.
 *
 * `status` defaults to `'ready'`: with no `uploadFn` the attachment is
 * immediately usable (current behaviour). The attach pipeline overrides
 * it to `'uploading'` when an upload is in flight.
 */
export function fileToAttachment(file: File): ChatAttachment {
  const mime = file.type || 'application/octet-stream';
  return {
    id: createId('att'),
    type: attachmentTypeFromMime(mime),
    url: URL.createObjectURL(file),
    name: file.name,
    mimeType: mime,
    sizeBytes: file.size,
    status: 'ready',
  };
}

/** Revoke an attachment's object-URL, if it holds one. Call on remove. */
export function revokeAttachmentUrl(attachment: Pick<ChatAttachment, 'url'>): void {
  if (attachment.url.startsWith('blob:')) {
    URL.revokeObjectURL(attachment.url);
  }
}
