// @ts-check

const globals = require('globals')
const eslint = require('@eslint/js')
const eslintPrettier = require('eslint-config-prettier')
const tseslint = require('typescript-eslint')
const reactPlugin = require('eslint-plugin-react')
const hooksPlugin = require('eslint-plugin-react-hooks')
const emotionPlugin = require('@emotion/eslint-plugin')
const reactCompiler = require('eslint-plugin-react-compiler')

const config = tseslint.config(
  {
    extends: [
      eslint.configs.recommended,
      eslintPrettier,
      ...tseslint.configs.recommended,
    ],
    rules: {
      // typescript-eslint plugin configuration
      // '@typescript-eslint/no-useless-template-literals': 'error',
      '@typescript-eslint/no-unnecessary-template-expression': 'off',
      '@typescript-eslint/no-unsafe-assignment': 'off',
      '@typescript-eslint/no-unsafe-call': 'off',
      '@typescript-eslint/no-unsafe-member-access': 'off',
      '@typescript-eslint/no-unsafe-return': 'off',
      '@typescript-eslint/ban-ts-comment': 'off',
      '@typescript-eslint/consistent-type-imports': [
        'error',
        { prefer: 'type-imports' },
      ],

      'react-compiler/react-compiler': 'error',

      // basal eslint rules
      'no-template-curly-in-string': 'error',
      'prefer-template': 'error',
      'no-lone-blocks': 'error',
      'multiline-comment-style': ['error', 'starred-block'],
      'arrow-body-style': ['error', 'as-needed'],
      'no-console': 'off',

      // react plugin configuration
      ...reactPlugin.configs.recommended.rules,
      ...reactPlugin.configs['jsx-runtime'].rules,
      'react/hook-use-state': 'error',
      'react/self-closing-comp': 'error',
      'react/prop-types': 'off',
      'react/function-component-definition': [
        2,
        {
          namedComponents: 'arrow-function',
        },
      ],
      'react/prefer-stateless-function': [
        2,
        {
          ignorePureComponents: true,
        },
      ],
      'react/react-in-jsx-scope': 'off',
      'react/iframe-missing-sandbox': 'error',
      'react/jsx-boolean-value': 'error',
      'react/jsx-curly-spacing': [
        'error',
        {
          when: 'never',
        },
      ],
      'react/jsx-equals-spacing': ['error', 'never'],
      'react/jsx-first-prop-new-line': ['error', 'multiline'],
      'react/jsx-fragments': ['error', 'syntax'],

      // react-hooks plugin configuration
      'react-hooks/rules-of-hooks': 'error',
      'react-hooks/exhaustive-deps': 'warn',

      // emotion plugin configuration
      'react/no-unknown-property': ['error', { ignore: ['css'] }],
    },

    languageOptions: {
      parser: tseslint.parser,
      parserOptions: {
        project: [
          './frontend/tsconfig.json',
          './graphql/tsconfig.json',
          './shared/tsconfig.json',
        ],
        jsxPragma: 'React',
        tsconfigRootDir: __dirname,
      },
      globals: {
        ...globals.node,
        ...globals.browser,
        ...globals.es2021,
      },
    },
    ignores: [
      // establishment of ignore and include paths for eslint
      'dist/**',
      'router.ts',
      'graphql/lib/**',
      'shared/lib/**',
      'vite.config.mts',
      'eslint.config.cjs',
      '.yarn/**',
    ],
    plugins: {
      '@typescript-eslint': tseslint.plugin,
      react: reactPlugin,
      // @ts-ignore
      'react-hooks': hooksPlugin,
      'react-compiler': reactCompiler,
      '@emotion': emotionPlugin,
    },
    settings: {
      react: {
        version: 'detect',
      },
      parserOptions: {
        ecmaFeatures: {
          jsx: true,
        },
      },
    },
    files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
    // there is a lack of typing in TSESlint for this property
    // @ts-ignore
    ignores: ['**/*.d.ts'],
  },
  {
    rules: {
      'no-restricted-imports': [
        'warn',
        {
          patterns: [
            {
              group: ['@/router', 'react-router-dom'],
              importNames: ['useParams'],
              message:
                'useParams is currently deprecated, please refactor to not use it or explicitly declare ignoration, see issue #195',
            },
          ],
        },
      ],
      // emotion plugin configuration
      'react/no-unknown-property': ['error', { ignore: ['css'] }],
    },

    languageOptions: {
      parser: tseslint.parser,
      parserOptions: {
        project: [
          './frontend/tsconfig.json',
          './graphql/tsconfig.json',
          './shared/tsconfig.json',
        ],
        jsxPragma: 'React',
        tsconfigRootDir: __dirname,
      },
      globals: {
        ...globals.node,
        ...globals.browser,
        ...globals.es2021,
      },
    },
    ignores: [
      // establishment of ignore and include paths for eslint
      'dist/**',
      'router.ts',
      'graphql/lib/**',
      'shared/lib/**',
      'vite.config.mts',
      'eslint.config.cjs',
      '.yarn/**',
    ],
    plugins: {
      '@typescript-eslint': tseslint.plugin,
      react: reactPlugin,
      // @ts-ignore
      'react-hooks': hooksPlugin,
      'react-compiler': reactCompiler,
      '@emotion': emotionPlugin,
    },
    settings: {
      react: {
        version: 'detect',
      },
      parserOptions: {
        ecmaFeatures: {
          jsx: true,
        },
      },
    },
    files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
    // there is a lack of typing in TSESlint for this property
    // @ts-ignore
    ignores: ['**/*.d.ts', 'frontend/src/pages/**/*'],
  }
)

module.exports = config
