import type { LearnMedia } from '../learn/types';
import type { InteractiveContentContext } from './types';

export type InteractiveContentMediaKind = 'image' | 'video' | 'caption' | 'audio' | 'file';
export type InteractiveContentEditorMedia = {
  id?: number;
  url: string;
  /** Portable value persisted in document data when the preview URL is ephemeral. */
  persistedUrl?: string;
  originalName: string;
  mimeType?: string;
  sizeBytes?: number;
  width?: number | null;
  height?: number | null;
  altText?: string;
};

export type InteractiveContentRunInput = {
  projectModeId?: string;
  language?: string;
  filename?: string;
  code: string;
  stdin?: string;
};
export type InteractiveContentRunResult = { status: string; exitCode: number; stdout: string; stderr: string };

export type InteractiveContentEditorAdapter = {
  context: InteractiveContentContext;
  runtimeDefaultLabel?: string;
  requiredLabel?: string;
  uploadMedia: (
    kind: InteractiveContentMediaKind,
    file: File,
    onProgress?: (progress: { loaded: number; total: number; percent: number }) => void,
    signal?: AbortSignal,
  ) => Promise<InteractiveContentEditorMedia>;
  populateMediaPicker?: (host: HTMLElement, kind: InteractiveContentMediaKind, onPick: (media: InteractiveContentEditorMedia) => void) => Promise<void> | void;
  /** Resolve a portable media reference (for example project-asset:assets/x.png) to a browser preview URL. */
  resolveMediaUrl?: (storedUrl: string) => string;
  runCodePreview: (input: InteractiveContentRunInput) => Promise<InteractiveContentRunResult>;
};

export function learnMediaAsInteractive(media: LearnMedia): InteractiveContentEditorMedia {
  return {
    id: media.id,
    url: media.url,
    originalName: media.originalName,
    mimeType: media.mimeType,
    sizeBytes: media.sizeBytes,
    width: media.width,
    height: media.height,
    altText: media.altText,
  };
}

export function setMediaReference(data: Record<string, unknown>, media: InteractiveContentEditorMedia, idKey = 'mediaId', urlKey = 'mediaUrl') {
  if (Number.isInteger(media.id) && Number(media.id) > 0) {
    data[idKey] = Number(media.id);
    delete data[urlKey];
  } else {
    data[urlKey] = media.persistedUrl || media.url;
    delete data[idKey];
  }
}

export function clearMediaReference(data: Record<string, unknown>, idKey = 'mediaId', urlKey = 'mediaUrl') {
  data[idKey] = 0;
  delete data[urlKey];
}

export function mediaReferenceUrl(data: Record<string, unknown>, idKey = 'mediaId', urlKey = 'mediaUrl', adapter?: InteractiveContentEditorAdapter) {
  const url = typeof data[urlKey] === 'string' ? String(data[urlKey]) : '';
  if (url) return adapter?.resolveMediaUrl?.(url) || url;
  const id = Number(data[idKey] || 0);
  return id > 0 ? `/api/learn/media/${id}` : '';
}
