export type LocalModelCategory = "general" | "coding" | "reasoning" | "vision";

export interface LocalModelVariant {
  label: string;
  precision: string;
  ollamaTag: string;
  rapidMlxAlias?: string;
}

export interface LocalModelRecommendation {
  id: string;
  name: string;
  category: LocalModelCategory;
  memory: string;
  description: string;
  ollamaTag: string;
  rapidMlxAlias?: string;
  variants: LocalModelVariant[];
  rapidMlxRequiresVision?: boolean;
}

const v = (
  label: string,
  precision: string,
  ollamaTag: string,
  rapidMlxAlias?: string,
): LocalModelVariant => ({ label, precision, ollamaTag, rapidMlxAlias });

export const RAPID_MLX_ALIAS_REPOS: Record<string, string> = {
  "deepseek-r1-32b": "mlx-community/DeepSeek-R1-Distill-Qwen-32B-4bit",
  "deepseek-r1-8b": "mlx-community/DeepSeek-R1-0528-Qwen3-8B-4bit",
  "devstral-v2-24b": "mlx-community/Devstral-Small-2-24B-Instruct-2512-4bit",
  "gemma-4-26b": "mlx-community/gemma-4-26b-a4b-it-4bit",
  "gemma-4-31b": "mlx-community/gemma-4-31b-it-4bit",
  "gpt-oss-20b": "mlx-community/GPT-OSS-20B-4bit",
  "mistral-24b": "mlx-community/Mistral-Small-3.1-24B-Instruct-2503-4bit",
  "nemotron-30b": "lmstudio-community/NVIDIA-Nemotron-3-Nano-30B-A3B-MLX-4bit",
  "qwen3-coder": "lmstudio-community/Qwen3-Coder-Next-MLX-4bit",
  "qwen3-coder-30b": "mlx-community/Qwen3-Coder-30B-A3B-Instruct-4bit",
  "qwen3-vl-30b": "mlx-community/Qwen3-VL-30B-A3B-Instruct-4bit",
  "qwen3-vl-4b": "mlx-community/Qwen3-VL-4B-Instruct-MLX-4bit",
  "qwen3-vl-8b": "mlx-community/Qwen3-VL-8B-Instruct-4bit",
  "qwen3.5-122b": "nightmedia/Qwen3.5-122B-A10B-Text-mxfp4-mlx",
  "qwen3.5-122b-8bit": "mlx-community/Qwen3.5-122B-A10B-8bit",
  "qwen3.5-27b": "mlx-community/Qwen3.5-27B-4bit",
  "qwen3.5-35b": "mlx-community/Qwen3.5-35B-A3B-8bit",
  "qwen3.5-4b": "mlx-community/Qwen3.5-4B-MLX-4bit",
  "qwen3.5-9b": "mlx-community/Qwen3.5-9B-4bit",
  "qwen3.6-27b": "mlx-community/Qwen3.6-27B-4bit",
  "qwen3.6-27b-8bit": "unsloth/Qwen3.6-27B-MLX-8bit",
  "qwen3.6-35b": "mlx-community/Qwen3.6-35B-A3B-4bit",
  "qwen3.6-35b-6bit": "mlx-community/Qwen3.6-35B-A3B-6bit",
};

