// @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 config = tseslint.config({
  extends: [
    eslint.configs.recommended,
    eslintPrettier,
    ...tseslint.configs.recommended,
  ],
  ignores: [
    // establishment of ignore and include paths for eslint
    'dist/**',
    'router.ts',
    'graphql/lib/**',
    'shared/lib/**',
    '*.generated.ts',
    'vite.config.mts',
    'eslint.config.cjs',
    '.yarn/**',
  ],
  plugins: {
    '@typescript-eslint': tseslint.plugin,
    react: reactPlugin,
    'react-hooks': hooksPlugin,
  },
  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,
    },
  },
  // @ts-ignore
  rules: {
    // typescript-eslint plugin configuration
    '@typescript-eslint/no-useless-template-literals': 'error',
    '@typescript-eslint/no-unsafe-argument': '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' },
    ],

    // 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': 'warn',

    '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',
          },
        ],
      },
    ],

    // react plugin configuration
    ...reactPlugin.configs.recommended.rules,
    ...reactPlugin.configs['jsx-runtime'].rules,
    'react/hook-use-state': 'error',
    'react/self-closing-comp': 'error',
    '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',
  },
  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'],
})

module.exports = config
