import eslint from '@eslint/js';
import eslintConfigPrettier from 'eslint-config-prettier';
import * as importPlugin from 'eslint-plugin-import';
import eslintPluginPrettier from 'eslint-plugin-prettier/recommended';
import eslintPluginReact from 'eslint-plugin-react';
import globals from 'globals';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  // config with just ignores is the replacement for `.eslintignore`
  {
    ignores: [
      '**/.*',
      '**/node_modules/**',
      '**/hardhat/**',
      '**/dist/**',
      '**/public/**',
      '**/cweb_tool/**',
      '**/cweb_dist/**',
      '**/build/**',
      '**/dapp-ui/src/pages/Bot/**',
      '**/dapp-ui/src/pages/BotHedging/**',
      '**/dapp-ui/src/pages/SwapTool/**',
    ],
  },
  // rest of the config by module

  // eslint
  {
    rules: {
      ...eslint.configs.recommended.rules,
      'no-console': ['warn', { allow: ['error'] }],
      'no-bitwise': 'error',
      'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
    },
  },
  {
    files: ['**/*.js', '**/*.mjs'],
    languageOptions: {
      sourceType: 'module',
      parserOptions: { ecmaVersion: 'latest' },
      globals: { ...globals.node, ...globals.browser },
    },
  },
  {
    files: ['**/*.cjs'],
    languageOptions: {
      sourceType: 'commonjs',
      parserOptions: { ecmaVersion: 'latest' },
      globals: { ...globals.node, ...globals.browser },
    },
  },

  // prettier
  eslintPluginPrettier,
  eslintConfigPrettier,

  // typescript
  ...tseslint.configs.recommendedTypeChecked.map((config) => ({
    ...config,
    files: ['**/*.ts', '**/*.tsx'], // We use TS config only for TS files
  })),
  {
    files: ['**/*.ts', '**/*.tsx'], // We use TS config only for TS files
    plugins: {
      '@typescript-eslint': tseslint.plugin,
    },
    languageOptions: {
      parser: tseslint.parser,
      parserOptions: {
        project: ['tsconfig.eslint.json', './packages/*/tsconfig.json'],
        tsconfigRootDir: import.meta.dirname,
      },
    },
    rules: {
      '@typescript-eslint/no-unused-vars': [
        'error',
        {
          argsIgnorePattern: '^_',
          varsIgnorePattern: '^_',
          caughtErrorsIgnorePattern: '^_',
        },
      ],
      '@typescript-eslint/no-explicit-any': 'error',
      '@typescript-eslint/ban-ts-comment': 'off',
      '@typescript-eslint/no-misused-promises': ['error', { checksVoidReturn: false }],
      '@typescript-eslint/no-empty-object-type': 'off',
      '@typescript-eslint/no-unnecessary-type-assertion': 'off',
      '@typescript-eslint/prefer-promise-reject-errors': 'off',
      '@typescript-eslint/no-unsafe-enum-comparison': 'off',
      '@typescript-eslint/no-unsafe-member-access': 'off',
      '@typescript-eslint/no-unsafe-argument': 'off',
      '@typescript-eslint/no-unsafe-assignment': 'off',
      '@typescript-eslint/restrict-template-expressions': 'off',
      '@typescript-eslint/no-base-to-string': 'warn',
      '@typescript-eslint/naming-convention': [
        'warn',
        {
          selector: 'variable',
          types: ['boolean'],
          format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
          prefix: ['is', 'should', 'has', 'can', 'did', 'use'],
          filter: {
            regex: '^_',
            match: false,
          },
        },
        {
          selector: 'variable',
          format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
          filter: {
            regex: '^_',
            match: false,
          },
        },
      ],
      '@typescript-eslint/explicit-function-return-type': [
        'off',
        {
          allowTypedFunctionExpressions: true,
        },
      ],
      '@typescript-eslint/no-floating-promises': 'off',
      '@typescript-eslint/require-await': 'off',
    },
  },

  // import-plugin
  {
    ...importPlugin.flatConfigs.recommended,
    rules: {
      'import/named': 'off',
      'import/newline-after-import': 'error',
      'import/order': [
        'warn',
        {
          'newlines-between': 'always',
          alphabetize: { order: 'asc' },
          groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
          pathGroupsExcludedImportTypes: ['react'],
          pathGroups: [
            { pattern: 'react', group: 'builtin', position: 'before' },
            { pattern: '@/**', group: 'external', position: 'after' },
          ],
        },
      ],
    },
  },
  {
    ...importPlugin.flatConfigs.typescript,
    settings: {
      alias: {
        map: [['@', './src']],
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
    },
  },

  // react, dapp-ui
  {
    files: ['packages/dapp-ui/src/**/*.jsx', 'packages/dapp-ui/src/**/*.tsx'],
    ...eslintPluginReact.configs.flat.recommended,
    settings: { react: { version: 'detect' } },
    rules: {
      ...eslintPluginReact.configs.flat.recommended.rules,
      'react/react-in-jsx-scope': 'off',
      'react/prop-types': 'off',
    },
  }
);