export function canonicalRapidMlxModel(value: string | undefined): string {
  const model = (value ?? "").trim().replace(/^rapid-mlx\//, "");
  if (!model) return "";
  return (RAPID_MLX_ALIAS_REPOS[model] ?? model).toLowerCase();
}

export const LOCAL_MODEL_RECOMMENDATIONS: LocalModelRecommendation[] = [
  {
    id: "qwen3.5-4b",
    name: "Qwen3.5 4B",
    category: "general",
    memory: "16GB Mac",
    description: "Fast default for chat, tools, and light coding.",
    ollamaTag: "qwen3.5:4b",
    rapidMlxAlias: "qwen3.5-4b",
    variants: [
      v("Default", "runtime default", "qwen3.5:4b", "qwen3.5-4b"),
      v("Q4_K_M", "4-bit", "qwen3.5:4b-q4_K_M"),
      v("Q8_0", "8-bit", "qwen3.5:4b-q8_0"),
      v("BF16", "bf16", "qwen3.5:4b-bf16"),
      v("MLX BF16", "mlx bf16", "qwen3.5:4b-mlx-bf16"),
      v("MXFP8", "mxfp8", "qwen3.5:4b-mxfp8"),
      v("NVFP4", "nvfp4", "qwen3.5:4b-nvfp4"),
    ],
  },
  {
    id: "qwen3.5-9b",
    name: "Qwen3.5 9B",
    category: "general",
    memory: "24GB Mac",
    description: "Better small all-rounder while staying quick.",
    ollamaTag: "qwen3.5:9b",
    rapidMlxAlias: "qwen3.5-9b",
    variants: [
      v("Default", "runtime default", "qwen3.5:9b", "qwen3.5-9b"),
      v("Q4_K_M", "4-bit", "qwen3.5:9b-q4_K_M"),
      v("Q8_0", "8-bit", "qwen3.5:9b-q8_0"),
      v("BF16", "bf16", "qwen3.5:9b-bf16"),
      v("MLX BF16", "mlx bf16", "qwen3.5:9b-mlx-bf16"),
      v("MXFP8", "mxfp8", "qwen3.5:9b-mxfp8"),
      v("NVFP4", "nvfp4", "qwen3.5:9b-nvfp4"),
    ],
  },
  {
    id: "qwen3.5-27b",
    name: "Qwen3.5 27B",
    category: "coding",
    memory: "32GB Mac",
    description: "Solid local coding and agent model.",
    ollamaTag: "qwen3.5:27b",
    rapidMlxAlias: "qwen3.5-27b",
    variants: [
      v("Default", "runtime default", "qwen3.5:27b", "qwen3.5-27b"),
      v("Q4_K_M", "4-bit", "qwen3.5:27b-q4_K_M"),
      v("Q8_0", "8-bit", "qwen3.5:27b-q8_0"),
      v("BF16", "bf16", "qwen3.5:27b-bf16"),
      v("MLX BF16", "mlx bf16", "qwen3.5:27b-mlx-bf16"),
      v("MXFP8", "mxfp8", "qwen3.5:27b-mxfp8"),
      v("NVFP4", "nvfp4", "qwen3.5:27b-nvfp4"),
      v("INT4", "int4", "qwen3.5:27b-int4"),
      v("INT8", "int8", "qwen3.5:27b-int8"),
      v("Coding BF16", "coding bf16", "qwen3.5:27b-coding-bf16"),
      v("Coding MXFP8", "coding mxfp8", "qwen3.5:27b-coding-mxfp8"),
      v("Coding NVFP4", "coding nvfp4", "qwen3.5:27b-coding-nvfp4"),
    ],
  },
  {
    id: "qwen3.5-35b",
    name: "Qwen3.5 35B",
    category: "general",
    memory: "48GB+ Mac",
    description: "Sweet spot for quality and speed on larger Macs.",
    ollamaTag: "qwen3.5:35b",
    rapidMlxAlias: "qwen3.5-35b",
    variants: [
      v("Default", "runtime default", "qwen3.5:35b", "qwen3.5-35b"),
      v("A3B", "a3b", "qwen3.5:35b-a3b"),
      v("Q4_K_M", "4-bit", "qwen3.5:35b-a3b-q4_K_M"),
      v("Q8_0", "8-bit", "qwen3.5:35b-a3b-q8_0"),
      v("BF16", "bf16", "qwen3.5:35b-a3b-bf16"),
      v("MLX BF16", "mlx bf16", "qwen3.5:35b-a3b-mlx-bf16"),
      v("MXFP8", "mxfp8", "qwen3.5:35b-a3b-mxfp8"),
      v("NVFP4", "nvfp4", "qwen3.5:35b-a3b-nvfp4"),
      v("INT4", "int4", "qwen3.5:35b-a3b-int4"),
      v("INT8", "int8", "qwen3.5:35b-a3b-int8"),
      v("Coding BF16", "coding bf16", "qwen3.5:35b-a3b-coding-bf16"),
      v("Coding MXFP8", "coding mxfp8", "qwen3.5:35b-a3b-coding-mxfp8"),
      v("Coding NVFP4", "coding nvfp4", "qwen3.5:35b-a3b-coding-nvfp4"),
    ],
  },
  {
    id: "qwen3.5-122b",
    name: "Qwen3.5 122B",
    category: "general",
    memory: "96GB+ Mac",
    description: "Frontier-level local model for high-memory Macs.",
    ollamaTag: "qwen3.5:122b",
    rapidMlxAlias: "qwen3.5-122b",
    variants: [
      v("Default", "runtime default", "qwen3.5:122b", "qwen3.5-122b"),
      v("A10B", "a10b", "qwen3.5:122b-a10b"),
      v("Q4_K_M", "4-bit", "qwen3.5:122b-a10b-q4_K_M"),
      v("MLX 8-bit", "8-bit", "qwen3.5:122b-a10b", "qwen3.5-122b-8bit"),
    ],
  },
  {
    id: "qwen3.6-27b",
    name: "Qwen3.6 27B",
    category: "coding",
    memory: "32GB Mac",
    description: "Newer Qwen coding model with strong long-context behavior.",
    ollamaTag: "qwen3.6:27b",
    rapidMlxAlias: "qwen3.6-27b",
    variants: [
      v("Default", "runtime default", "qwen3.6:27b", "qwen3.6-27b"),
      v("Q4_K_M", "4-bit", "qwen3.6:27b-q4_K_M"),
      v("Q8_0", "8-bit", "qwen3.6:27b-q8_0", "qwen3.6-27b-8bit"),
      v("BF16", "bf16", "qwen3.6:27b-bf16"),
      v("MLX BF16", "mlx bf16", "qwen3.6:27b-mlx-bf16"),
      v("MXFP8", "mxfp8", "qwen3.6:27b-mxfp8"),
      v("NVFP4", "nvfp4", "qwen3.6:27b-nvfp4"),
      v("Coding BF16", "coding bf16", "qwen3.6:27b-coding-bf16"),
      v("Coding MXFP8", "coding mxfp8", "qwen3.6:27b-coding-mxfp8"),
      v("Coding NVFP4", "coding nvfp4", "qwen3.6:27b-coding-nvfp4"),
    ],
  },
  {
    id: "qwen3.6-35b",
    name: "Qwen3.6 35B",
    category: "coding",
    memory: "32GB+ Mac",
    description: "Strong agentic coding with long context.",
    ollamaTag: "qwen3.6:35b",
    rapidMlxAlias: "qwen3.6-35b",
    variants: [
      v("Default", "runtime default", "qwen3.6:35b", "qwen3.6-35b"),
      v("A3B", "a3b", "qwen3.6:35b-a3b"),
      v("Q4_K_M", "4-bit", "qwen3.6:35b-a3b-q4_K_M"),
      v("Q8_0", "8-bit", "qwen3.6:35b-a3b-q8_0"),
      v("BF16", "bf16", "qwen3.6:35b-a3b-bf16"),
      v("MLX BF16", "mlx bf16", "qwen3.6:35b-a3b-mlx-bf16"),
      v("MXFP8", "mxfp8", "qwen3.6:35b-a3b-mxfp8"),
      v("NVFP4", "nvfp4", "qwen3.6:35b-a3b-nvfp4"),
      v("MLX 6-bit", "6-bit", "qwen3.6:35b-a3b", "qwen3.6-35b-6bit"),
      v("Coding BF16", "coding bf16", "qwen3.6:35b-a3b-coding-bf16"),
      v("Coding MXFP8", "coding mxfp8", "qwen3.6:35b-a3b-coding-mxfp8"),
      v("Coding NVFP4", "coding nvfp4", "qwen3.6:35b-a3b-coding-nvfp4"),
    ],
  },
  {
    id: "qwen3-coder-30b",
    name: "Qwen3 Coder 30B",
    category: "coding",
    memory: "32GB+ Mac",
    description: "Efficient code-agent model for repository work.",
    ollamaTag: "qwen3-coder:30b",
    rapidMlxAlias: "qwen3-coder-30b",
    variants: [
      v("Default", "runtime default", "qwen3-coder:30b", "qwen3-coder-30b"),
      v("Q4_K_M", "4-bit", "qwen3-coder:30b-a3b-q4_K_M"),
      v("Q8_0", "8-bit", "qwen3-coder:30b-a3b-q8_0"),
      v("FP16", "fp16", "qwen3-coder:30b-a3b-fp16"),
    ],
  },
  {
    id: "qwen3-coder-next",
    name: "Qwen3 Coder Next",
    category: "coding",
    memory: "64GB+ Mac",
    description: "Larger coding-agent model for harder software tasks.",
    ollamaTag: "qwen3-coder-next:latest",
    rapidMlxAlias: "qwen3-coder",
    variants: [
      v("Default", "runtime default", "qwen3-coder-next:latest", "qwen3-coder"),
      v("Q4_K_M", "4-bit", "qwen3-coder-next:q4_K_M"),
      v("Q8_0", "8-bit", "qwen3-coder-next:q8_0"),
    ],
  },
  {
    id: "gpt-oss-20b",
    name: "GPT-OSS 20B",
    category: "reasoning",
    memory: "24GB+ Mac",
    description: "Popular open-weight reasoning and developer model.",
    ollamaTag: "gpt-oss:20b",
    rapidMlxAlias: "gpt-oss-20b",
    variants: [v("Default", "MXFP4", "gpt-oss:20b", "gpt-oss-20b")],
  },
  {
    id: "gpt-oss-120b",
    name: "GPT-OSS 120B",
    category: "reasoning",
    memory: "128GB+ Mac",
    description: "High-reasoning open-weight GPT-OSS model for large-memory Macs.",
    ollamaTag: "gpt-oss:120b",
    rapidMlxAlias: "mlx-community/gpt-oss-120b-mxfp4-bf16",
    variants: [
      v("Default", "MXFP4", "gpt-oss:120b"),
      v(
        "MLX MXFP4 BF16",
        "mxfp4/bf16",
        "gpt-oss:120b",
        "mlx-community/gpt-oss-120b-mxfp4-bf16",
      ),
    ],
  },
  {
    id: "deepseek-r1-8b",
    name: "DeepSeek-R1 8B",
    category: "reasoning",
    memory: "16GB Mac",
    description: "Small reasoning model for planning and math.",
    ollamaTag: "deepseek-r1:8b",
    rapidMlxAlias: "deepseek-r1-8b",
    variants: [
      v("Default", "runtime default", "deepseek-r1:8b", "deepseek-r1-8b"),
      v("Qwen3 Q4_K_M", "4-bit", "deepseek-r1:8b-0528-qwen3-q4_K_M"),
      v("Qwen3 Q8_0", "8-bit", "deepseek-r1:8b-0528-qwen3-q8_0"),
      v("Qwen3 FP16", "fp16", "deepseek-r1:8b-0528-qwen3-fp16"),
      v("Llama Q4_K_M", "4-bit", "deepseek-r1:8b-llama-distill-q4_K_M"),
      v("Llama Q8_0", "8-bit", "deepseek-r1:8b-llama-distill-q8_0"),
      v("Llama FP16", "fp16", "deepseek-r1:8b-llama-distill-fp16"),
    ],
  },
  {
    id: "deepseek-r1-32b",
    name: "DeepSeek-R1 32B",
    category: "reasoning",
    memory: "32GB+ Mac",
    description: "Reasoning-heavy model for planning and math.",
    ollamaTag: "deepseek-r1:32b",
    rapidMlxAlias: "deepseek-r1-32b",
    variants: [
      v("Default", "runtime default", "deepseek-r1:32b", "deepseek-r1-32b"),
      v("Q4_K_M", "4-bit", "deepseek-r1:32b-qwen-distill-q4_K_M"),
      v("Q8_0", "8-bit", "deepseek-r1:32b-qwen-distill-q8_0"),
      v("FP16", "fp16", "deepseek-r1:32b-qwen-distill-fp16"),
    ],
  },
  {
    id: "gemma-4-26b",
    name: "Gemma 4 26B",
    category: "vision",
    memory: "32GB+ Mac",
    description: "Strong multimodal all-rounder.",
    ollamaTag: "gemma4:26b",
    rapidMlxAlias: "gemma-4-26b",
    rapidMlxRequiresVision: true,
    variants: [
      v("Default", "a4b", "gemma4:26b", "gemma-4-26b"),
      v("Q4_K_M", "4-bit", "gemma4:26b-a4b-it-q4_K_M"),
      v("Q8_0", "8-bit", "gemma4:26b-a4b-it-q8_0"),
      v("MLX BF16", "mlx bf16", "gemma4:26b-mlx-bf16"),
      v("MXFP8", "mxfp8", "gemma4:26b-mxfp8"),
      v("NVFP4", "nvfp4", "gemma4:26b-nvfp4"),
    ],
  },
  {
    id: "gemma-4-31b",
    name: "Gemma 4 31B",
    category: "vision",
    memory: "48GB+ Mac",
    description: "Dense Gemma 4 model with stronger multimodal quality.",
    ollamaTag: "gemma4:31b",
    rapidMlxAlias: "gemma-4-31b",
    rapidMlxRequiresVision: true,
    variants: [
      v("Default", "runtime default", "gemma4:31b", "gemma-4-31b"),
      v("Q4_K_M", "4-bit", "gemma4:31b-it-q4_K_M"),
      v("Q8_0", "8-bit", "gemma4:31b-it-q8_0"),
      v("BF16", "bf16", "gemma4:31b-it-bf16"),
      v("MLX BF16", "mlx bf16", "gemma4:31b-mlx-bf16"),
      v("MXFP8", "mxfp8", "gemma4:31b-mxfp8"),
      v("NVFP4", "nvfp4", "gemma4:31b-nvfp4"),
      v("Coding MTP BF16", "coding mtp bf16", "gemma4:31b-coding-mtp-bf16"),
    ],
  },
  {
    id: "qwen3-vl-4b",
    name: "Qwen3-VL 4B",
    category: "vision",
    memory: "16GB Mac",
    description: "Fast vision-language model for screenshots and images.",
    ollamaTag: "qwen3-vl:4b",
    rapidMlxAlias: "qwen3-vl-4b",
    rapidMlxRequiresVision: true,
    variants: [
      v("Default", "runtime default", "qwen3-vl:4b", "qwen3-vl-4b"),
      v("Instruct", "default", "qwen3-vl:4b-instruct"),
      v("Instruct Q4_K_M", "4-bit", "qwen3-vl:4b-instruct-q4_K_M"),
      v("Instruct Q8_0", "8-bit", "qwen3-vl:4b-instruct-q8_0"),
      v("Instruct BF16", "bf16", "qwen3-vl:4b-instruct-bf16"),
      v("Thinking", "default", "qwen3-vl:4b-thinking"),
      v("Thinking Q4_K_M", "4-bit", "qwen3-vl:4b-thinking-q4_K_M"),
      v("Thinking Q8_0", "8-bit", "qwen3-vl:4b-thinking-q8_0"),
      v("Thinking BF16", "bf16", "qwen3-vl:4b-thinking-bf16"),
    ],
  },
  {
    id: "qwen3-vl-8b",
    name: "Qwen3-VL 8B",
    category: "vision",
    memory: "24GB Mac",
    description: "Balanced vision-language model for local multimodal work.",
    ollamaTag: "qwen3-vl:8b",
    rapidMlxAlias: "qwen3-vl-8b",
    rapidMlxRequiresVision: true,
    variants: [
      v("Default", "runtime default", "qwen3-vl:8b", "qwen3-vl-8b"),
      v("Instruct", "default", "qwen3-vl:8b-instruct"),
      v("Instruct Q4_K_M", "4-bit", "qwen3-vl:8b-instruct-q4_K_M"),
      v("Instruct Q8_0", "8-bit", "qwen3-vl:8b-instruct-q8_0"),
      v("Instruct BF16", "bf16", "qwen3-vl:8b-instruct-bf16"),
      v("Thinking", "default", "qwen3-vl:8b-thinking"),
      v("Thinking Q4_K_M", "4-bit", "qwen3-vl:8b-thinking-q4_K_M"),
      v("Thinking Q8_0", "8-bit", "qwen3-vl:8b-thinking-q8_0"),
      v("Thinking BF16", "bf16", "qwen3-vl:8b-thinking-bf16"),
    ],
  },
  {
    id: "qwen3-vl-30b",
    name: "Qwen3-VL 30B",
    category: "vision",
    memory: "48GB+ Mac",
    description: "High-quality vision-language model for heavier image tasks.",
    ollamaTag: "qwen3-vl:30b",
    rapidMlxAlias: "qwen3-vl-30b",
    rapidMlxRequiresVision: true,
    variants: [
      v("Default", "runtime default", "qwen3-vl:30b", "qwen3-vl-30b"),
      v("A3B", "a3b", "qwen3-vl:30b-a3b"),
      v("Instruct", "default", "qwen3-vl:30b-a3b-instruct"),
      v("Instruct Q4_K_M", "4-bit", "qwen3-vl:30b-a3b-instruct-q4_K_M"),
      v("Instruct Q8_0", "8-bit", "qwen3-vl:30b-a3b-instruct-q8_0"),
      v("Instruct BF16", "bf16", "qwen3-vl:30b-a3b-instruct-bf16"),
      v("Thinking", "default", "qwen3-vl:30b-a3b-thinking"),
      v("Thinking Q4_K_M", "4-bit", "qwen3-vl:30b-a3b-thinking-q4_K_M"),
      v("Thinking Q8_0", "8-bit", "qwen3-vl:30b-a3b-thinking-q8_0"),
      v("Thinking BF16", "bf16", "qwen3-vl:30b-a3b-thinking-bf16"),
    ],
  },
  {
    id: "devstral-v2-24b",
    name: "Devstral Small 2 24B",
    category: "coding",
    memory: "32GB Mac",
    description: "Mistral coding-agent model for editing and tool use.",
    ollamaTag: "devstral-small-2:24b",
    rapidMlxAlias: "devstral-v2-24b",
    variants: [
      v("Default", "runtime default", "devstral-small-2:24b", "devstral-v2-24b"),
      v("Q4_K_M", "4-bit", "devstral-small-2:24b-instruct-2512-q4_K_M"),
      v("Q8_0", "8-bit", "devstral-small-2:24b-instruct-2512-q8_0"),
      v("FP16", "fp16", "devstral-small-2:24b-instruct-2512-fp16"),
    ],
  },
  {
    id: "mistral-small-24b",
    name: "Mistral Small 24B",
    category: "general",
    memory: "32GB Mac",
    description: "Reliable general model with strong instruction following.",
    ollamaTag: "mistral-small:24b",
    rapidMlxAlias: "mistral-24b",
    variants: [
      v("Default", "runtime default", "mistral-small:24b", "mistral-24b"),
      v("Q4_K_M", "4-bit", "mistral-small:24b-instruct-2501-q4_K_M"),
      v("Q8_0", "8-bit", "mistral-small:24b-instruct-2501-q8_0"),
      v("FP16", "fp16", "mistral-small:24b-instruct-2501-fp16"),
    ],
  },
  {
    id: "nemotron-3-nano-30b",
    name: "Nemotron 3 Nano 30B",
    category: "reasoning",
    memory: "32GB+ Mac",
    description: "Fast MoE reasoning model with long-context strengths.",
    ollamaTag: "nemotron-3-nano:30b",
    rapidMlxAlias: "nemotron-30b",
    variants: [
      v("Default", "a3b", "nemotron-3-nano:30b", "nemotron-30b"),
      v("Q4_K_M", "4-bit", "nemotron-3-nano:30b-a3b-q4_K_M"),
      v("Q8_0", "8-bit", "nemotron-3-nano:30b-a3b-q8_0"),
      v("FP16", "fp16", "nemotron-3-nano:30b-a3b-fp16"),
    ],
  },
];
