module.exports = {
  root: true,
  env: {
    browser: true,
  },
  extends: ['airbnb', 'airbnb/hooks', 'prettier'],
  parser: '@typescript-eslint/parser',
  globals: {
    document: true,
    window: true,
    event: true,
    ACMS: true,
    google: true,
    prettyPrint: true,
    _: true,
    $: true,
    jQuery: true,
  },
  rules: {
    // 特定のプロパティの利用を禁止（eslint-config-airbnbの上書き）
    'no-restricted-properties': [
      'error',
      // arguments.calleeの利用を許可
      // {
      //   object: 'arguments',
      //   property: 'callee',
      //   message: 'arguments.callee is deprecated,'
      // },
      {
        object: 'global',
        property: 'isFinite',
        message: 'Please use Number.isFinite instead',
      },
      {
        object: 'self',
        property: 'isFinite',
        message: 'Please use Number.isFinite instead',
      },
      {
        object: 'window',
        property: 'isFinite',
        message: 'Please use Number.isFinite instead',
      },
      {
        object: 'global',
        property: 'isNaN',
        message: 'Please use Number.isNaN instead',
      },
      {
        object: 'self',
        property: 'isNaN',
        message: 'Please use Number.isNaN instead',
      },
      {
        object: 'window',
        property: 'isNaN',
        message: 'Please use Number.isNaN instead',
      },
      {
        property: '__defineGetter__',
        message: 'Please use Object.defineProperty instead.',
      },
      {
        property: '__defineSetter__',
        message: 'Please use Object.defineProperty instead.',
      },
      {
        object: 'Math',
        property: 'pow',
        message: 'Use the exponentiation operator (**) instead.',
      },
    ],
    // 特定の構文を禁止（eslint-config-airbnbの上書き）
    'no-restricted-syntax': [
      'error',
      // 'ForInStatement', for..in文の利用を許可
      'LabeledStatement',
      'WithStatement',
    ],
    'jsx-a11y/label-has-associated-control': [
      'error',
      {
        assert: 'either', // 変更
      },
    ],
    // import時に拡張子の省略を禁止
    'import/extensions': [
      'error',
      // ↓は省略を許可
      {
        js: 'never',
        jsx: 'never',
        ts: 'never',
        tsx: 'never',
      },
    ],
    // package.jsonのdependenciesに記載されているモジュールのみをimport可能にする
    // testファイルはdevDependenciesに記載されているモジュールもimport可能にする
    'import/no-extraneous-dependencies': [
      'error',
      {
        devDependencies: ['**/*.test.{js,ts,jsx,tsx}', '**/*.spec.{js,ts,jsx,tsx}'],
      }
    ],
    // jsxを利用する場合のファイル名を強制
    'react/jsx-filename-extension': [
      'error',
      {
        extensions: ['.jsx', '.tsx', 'js'],
      },
    ],
    // 関数コンポーネントはアロー関数を強制
    'react/function-component-definition': [
      'error',
      {
        namedComponents: 'arrow-function',
        unnamedComponents: 'arrow-function',
      },
    ],
    'react-hooks/exhaustive-deps': [
      'warn',
      {
        // accepts a regex to match the names of custom Hooks that have dependencies.
        additionalHooks: '(useUpdateEffect)',
      },
    ],
    // 同じ名前の変数を許可
    'no-shadow': 'off',
    // アンダースコアを許可
    'no-underscore-dangle': 'off',
    // thisを使用しないクラスを許可
    'class-methods-use-this': 'off',
    // 関数の引数への代入を許可
    'no-param-reassign': 'off',
    // case文でのレキシカル宣言を許可
    'no-case-declarations': 'off',
    // continueを許可
    'no-continue': 'off',
    // 未宣言の変数の使用を許可
    'no-undef': 'off',
    // 最大行長を強制しない
    'max-len': 'off',
    // exportするモジュールが1つの場合でもnamed exportを許可
    'import/prefer-default-export': 'off',
    // Reactコンポーネント内でメソッドの順番を強制しない
    'react/sort-comp': 'off',
    // propsでのbindを許可
    'react/jsx-no-bind': 'off',
    // props-typeの未定義を許可
    'react/prop-types': 'off',
    // propsをスプレッド構文で渡すことを許可
    'react/jsx-props-no-spreading': 'off',
    // 分割代入を強制しない
    'react/destructuring-assignment': 'off',
    // default propsの定義を強制しない
    'react/require-default-props': 'off',
    // 静的プロパティの位置を強制しない
    'react/static-property-placement': 'off',
    // 未使用stateを許可
    'react/no-unused-state': 'off',
    // defaultPropsとpropTypesの一致を強制しない
    'react/default-props-match-prop-types': 'off',
    // button要素にtype属性を強制
    'react/button-has-type': [
      'error',
      {
        reset: true,
      },
    ],
    // React18対応
    'react/jsx-uses-react': 'off',
    // React18対応
    'react/react-in-jsx-scope': 'off',
    // 無名関数を許可
    'func-names': 'off',
    // if文でのfor-in文を許可
    'guard-for-in': 'off',
    // ++を許可
    'no-plusplus': 'off',
    // arguments.caller, arguments.calleeを許可
    'no-caller': 'off',
    // 値を返さないreturn文を許可
    'consistent-return': 'off',
    // 特定のグローバル変数の使用を制限をしない
    'no-restricted-globals': 'off',
    // アラートの使用を許可
    'no-alert': 'off',
    // 未使用の変数を許可
    'no-unused-vars': 'off',
    // 'React' was used before it was defined 対策
    'no-use-before-define': 'off',
    // camelcaseに警告
    camelcase: 'warn',
    'arrow-body-style': 'off',
  },
  overrides: [
    // プロジェクトにJavaScriptとTypeScriptが共存しているため、
    // ts, tsxの拡張子のファイルは別途TypeScript用のルールを適用
    {
      files: ['**/*.ts', '**/*.tsx'],
      extends: ['plugin:@typescript-eslint/recommended'],
      plugins: ['@typescript-eslint'],
      rules: {
        // 未使用変数を禁止
        '@typescript-eslint/no-unused-vars': 'error',
        // 定義前の変数の使用に警告
        '@typescript-eslint/no-use-before-define': 'warn',
        // 空の関数を許可
        '@typescript-eslint/no-empty-function': 'off',
      },
    },
  ],
  settings: {
    'import/resolver': {
      webpack: {
        config: 'webpack.prod.js',
      },
      typescript: {},
    },
  },
};
