import type { SimpleIcon } from "simple-icons";
import {
  siAstro,
  siBun,
  siC,
  siClojure,
  siCmake,
  siCplusplus,
  siCss,
  siDart,
  siDeno,
  siDocker,
  siDotnet,
  siEditorconfig,
  siElixir,
  siErlang,
  siEslint,
  siFortran,
  siFsharp,
  siGit,
  siGitignoredotio,
  siGnubash,
  siGo,
  siGradle,
  siGraphql,
  siHaskell,
  siHtml5,
  siJavascript,
  siJson,
  siJulia,
  siKotlin,
  siLua,
  siMake,
  siMarkdown,
  siNodedotjs,
  siNpm,
  siOcaml,
  siOpenjdk,
  siPerl,
  siPhp,
  siPnpm,
  siPrettier,
  siPython,
  siR,
  siReact,
  siRuby,
  siRust,
  siSass,
  siScala,
  siShell,
  siSqlite,
  siSvelte,
  siSvg,
  siSwift,
  siTailwindcss,
  siTauri,
  siTerraform,
  siToml,
  siTypescript,
  siVite,
  siVuedotjs,
  siYaml,
  siYarn,
  siZig,
  siZsh,
} from "simple-icons";

export interface LanguageIconSpec {
  icon: SimpleIcon;
  title: string;
}

function spec(icon: SimpleIcon, title = icon.title): LanguageIconSpec {
  return { icon, title };
}

const fileNameIcons = new Map<string, LanguageIconSpec>([
  ["dockerfile", spec(siDocker, "Docker")],
  ["docker-compose.yml", spec(siDocker, "Docker Compose")],
  ["docker-compose.yaml", spec(siDocker, "Docker Compose")],
  ["compose.yml", spec(siDocker, "Docker Compose")],
  ["compose.yaml", spec(siDocker, "Docker Compose")],
  ["package.json", spec(siNodedotjs, "Node package")],
  ["package-lock.json", spec(siNpm, "npm lockfile")],
  ["pnpm-lock.yaml", spec(siPnpm, "pnpm lockfile")],
  ["yarn.lock", spec(siYarn, "Yarn lockfile")],
  ["bun.lockb", spec(siBun, "Bun lockfile")],
  ["deno.json", spec(siDeno, "Deno")],
  ["deno.jsonc", spec(siDeno, "Deno")],
  ["cargo.toml", spec(siRust, "Cargo")],
  ["cargo.lock", spec(siRust, "Cargo lockfile")],
  ["tauri.conf.json", spec(siTauri, "Tauri")],
  ["svelte.config.js", spec(siSvelte, "Svelte config")],
  ["svelte.config.ts", spec(siSvelte, "Svelte config")],
  ["vite.config.js", spec(siVite, "Vite config")],
  ["vite.config.ts", spec(siVite, "Vite config")],
  ["tailwind.config.js", spec(siTailwindcss, "Tailwind CSS config")],
  ["tailwind.config.ts", spec(siTailwindcss, "Tailwind CSS config")],
  ["eslint.config.js", spec(siEslint, "ESLint config")],
  ["eslint.config.mjs", spec(siEslint, "ESLint config")],
  [".eslintrc", spec(siEslint, "ESLint config")],
  [".eslintrc.js", spec(siEslint, "ESLint config")],
  [".eslintrc.cjs", spec(siEslint, "ESLint config")],
  [".prettierrc", spec(siPrettier, "Prettier config")],
  [".prettierrc.json", spec(siPrettier, "Prettier config")],
  [".prettierrc.js", spec(siPrettier, "Prettier config")],
  [".gitignore", spec(siGitignoredotio, "gitignore")],
  [".gitattributes", spec(siGit, "Git attributes")],
  [".gitmodules", spec(siGit, "Git modules")],
  [".editorconfig", spec(siEditorconfig, "EditorConfig")],
  ["cmakelists.txt", spec(siCmake, "CMake")],
  ["makefile", spec(siMake, "Makefile")],
  ["justfile", spec(siShell, "Justfile")],
  ["rakefile", spec(siRuby, "Rakefile")],
  ["gemfile", spec(siRuby, "Gemfile")],
]);

