// SPDX-License-Identifier: MIT
// Copyright (c) 2025-2026 SenWeaverCoding

import { addCollection, type IconifyJSON } from '@iconify/react/dist/offline'

let registered = false
let registerPromise: Promise<void> | null = null

export function ensureVscodeIcons(): Promise<void> {
  if (registered) return Promise.resolve()
  if (registerPromise) return registerPromise
  registerPromise = import('@iconify-json/vscode-icons/icons.json')
    .then((mod) => {
      const data = ((mod as unknown as { default?: IconifyJSON }).default ??
        (mod as unknown)) as IconifyJSON
      addCollection(data)
      registered = true
    })
    .catch((err) => {

      registerPromise = null
      throw err
    })
  return registerPromise
}

export function isVscodeIconsReady(): boolean {
  return registered
}

const PREFIX = 'vscode-icons:'
const DEFAULT_FILE = `${PREFIX}default-file`
const DEFAULT_FOLDER = `${PREFIX}default-folder`
const DEFAULT_FOLDER_OPEN = `${PREFIX}default-folder-opened`

const NAMED: Record<string, string> = {

  'package.json': 'file-type-npm',
  'package-lock.json': 'file-type-npm',
  '.npmrc': 'file-type-npm',
  'yarn.lock': 'file-type-yarn',
  '.yarnrc': 'file-type-yarn',
  '.yarnrc.yml': 'file-type-yarn',
  'pnpm-lock.yaml': 'file-type-pnpm',
  'pnpm-workspace.yaml': 'file-type-pnpm',
  'bun.lock': 'file-type-bun',
  'bun.lockb': 'file-type-bun',
  'bunfig.toml': 'file-type-bun',
  'deno.json': 'file-type-deno',
  'deno.jsonc': 'file-type-deno',
  'deno.lock': 'file-type-deno',

  'cargo.toml': 'file-type-cargo',
  'cargo.lock': 'file-type-cargo',
  'rust-toolchain': 'file-type-rust-toolchain',
  'rust-toolchain.toml': 'file-type-rust-toolchain',
  'rustfmt.toml': 'file-type-rust',

  'go.mod': 'file-type-go',
  'go.sum': 'file-type-go',
  'go.work': 'file-type-go',
  'go.work.sum': 'file-type-go',

  'requirements.txt': 'file-type-pip',
  'pyproject.toml': 'file-type-python',
  'poetry.lock': 'file-type-poetry',
  'pipfile': 'file-type-pip',
  'pipfile.lock': 'file-type-pip',
  'setup.py': 'file-type-python',
  'setup.cfg': 'file-type-python',
  'manifest.in': 'file-type-python',

  'tsconfig.json': 'file-type-tsconfig',
  'tsconfig.app.json': 'file-type-tsconfig',
  'tsconfig.node.json': 'file-type-tsconfig',
  'tsconfig.base.json': 'file-type-tsconfig',
  'tsconfig.build.json': 'file-type-tsconfig',
  'jsconfig.json': 'file-type-jsconfig',

  'vite.config.ts': 'file-type-vite',
  'vite.config.js': 'file-type-vite',
  'vite.config.mts': 'file-type-vite',
  'vitest.config.ts': 'file-type-vitest',
  'vitest.config.js': 'file-type-vitest',
  'webpack.config.js': 'file-type-webpack',
  'webpack.config.ts': 'file-type-webpack',
  'rollup.config.js': 'file-type-rollup',
  'rollup.config.ts': 'file-type-rollup',
  'esbuild.config.js': 'file-type-esbuild',
  'esbuild.config.ts': 'file-type-esbuild',
  'gulpfile.js': 'file-type-gulp',
  'gruntfile.js': 'file-type-grunt',
  'turbo.json': 'file-type-turbo',
  'nx.json': 'file-type-nrwl',
  'rush.json': 'file-type-rush',

  'tailwind.config.js': 'file-type-tailwind',
  'tailwind.config.ts': 'file-type-tailwind',
  'tailwind.config.cjs': 'file-type-tailwind',
  'postcss.config.js': 'file-type-postcssconfig',
  'postcss.config.cjs': 'file-type-postcssconfig',
  'postcss.config.ts': 'file-type-postcssconfig',

  '.eslintrc': 'file-type-eslint',
  '.eslintrc.json': 'file-type-eslint',
  '.eslintrc.js': 'file-type-eslint',
  '.eslintrc.cjs': 'file-type-eslint',
  '.eslintrc.yml': 'file-type-eslint',
  'eslint.config.js': 'file-type-eslint',
  'eslint.config.mjs': 'file-type-eslint',
  'eslint.config.ts': 'file-type-eslint',
  '.eslintignore': 'file-type-eslint',
  '.prettierrc': 'file-type-prettier',
  '.prettierrc.json': 'file-type-prettier',
  '.prettierrc.js': 'file-type-prettier',
  '.prettierrc.yml': 'file-type-prettier',
  '.prettierrc.yaml': 'file-type-prettier',
  '.prettierignore': 'file-type-prettier',
  'prettier.config.js': 'file-type-prettier',
  '.editorconfig': 'file-type-editorconfig',
  '.stylelintrc': 'file-type-stylelint',
  'stylelint.config.js': 'file-type-stylelint',
  'biome.json': 'file-type-biome',

  'babel.config.js': 'file-type-babel',
  '.babelrc': 'file-type-babel',
  '.babelrc.json': 'file-type-babel',
  '.swcrc': 'file-type-swc',

  '.gitignore': 'file-type-git',
  '.gitattributes': 'file-type-git',
  '.gitmodules': 'file-type-git',
  '.gitkeep': 'file-type-git',
  '.gitconfig': 'file-type-git',
  '.mailmap': 'file-type-git',

  dockerfile: 'file-type-docker',
  '.dockerignore': 'file-type-docker',
  'docker-compose.yml': 'file-type-docker2',
  'docker-compose.yaml': 'file-type-docker2',
  'docker-compose.override.yml': 'file-type-docker2',
  'compose.yml': 'file-type-docker2',
  'compose.yaml': 'file-type-docker2',

  'kustomization.yaml': 'file-type-kubernetes',
  'kustomization.yml': 'file-type-kubernetes',

  '.travis.yml': 'file-type-travis',
  'jenkinsfile': 'file-type-jenkins',

  'license': 'file-type-license',
  'license.md': 'file-type-license',
  'license.txt': 'file-type-license',
  'license-mit': 'file-type-license',
  'copying': 'file-type-license',
  'readme': 'file-type-info',
  'readme.md': 'file-type-info',
  'readme.txt': 'file-type-info',
  'readme.rst': 'file-type-info',
  'authors': 'file-type-authors',
  'contributors': 'file-type-authors',
  'changelog': 'file-type-changelog',
  'changelog.md': 'file-type-changelog',
  'history.md': 'file-type-changelog',
  'history': 'file-type-changelog',
  'codeowners': 'file-type-codeowners',

  makefile: 'file-type-makefile',
  'cmakelists.txt': 'file-type-cmake',

  '.env': 'file-type-dotenv',
  '.env.local': 'file-type-dotenv',
  '.env.development': 'file-type-dotenv',
  '.env.production': 'file-type-dotenv',
  '.env.test': 'file-type-dotenv',
  '.env.example': 'file-type-dotenv',
  '.env.sample': 'file-type-dotenv',

  'tauri.conf.json': 'file-type-tauri',

  procfile: 'file-type-heroku',
  'app.json': 'file-type-expo',
  'metro.config.js': 'file-type-metro',
}

