export type Modality = "image" | "video" | "audio" | "document" | "file";

export interface ModalityInfo {
  id: Modality;
  name: string;
  icon: string; // lucide icon name, same convention as CategoryInfo
  color: string;
}

// Five modality values in code, surfaced as five UI sections:
// Image, Video, Audio, PDF ("document" id) and Files ("file" id).
export const MODALITIES: ModalityInfo[] = [
  { id: "image", name: "Image", icon: "Image", color: "#3B82F6" },
  { id: "video", name: "Video", icon: "Video", color: "#EF4444" },
  { id: "audio", name: "Audio", icon: "AudioLines", color: "#10B981" },
  { id: "document", name: "PDF", icon: "FileText", color: "#8B5CF6" },
  { id: "file", name: "Files", icon: "FileArchive", color: "#F59E0B" },
];

// Which BullMQ pool a modality's tools run on. AI tools override to "ai"
// at enqueue time regardless of modality.
export const MODALITY_POOL: Record<Modality, "image" | "media" | "docs"> = {
  image: "image",
  video: "media",
  audio: "media",
  document: "docs",
  file: "docs",
};

// Default accepted input extensions per modality (with dots; drives the
// file picker accept attribute and docs). Tools may narrow this.
export const IMAGE_INPUTS = [
  ".jpg",
  ".jpeg",
  ".png",
  ".webp",
  ".gif",
  ".bmp",
  ".tiff",
  ".tif",
  ".avif",
  ".heic",
  ".heif",
  ".svg",
  ".svgz",
  ".ico",
  ".jxl",
  ".jp2",
  ".psd",
  ".tga",
  ".exr",
  ".hdr",
  ".dng",
  ".cr2",
  ".nef",
  ".arw",
  ".orf",
  ".rw2",
  ".ppm",
  ".pgm",
  ".pbm",
  ".qoi",
  ".dds",
  ".fits",
  ".dpx",
  ".apng",
  ".cur",
  ".eps",
];
export const VIDEO_INPUTS = [
  ".mp4",
  ".mov",
  ".webm",
  ".mkv",
  ".avi",
  ".m4v",
  ".mts",
  ".m2ts",
  ".3gp",
  ".flv",
  ".wmv",
  ".mpg",
  ".mpeg",
  ".ts",
  ".ogv",
];
export const AUDIO_INPUTS = [
  ".mp3",
  ".wav",
  ".flac",
  ".aac",
  ".m4a",
  ".ogg",
  ".opus",
  ".wma",
  ".aiff",
  ".amr",
  ".ac3",
];
export const SUBTITLE_INPUTS = [".srt", ".vtt", ".ass"] as const;
export const DOCUMENT_INPUTS = [
  ".pdf",
  ".docx",
  ".doc",
  ".xlsx",
  ".xls",
  ".pptx",
  ".ppt",
  ".odt",
  ".ods",
  ".odp",
  ".rtf",
  ".txt",
  ".md",
  ".html",
  ".epub",
];
export const FILE_INPUTS = [".csv", ".json", ".xml", ".yaml", ".yml", ".zip"];

export function detectModalityFromMime(mime: string): Modality {
  if (mime.startsWith("image/")) return "image";
  if (mime.startsWith("video/")) return "video";
  if (mime.startsWith("audio/")) return "audio";
  if (
    mime === "application/pdf" ||
    mime.includes("officedocument") ||
    mime.includes("msword") ||
    mime.includes("ms-excel") ||
    mime.includes("ms-powerpoint") ||
    mime === "application/epub+zip" ||
    mime.startsWith("text/html")
  ) {
    return "document";
  }
  return "file";
}

const MODALITY_EXTENSION_SETS: [Modality, readonly string[]][] = [
  ["image", IMAGE_INPUTS],
  ["video", VIDEO_INPUTS],
  ["audio", AUDIO_INPUTS],
  ["document", DOCUMENT_INPUTS],
  ["file", FILE_INPUTS],
];

/** Owning modality for a file extension (with or without leading dot), or null. */
export function modalityForExtension(ext: string): Modality | null {
  const norm = (ext.startsWith(".") ? ext : `.${ext}`).toLowerCase();
  for (const [modality, set] of MODALITY_EXTENSION_SETS) {
    if (set.includes(norm)) return modality;
  }
  return null;
}

/** The modality a tool consumes. Derived from acceptedInputs so tools whose `modality`
 *  differs from their real input (gif-to-video, images-to-video) are correct. */
export function toolInputModality(tool: {
  modality: Modality;
  acceptedInputs: string[];
}): Modality {
  const first = tool.acceptedInputs[0];
  if (first) {
    const m = modalityForExtension(first);
    if (m) return m;
  }
  return tool.modality;
}

/** The modality a tool produces. Uses the explicit override, else the tool modality. */
export function toolOutputModality(tool: {
  modality: Modality;
  outputModality?: Modality;
}): Modality {
  return tool.outputModality ?? tool.modality;
}