const extensionIcons = new Map<string, LanguageIconSpec>([
  ["js", spec(siJavascript)],
  ["mjs", spec(siJavascript)],
  ["cjs", spec(siJavascript)],
  ["jsx", spec(siReact, "React JSX")],
  ["ts", spec(siTypescript)],
  ["mts", spec(siTypescript)],
  ["cts", spec(siTypescript)],
  ["tsx", spec(siReact, "React TSX")],
  ["svelte", spec(siSvelte)],
  ["vue", spec(siVuedotjs, "Vue")],
  ["astro", spec(siAstro)],
  ["rs", spec(siRust)],
  ["go", spec(siGo)],
  ["py", spec(siPython)],
  ["pyw", spec(siPython)],
  ["java", spec(siOpenjdk, "Java")],
  ["kt", spec(siKotlin)],
  ["kts", spec(siKotlin)],
  ["cs", spec(siDotnet, "C#")],
  ["cpp", spec(siCplusplus, "C++")],
  ["cxx", spec(siCplusplus, "C++")],
  ["cc", spec(siCplusplus, "C++")],
  ["hpp", spec(siCplusplus, "C++")],
  ["hh", spec(siCplusplus, "C++")],
  ["c", spec(siC)],
  ["h", spec(siC)],
  ["swift", spec(siSwift)],
  ["php", spec(siPhp, "PHP")],
  ["rb", spec(siRuby)],
  ["lua", spec(siLua)],
  ["dart", spec(siDart)],
  ["scala", spec(siScala)],
  ["zig", spec(siZig)],
  ["ex", spec(siElixir)],
  ["exs", spec(siElixir)],
  ["erl", spec(siErlang)],
  ["hrl", spec(siErlang)],
  ["fs", spec(siFsharp, "F#")],
  ["fsx", spec(siFsharp, "F#")],
  ["fsi", spec(siFsharp, "F#")],
  ["clj", spec(siClojure)],
  ["cljs", spec(siClojure)],
  ["hs", spec(siHaskell)],
  ["lhs", spec(siHaskell)],
  ["ml", spec(siOcaml, "OCaml")],
  ["mli", spec(siOcaml, "OCaml")],
  ["jl", spec(siJulia)],
  ["r", spec(siR, "R")],
  ["pl", spec(siPerl)],
  ["pm", spec(siPerl)],
  ["f", spec(siFortran)],
  ["f90", spec(siFortran)],
  ["f95", spec(siFortran)],
  ["html", spec(siHtml5, "HTML")],
  ["htm", spec(siHtml5, "HTML")],
  ["css", spec(siCss, "CSS")],
  ["scss", spec(siSass, "Sass")],
  ["sass", spec(siSass, "Sass")],
  ["svg", spec(siSvg, "SVG")],
  ["json", spec(siJson, "JSON")],
  ["jsonc", spec(siJson, "JSONC")],
  ["json5", spec(siJson, "JSON5")],
  ["yaml", spec(siYaml, "YAML")],
  ["yml", spec(siYaml, "YAML")],
  ["toml", spec(siToml, "TOML")],
  ["tf", spec(siTerraform, "Terraform")],
  ["tfvars", spec(siTerraform, "Terraform variables")],
  ["graphql", spec(siGraphql, "GraphQL")],
  ["gql", spec(siGraphql, "GraphQL")],
  ["md", spec(siMarkdown, "Markdown")],
  ["mdx", spec(siMarkdown, "MDX")],
  ["sh", spec(siGnubash, "Shell script")],
  ["bash", spec(siGnubash, "Bash")],
  ["zsh", spec(siZsh, "Zsh")],
  ["fish", spec(siShell, "Fish shell")],
  ["sql", spec(siSqlite, "SQL")],
  ["sqlite", spec(siSqlite, "SQLite")],
  ["sqlite3", spec(siSqlite, "SQLite")],
]);

export function languageIconForPath(path: string): LanguageIconSpec | null {
  const name = path.split(/[\\/]/).pop()?.toLowerCase() ?? "";
  const byName = fileNameIcons.get(name);
  if (byName) return byName;

  const index = name.lastIndexOf(".");
  if (index <= 0) return null;
  return extensionIcons.get(name.slice(index + 1)) ?? null;
}