const BY_EXT: Record<string, string> = {

  js: 'file-type-js',
  mjs: 'file-type-js',
  cjs: 'file-type-js',
  jsx: 'file-type-reactjs',
  ts: 'file-type-typescript',
  mts: 'file-type-typescript',
  cts: 'file-type-typescript',
  tsx: 'file-type-reactts',

  py: 'file-type-python',
  pyi: 'file-type-python',
  pyx: 'file-type-python',
  pyc: 'file-type-python',
  ipynb: 'file-type-jupyter',

  rs: 'file-type-rust',
  go: 'file-type-go',

  java: 'file-type-java',
  class: 'file-type-class',
  jar: 'file-type-jar',
  kt: 'file-type-kotlin',
  kts: 'file-type-kotlin',
  scala: 'file-type-scala',
  sbt: 'file-type-scala',
  groovy: 'file-type-groovy',
  gradle: 'file-type-gradle',

  c: 'file-type-c',
  h: 'file-type-cheader',
  cpp: 'file-type-cpp3',
  cc: 'file-type-cpp3',
  cxx: 'file-type-cpp3',
  hpp: 'file-type-cppheader',
  hxx: 'file-type-cppheader',
  cs: 'file-type-csharp',
  csproj: 'file-type-csproj',
  fs: 'file-type-fsharp',
  fsx: 'file-type-fsharp',
  fsproj: 'file-type-fsproj',
  vb: 'file-type-vb',
  vbs: 'file-type-vbs',

  swift: 'file-type-swift',
  m: 'file-type-objectivec',
  mm: 'file-type-objectivecpp',

  rb: 'file-type-ruby',
  erb: 'file-type-erb',
  gemspec: 'file-type-gemfile',
  php: 'file-type-php',
  perl: 'file-type-perl',
  pl: 'file-type-perl',
  pm: 'file-type-perl',
  r: 'file-type-r',
  rmd: 'file-type-r',
  jl: 'file-type-julia',
  ex: 'file-type-elixir',
  exs: 'file-type-elixir',
  erl: 'file-type-erlang',
  hrl: 'file-type-erlang',
  hs: 'file-type-haskell',
  lhs: 'file-type-haskell',
  clj: 'file-type-clojure',
  cljs: 'file-type-clojure',
  edn: 'file-type-clojure',
  elm: 'file-type-elm',
  ml: 'file-type-ocaml',
  mli: 'file-type-ocaml',
  dart: 'file-type-dartlang',
  lua: 'file-type-lua',
  zig: 'file-type-zig',
  nim: 'file-type-nim',
  cr: 'file-type-crystal',
  vala: 'file-type-vala',
  d: 'file-type-d',
  pas: 'file-type-pascal',
  ada: 'file-type-ada',
  adb: 'file-type-ada',
  ads: 'file-type-ada',

  sh: 'file-type-shell',
  bash: 'file-type-shell',
  zsh: 'file-type-shell',
  fish: 'file-type-shell',
  ksh: 'file-type-shell',
  ps1: 'file-type-powershell',
  psm1: 'file-type-powershell',
  psd1: 'file-type-powershell',
  bat: 'file-type-bat',
  cmd: 'file-type-bat',

  html: 'file-type-html',
  htm: 'file-type-html',
  xhtml: 'file-type-html',
  xml: 'file-type-xml',
  xsl: 'file-type-xml',
  xslt: 'file-type-xml',
  svg: 'file-type-svg',
  css: 'file-type-css',
  scss: 'file-type-scss',
  sass: 'file-type-sass',
  less: 'file-type-less',
  styl: 'file-type-stylus',
  postcss: 'file-type-postcss',
  vue: 'file-type-vue',
  svelte: 'file-type-svelte',
  astro: 'file-type-astro',

  json: 'file-type-json',
  jsonc: 'file-type-json',
  json5: 'file-type-json',
  yaml: 'file-type-yaml',
  yml: 'file-type-yaml',
  toml: 'file-type-toml',
  ini: 'file-type-ini',
  conf: 'file-type-config',
  config: 'file-type-config',
  cfg: 'file-type-config',
  properties: 'file-type-properties',
  env: 'file-type-dotenv',
  csv: 'file-type-excel2',
  tsv: 'file-type-excel2',

  md: 'file-type-markdown',
  markdown: 'file-type-markdown',
  mdx: 'file-type-mdx',
  rst: 'file-type-restructuredtext',
  adoc: 'file-type-asciidoc',
  asciidoc: 'file-type-asciidoc',
  txt: 'file-type-text',
  log: 'file-type-log',
  pdf: 'file-type-pdf2',
  doc: 'file-type-word',
  docx: 'file-type-word',
  xls: 'file-type-excel',
  xlsx: 'file-type-excel',
  ppt: 'file-type-powerpoint',
  pptx: 'file-type-powerpoint',

  png: 'file-type-image',
  jpg: 'file-type-image',
  jpeg: 'file-type-image',
  gif: 'file-type-image',
  webp: 'file-type-image',
  bmp: 'file-type-image',
  tiff: 'file-type-image',
  tif: 'file-type-image',
  ico: 'file-type-favicon',
  avif: 'file-type-avif',

  mp4: 'file-type-video',
  mov: 'file-type-video',
  webm: 'file-type-video',
  avi: 'file-type-video',
  mkv: 'file-type-video',
  flv: 'file-type-video',
  mp3: 'file-type-audio',
  wav: 'file-type-audio',
  ogg: 'file-type-audio',
  flac: 'file-type-audio',
  aac: 'file-type-audio',
  m4a: 'file-type-audio',

  ttf: 'file-type-font',
  otf: 'file-type-font',
  woff: 'file-type-font',
  woff2: 'file-type-font',
  eot: 'file-type-font',

  zip: 'file-type-zip',
  tar: 'file-type-zip',
  gz: 'file-type-zip',
  tgz: 'file-type-zip',
  bz2: 'file-type-zip',
  xz: 'file-type-zip',
  '7z': 'file-type-zip',
  rar: 'file-type-zip',

  sql: 'file-type-sql',
  sqlite: 'file-type-sqlite',
  sqlite3: 'file-type-sqlite',
  db: 'file-type-db',

  graphql: 'file-type-graphql',
  gql: 'file-type-graphql',
  proto: 'file-type-protobuf',
  prisma: 'file-type-prisma',

  bin: 'file-type-binary',
  exe: 'file-type-binary',
  wasm: 'file-type-wasm',
  patch: 'file-type-diff',
  diff: 'file-type-diff',
  ipynb_checkpoints: 'file-type-jupyter',
  tex: 'file-type-tex',
  bib: 'file-type-bibtex',

}

