import type { BuiltInExportPreset } from './preset.types';

function immutable<T extends BuiltInExportPreset>(preset: T): Readonly<T> {
  return Object.freeze({
    ...preset,
    requirements: Object.freeze({
      ...preset.requirements,
      ...(preset.requirements.muxers
        ? { muxers: Object.freeze([...preset.requirements.muxers]) }
        : {}),
      ...(preset.requirements.encoders
        ? { encoders: Object.freeze([...preset.requirements.encoders]) }
        : {}),
      ...(preset.requirements.filters
        ? { filters: Object.freeze([...preset.requirements.filters]) }
        : {}),
    }),
    ...(preset.video ? { video: Object.freeze({ ...preset.video }) } : {}),
    ...(preset.audio ? { audio: Object.freeze({ ...preset.audio }) } : {}),
    settingsSummary: Object.freeze([...preset.settingsSummary]),
  });
}

export const VIDEO_PRESETS: readonly BuiltInExportPreset[] = Object.freeze([
  immutable({
    id: 'mp4-h264-balanced',
    name: 'MP4 · H.264 + AAC',
    description: 'Balanced browser-friendly video.',
    kind: 'video',
    container: 'mp4',
    fileExtension: 'mp4',
    video: {
      codec: 'libx264',
      qualityMode: 'balanced',
      crf: 23,
      pixelFormat: 'yuv420p',
      encoderPreset: 'medium',
    },
    audio: { codec: 'aac', bitrateKbps: 160, sampleRate: 48_000, channels: 2 },
    fastStart: true,
    metadataPolicy: 'copy',
    chapterPolicy: 'keep',
    subtitlePolicy: 'convert',
    requirements: {
      muxers: ['mp4'],
      encoders: ['libx264', 'aac'],
    },
    settingsSummary: [
      'libx264 CRF 23, medium preset',
      'yuv420p pixel format',
      'AAC 160 kbit/s stereo at 48 kHz',
      'fast-start metadata',
    ],
    builtIn: true,
  }),
  immutable({
    id: 'mp4-h264-compatibility',
    name: 'MP4 · H.264 compatibility',
    description: 'Conservative settings for broad playback support.',
    kind: 'video',
    container: 'mp4',
    fileExtension: 'mp4',
    video: {
      codec: 'libx264',
      qualityMode: 'compatibility',
      crf: 24,
      pixelFormat: 'yuv420p',
      encoderPreset: 'fast',
    },
    audio: { codec: 'aac', bitrateKbps: 128, sampleRate: 44_100, channels: 2 },
    fastStart: true,
    metadataPolicy: 'copy',
    chapterPolicy: 'keep',
    subtitlePolicy: 'convert',
    requirements: { muxers: ['mp4'], encoders: ['libx264', 'aac'] },
    settingsSummary: [
      'libx264 CRF 24, fast preset',
      'yuv420p pixel format',
      'AAC 128 kbit/s stereo at 44.1 kHz',
    ],
    builtIn: true,
  }),
  immutable({
    id: 'webm-vp9-opus',
    name: 'WebM · VP9 + Opus',
    description: 'Efficient open web video when both encoders are available.',
    kind: 'video',
    container: 'webm',
    fileExtension: 'webm',
    video: {
      codec: 'libvpx-vp9',
      qualityMode: 'smaller-file',
      crf: 32,
      bitrateKbps: 0,
      pixelFormat: 'yuv420p',
    },
    audio: {
      codec: 'libopus',
      bitrateKbps: 128,
      sampleRate: 48_000,
      channels: 2,
    },
    metadataPolicy: 'copy',
    chapterPolicy: 'keep',
    subtitlePolicy: 'convert',
    requirements: {
      muxers: ['webm'],
      encoders: ['libvpx-vp9', 'libopus'],
    },
    settingsSummary: ['libvpx-vp9 CRF 32', 'Opus 128 kbit/s stereo at 48 kHz'],
    builtIn: true,
  }),
  immutable({
    id: 'webm-vp8-vorbis',
    name: 'WebM · VP8 + Vorbis',
    description: 'Compatibility-oriented open web video.',
    kind: 'video',
    container: 'webm',
    fileExtension: 'webm',
    video: {
      codec: 'libvpx',
      qualityMode: 'compatibility',
      crf: 18,
      bitrateKbps: 1_500,
      pixelFormat: 'yuv420p',
    },
    audio: {
      codec: 'libvorbis',
      bitrateKbps: 128,
      sampleRate: 48_000,
      channels: 2,
    },
    metadataPolicy: 'copy',
    chapterPolicy: 'keep',
    subtitlePolicy: 'convert',
    requirements: { muxers: ['webm'], encoders: ['libvpx', 'libvorbis'] },
    settingsSummary: ['libvpx CRF 18, 1.5 Mbit/s target', 'Vorbis 128 kbit/s'],
    builtIn: true,
  }),
  immutable({
    id: 'animated-webp',
    name: 'Animated WebP',
    description: 'Animated image derivative without audio.',
    kind: 'derivative',
    container: 'webp',
    fileExtension: 'webp',
    video: {
      codec: 'libwebp_anim',
      qualityMode: 'balanced',
      crf: 60,
      pixelFormat: 'rgba',
    },
    metadataPolicy: 'remove',
    chapterPolicy: 'remove',
    subtitlePolicy: 'none',
    requirements: { muxers: ['webp'], encoders: ['libwebp_anim'] },
    settingsSummary: ['libwebp_anim quality 60', 'audio omitted'],
    builtIn: true,
  }),
  immutable({
    id: 'animated-gif',
    name: 'Animated GIF',
    description: 'Advanced compatibility derivative with limited colours.',
    kind: 'derivative',
    container: 'gif',
    fileExtension: 'gif',
    video: { codec: 'gif', qualityMode: 'compatibility' },
    metadataPolicy: 'remove',
    chapterPolicy: 'remove',
    subtitlePolicy: 'none',
    requirements: {
      muxers: ['gif'],
      encoders: ['gif'],
      filters: ['palettegen', 'paletteuse'],
    },
    settingsSummary: ['palettegen/paletteuse filter workflow', 'audio omitted'],
    builtIn: true,
  }),
  immutable({
    id: 'matroska-h264-aac',
    name: 'Matroska · H.264 + AAC',
    description: 'Flexible Matroska output with selected compatible streams.',
    kind: 'video',
    container: 'matroska',
    fileExtension: 'mkv',
    video: {
      codec: 'libx264',
      qualityMode: 'higher-quality',
      crf: 20,
      pixelFormat: 'yuv420p',
      encoderPreset: 'medium',
    },
    audio: { codec: 'aac', bitrateKbps: 192, sampleRate: 48_000, channels: 2 },
    metadataPolicy: 'copy',
    chapterPolicy: 'keep',
    subtitlePolicy: 'copy-compatible',
    requirements: { muxers: ['matroska'], encoders: ['libx264', 'aac'] },
    settingsSummary: ['libx264 CRF 20', 'AAC 192 kbit/s', 'Matroska container'],
    builtIn: true,
  }),
]);
