import eslintJs from '@eslint/js';
import { defineConfig } from 'eslint/config';
import globals from 'globals';
import { includeIgnoreFile } from '@eslint/compat'; // Added for .gitignore
import { fileURLToPath } from 'node:url'; // Added for .gitignore path
import eslintPluginJsdoc from 'eslint-plugin-jsdoc';
import eslintPluginN from 'eslint-plugin-n';
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
import tseslint from 'typescript-eslint';
import eslintPluginVitest from '@vitest/eslint-plugin';
import eslintConfigPrettier from 'eslint-config-prettier';

const gitignorePath = fileURLToPath(new URL('.gitignore', import.meta.url));

export default defineConfig(
  includeIgnoreFile(gitignorePath), // Handle .gitignore patterns

  // Global linter options
  {
    linterOptions: {
      reportUnusedDisableDirectives: true, // Enable reporting of unused disable directives
    },
  },

  // Base configurations for all relevant files
  eslintJs.configs.recommended, // Basic ESLint recommended rules

  {
    // JSDoc configuration
    plugins: { jsdoc: eslintPluginJsdoc },
    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
    rules: {
      ...eslintPluginJsdoc.configs.recommended.rules,
      'jsdoc/require-jsdoc': 0,
      'jsdoc/tag-lines': [2, 'any', { startLines: 1 }],
      'jsdoc/require-param-type': 0,
      'jsdoc/require-returns-type': 0,
      'jsdoc/no-types': 2,
      'jsdoc/require-returns-check': 0, // Was in TS override, better here
    },
    settings: {
      jsdoc: {
        mode: 'typescript',
        tagNamePreference: { category: 'category' },
      },
    },
  },

  {
    // Node plugin configuration
    plugins: { n: eslintPluginN },
    rules: {
      ...eslintPluginN.configs.recommended.rules,
      'n/file-extension-in-import': [2, 'always'],
      'n/no-missing-import': 0,
    },
  },

  {
    // Unicorn plugin configuration
    plugins: { unicorn: eslintPluginUnicorn },
    rules: {
      ...eslintPluginUnicorn.configs.recommended.rules,
      'unicorn/no-null': 0,
      'unicorn/prevent-abbreviations': 0,
      'unicorn/prefer-code-point': 0,
      'unicorn/no-for-loop': 0,
      'unicorn/no-array-callback-reference': 0,
      'unicorn/prefer-spread': 0,
      'unicorn/no-useless-undefined': 0,
      'unicorn/no-array-reduce': 0,
      'unicorn/prefer-array-find': 0,
      'unicorn/prefer-module': 0,
      'unicorn/prefer-at': 0,
      'unicorn/prefer-string-replace-all': 0,
      'unicorn/prefer-switch': [2, { emptyDefaultCase: 'do-nothing-comment' }],
    },
  },

  // Global custom rules and language options
  {
    languageOptions: {
      globals: globals.node,
      parserOptions: {
        projectService: {
          allowDefaultProject: ['*.js'],
          defaultProject: 'tsconfig.json',
        },
        tsconfigRootDir: import.meta.dirname, // eslint-disable-line n/no-unsupported-features/node-builtins
      },
    },
    rules: {
      'array-callback-return': [2, { allowImplicit: true }],
      'no-lonely-if': 2,
      'no-proto': 2,
      eqeqeq: [2, 'smart'],
      'no-caller': 2,
      'dot-notation': 2,
      'no-var': 2,
      'prefer-const': 2,
      'prefer-arrow-callback': [2, { allowNamedFunctions: true }],
      'arrow-body-style': [2, 'as-needed'],
      'object-shorthand': 2,
      'prefer-template': 2,
      'one-var': [2, 'never'],
      'prefer-destructuring': [2, { object: true }],
      'capitalized-comments': 2,
      'multiline-comment-style': [2, 'starred-block'],
      'spaced-comment': 2,
      yoda: [2, 'never'],
      curly: [2, 'multi-line'],
      'no-else-return': [2, { allowElseIf: false }],
      'no-unused-expressions': 2,
      'no-useless-call': 2,
      'no-use-before-define': [2, 'nofunc'],
      'no-constant-binary-expression': 2,
      'no-void': 2,
    },
  },

  // TypeScript specific configurations
  tseslint.configs.recommendedTypeChecked,
  tseslint.configs.stylisticTypeChecked,
  {
    // Custom overrides and settings for TypeScript files
    files: ['**/*.ts', '**/*.mts', '**/*.cts'], // Ensure this block specifically targets TS files
    rules: {
      // Override base ESLint rules for TS
      'dot-notation': 0,
      'no-use-before-define': 0,
      // "curly" is already defined globally with [2, "multi-line"]

      // Rule from original TS override related to Node features
      'n/no-unsupported-features/es-syntax': 0,

      // Original TypeScript specific rules
      '@typescript-eslint/prefer-for-of': 0,
      '@typescript-eslint/member-ordering': 0,
      '@typescript-eslint/explicit-function-return-type': 0,
      '@typescript-eslint/no-unused-vars': [
        'error',
        { argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
      ],
      '@typescript-eslint/no-use-before-define': [
        2,
        {
          functions: false,
          classes: true,
          variables: true,
          enums: true,
          typedefs: true,
        },
      ],
      '@typescript-eslint/consistent-type-definitions': [2, 'interface'],
      '@typescript-eslint/prefer-function-type': 2,
      '@typescript-eslint/no-unnecessary-type-arguments': 2,
      '@typescript-eslint/prefer-string-starts-ends-with': 2,
      '@typescript-eslint/prefer-readonly': 2,
      '@typescript-eslint/prefer-includes': 2,
      '@typescript-eslint/switch-exhaustiveness-check': 2,
      '@typescript-eslint/prefer-nullish-coalescing': 2,
      '@typescript-eslint/no-non-null-assertion': 1,
      '@typescript-eslint/consistent-type-imports': 2,
      '@typescript-eslint/no-explicit-any': 1, // TODO
    },
  },

  // Vitest specific configuration (for *.spec.ts files)
  {
    files: ['**/*.spec.ts'],
    plugins: { vitest: eslintPluginVitest },
    languageOptions: {
      globals: {
        ...globals.vitest, // Add Vitest globals
      },
    },
    rules: {
      // Assuming "recommended" is the flat config equivalent for "legacy-recommended"
      ...eslintPluginVitest.configs.recommended.rules,
      'n/no-unpublished-import': 0, // Allow importing devDependencies
      '@typescript-eslint/no-explicit-any': 0, // Allow `any` in tests
      '@typescript-eslint/no-non-null-assertion': 0, // Allow `!` assertions in tests
    },
  },

  // Website specific configuration
  {
    files: ['website/**/*.ts', 'website/**/*.tsx', 'website/**/*.mts'],
    languageOptions: {
      parserOptions: {
        projectService: {
          allowDefaultProject: ['*.mjs'],
        },
        tsconfigRootDir: `${import.meta.dirname}/website`, // eslint-disable-line n/no-unsupported-features/node-builtins
      },
    },
  },

  // Prettier - must be the last configuration to override styling rules
  eslintConfigPrettier,
);