const FOLDER_NAMED: Record<string, string> = {
  src: 'folder-type-src',
  source: 'folder-type-src',
  sources: 'folder-type-src',
  app: 'folder-type-app',
  apps: 'folder-type-app',
  pages: 'folder-type-view',
  views: 'folder-type-view',
  view: 'folder-type-view',
  components: 'folder-type-component',
  component: 'folder-type-component',
  hooks: 'folder-type-hook',
  hook: 'folder-type-hook',
  lib: 'folder-type-library',
  libs: 'folder-type-library',
  library: 'folder-type-library',
  utils: 'folder-type-tools',
  util: 'folder-type-tools',
  helpers: 'folder-type-helper',
  helper: 'folder-type-helper',
  api: 'folder-type-api',
  apis: 'folder-type-api',
  controllers: 'folder-type-controller',
  controller: 'folder-type-controller',
  services: 'folder-type-services',
  service: 'folder-type-services',
  models: 'folder-type-model',
  model: 'folder-type-model',
  modules: 'folder-type-module',
  module: 'folder-type-module',
  store: 'folder-type-redux',
  stores: 'folder-type-redux',
  redux: 'folder-type-redux',
  test: 'folder-type-test',
  tests: 'folder-type-test',
  __tests__: 'folder-type-test',
  spec: 'folder-type-test',
  __mocks__: 'folder-type-mock',
  mocks: 'folder-type-mock',
  mock: 'folder-type-mock',
  fixtures: 'folder-type-mock',
  e2e: 'folder-type-e2e',
  cypress: 'folder-type-cypress',
  config: 'folder-type-config',
  configs: 'folder-type-config',
  configuration: 'folder-type-config',
  scripts: 'folder-type-script',
  script: 'folder-type-script',
  build: 'folder-type-dist',
  dist: 'folder-type-dist',
  out: 'folder-type-dist',
  output: 'folder-type-dist',
  target: 'folder-type-dist',
  bin: 'folder-type-binary',
  binary: 'folder-type-binary',
  binaries: 'folder-type-binary',
  public: 'folder-type-public',
  static: 'folder-type-public',
  www: 'folder-type-www',
  assets: 'folder-type-asset',
  asset: 'folder-type-asset',
  resources: 'folder-type-asset',
  images: 'folder-type-images',
  image: 'folder-type-images',
  img: 'folder-type-images',
  imgs: 'folder-type-images',
  icons: 'folder-type-favicon',
  icon: 'folder-type-favicon',
  fonts: 'folder-type-fonts',
  font: 'folder-type-fonts',
  styles: 'folder-type-style',
  style: 'folder-type-style',
  css: 'folder-type-css',
  scss: 'folder-type-sass',
  sass: 'folder-type-sass',
  less: 'folder-type-less',
  themes: 'folder-type-theme',
  theme: 'folder-type-theme',
  docs: 'folder-type-docs',
  doc: 'folder-type-docs',
  documentation: 'folder-type-docs',
  i18n: 'folder-type-locale',
  locales: 'folder-type-locale',
  locale: 'folder-type-locale',
  translations: 'folder-type-locale',
  translation: 'folder-type-locale',
  middleware: 'folder-type-middleware',
  middlewares: 'folder-type-middleware',
  routes: 'folder-type-route',
  route: 'folder-type-route',
  router: 'folder-type-route',
  routers: 'folder-type-route',
  routing: 'folder-type-route',
  layouts: 'folder-type-app',
  layout: 'folder-type-app',
  context: 'folder-type-shared',
  contexts: 'folder-type-shared',
  providers: 'folder-type-shared',
  shared: 'folder-type-shared',
  common: 'folder-type-common',
  commons: 'folder-type-common',
  core: 'folder-type-app',
  types: 'folder-type-typescript',
  type: 'folder-type-typescript',
  typings: 'folder-type-typings',
  '@types': 'folder-type-typings',
  interfaces: 'folder-type-interfaces',
  interface: 'folder-type-interfaces',
  schema: 'folder-type-graphql',
  schemas: 'folder-type-graphql',
  graphql: 'folder-type-graphql',
  database: 'folder-type-db',
  db: 'folder-type-db',
  prisma: 'folder-type-prisma',

  '.git': 'folder-type-git',
  '.github': 'folder-type-github',
  '.gitlab': 'folder-type-gitlab',
  '.vscode': 'folder-type-vscode',
  '.idea': 'folder-type-idea',
  '.cursor': 'folder-type-cursor',
  '.devcontainer': 'folder-type-devcontainer',
  '.husky': 'folder-type-husky',
  '.next': 'folder-type-next',
  '.nuxt': 'folder-type-nuxt',
  '.expo': 'folder-type-expo',
  '.docker': 'folder-type-docker',
  '.aws': 'folder-type-aws',
  '.azure': 'folder-type-azure',
  '.gcp': 'folder-type-gcp',
  '.gemini': 'folder-type-gemini',
  '.claude': 'folder-type-claude',
  '.junie': 'folder-type-junie',
  '.windsurf': 'folder-type-windsurf',
  '.zed': 'folder-type-zed',
  '.changesets': 'folder-type-changesets',
  '.changeset': 'folder-type-changesets',
  '.dependabot': 'folder-type-dependabot',
  '.circleci': 'folder-type-circleci',
  '.travis': 'folder-type-travis',
  '.history': 'folder-type-temp',
  '.cache': 'folder-type-temp',
  '.tmp': 'folder-type-temp',
  '.temp': 'folder-type-temp',

  node_modules: 'folder-type-node',
  vendor: 'folder-type-package',
  packages: 'folder-type-package',
  package: 'folder-type-package',
  plugin: 'folder-type-plugin',
  plugins: 'folder-type-plugin',
  tools: 'folder-type-tools',
  tool: 'folder-type-tools',
  cli: 'folder-type-cli',
  template: 'folder-type-template',
  templates: 'folder-type-template',

  'src-tauri': 'folder-type-tauri',
  'src-svelte': 'folder-type-svelte',
  rust: 'folder-type-cargo',
  cargo: 'folder-type-cargo',

  nginx: 'folder-type-nginx',
  apache: 'folder-type-apache',
  redis: 'folder-type-redis',
  mongodb: 'folder-type-mongodb',
  mongo: 'folder-type-mongodb',
  mysql: 'folder-type-mysql',
  mariadb: 'folder-type-mariadb',

  android: 'folder-type-android',
  ios: 'folder-type-ios',
  linux: 'folder-type-linux',
  macos: 'folder-type-macos',
  windows: 'folder-type-windows',
  client: 'folder-type-client',
  server: 'folder-type-server',
  frontend: 'folder-type-client',
  backend: 'folder-type-server',
  k8s: 'folder-type-kubernetes',
  kubernetes: 'folder-type-kubernetes',
  electron: 'folder-type-electron',
  flutter: 'folder-type-flutter',
  godot: 'folder-type-godot',
  story: 'folder-type-story',
  stories: 'folder-type-story',
  storybook: 'folder-type-story',
  '.storybook': 'folder-type-story',
  notebooks: 'folder-type-notebooks',
  coverage: 'folder-type-coverage',
  '.nyc_output': 'folder-type-coverage',
}

