import globals from 'globals';
import typescriptParser from '@typescript-eslint/parser';
import typescriptPlugin from '@typescript-eslint/eslint-plugin';
import { fixupPluginRules } from '@eslint/compat';
import stylisticPlugin from '@stylistic/eslint-plugin';
import filenamesPlugin from 'eslint-plugin-filenames';
import { importX as importPlugin } from 'eslint-plugin-import-x';
import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript';
import barrelFilesPlugin from 'eslint-plugin-barrel-files';
import prettierPlugin from 'eslint-plugin-prettier';
import promisePlugin from 'eslint-plugin-promise';
import baseRules from '../rules/base.mjs';
import stylisticRules from '../rules/stylistic.mjs';
import promiseRules from '../rules/promise.mjs';
import filenameRules from '../rules/filenames.mjs';
import importRules from '../rules/import.mjs';
import typescriptRules from '../rules/typescript.mjs';
import barrelFilesRules from '../rules/barrel-files.mjs';

export default [
  {
    linterOptions: {
      reportUnusedDisableDirectives: 'error',
    },
    languageOptions: {
      parser: typescriptParser,
      parserOptions: {
        sourceType: 'module',
        project: './tsconfig.json',
        ecmaVersion: 2024,
      },
      globals: {
        ...globals.es2024,
      },
    },
    plugins: {
      '@stylistic': stylisticPlugin,
      '@typescript-eslint': typescriptPlugin,
      'barrel-files': barrelFilesPlugin,
      filenames: fixupPluginRules(filenamesPlugin),
      'import-x': importPlugin,
      prettier: prettierPlugin,
      promise: promisePlugin,
    },
    settings: {
      'import-x/extensions': ['.ts', '.cts', '.mts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'],

      'import-x/external-module-folders': ['node_modules', 'node_modules/@types'],

      'import-x/parsers': {
        // omit `.d.ts` because
        //   1) TypeScript compilation already confirms that types are resolved, and
        //   2) it would mask an unresolved `.ts`/`.tsx`/`.js`/`.jsx` implementation.
        '@typescript-eslint/parser': ['.ts', '.cts', '.mts', '.tsx'],
      },

      'import-x/resolver-next': [
        createTypeScriptImportResolver({
          // always try to resolve types under `<root>@types` directory even it doesn't contain any source code, like `@types/lodash`
          alwaysTryTypes: true,

          // use <root>/path/to/folder/tsconfig.json
          project: '<root>/tsconfig.json',
        }),
      ],
    },
    rules: {
      ...baseRules,
      ...stylisticRules,
      ...barrelFilesRules,
      ...filenameRules,
      ...importRules,
      ...promiseRules,
      ...typescriptRules,

      'import-x/named': 'off', // conflicts with TS's type system
      'import-x/no-unused-modules': 'off', // false positives
      'prettier/prettier': 'error',
    },
  },
];