export function getFileIconId(
  name: string,
  isDir: boolean,
  expanded: boolean,
): string {
  if (!name) return isDir ? (expanded ? DEFAULT_FOLDER_OPEN : DEFAULT_FOLDER) : DEFAULT_FILE
  const lower = name.toLowerCase()
  if (isDir) {
    const named = FOLDER_NAMED[lower]
    if (named) return `${PREFIX}${named}${expanded ? '-opened' : ''}`
    return expanded ? DEFAULT_FOLDER_OPEN : DEFAULT_FOLDER
  }

  const exact = NAMED[lower]
  if (exact) return `${PREFIX}${exact}`

  if (lower.endsWith('.d.ts')) return `${PREFIX}file-type-typescriptdef`
  if (lower.endsWith('.test.ts') || lower.endsWith('.spec.ts')) {
    return `${PREFIX}file-type-typescript`
  }
  if (lower.endsWith('.test.tsx') || lower.endsWith('.spec.tsx')) {
    return `${PREFIX}file-type-reactts`
  }
  if (lower.endsWith('.test.js') || lower.endsWith('.spec.js')) {
    return `${PREFIX}file-type-js`
  }
  if (lower.endsWith('.stories.ts') || lower.endsWith('.stories.tsx')) {
    return `${PREFIX}file-type-storybook`
  }
  if (lower.endsWith('.module.css')) return `${PREFIX}file-type-css`
  if (lower.endsWith('.module.scss')) return `${PREFIX}file-type-scss`

  const dot = lower.lastIndexOf('.')
  if (dot > 0 && dot < lower.length - 1) {
    const ext = lower.slice(dot + 1)
    const byExt = BY_EXT[ext]
    if (byExt) return `${PREFIX}${byExt}`
  }

  if (lower.startsWith('.')) return `${PREFIX}file-type-text`
  return DEFAULT_FILE
}
