import { JavascriptRules, PluginRules, RuleOptions } from "./eslintRules.mjs";
import { VueOptions } from "./options/vue.mjs";
import { ZodOptions } from "./options/zod.mjs";
import { NuxtOptions } from "./options/nuxt.mjs";
import { TestOptions } from "./options/test.mjs";
import { ReactOptions } from "./options/react.mjs";
import { BaselineOptions } from "./options/baseline.mjs";
import { MarkdownOptions } from "./options/markdown.mjs";
import { TailwindOptions } from "./options/tailwind.mjs";
import { StylisticOptions } from "./options/stylistic.mjs";
import { TypescriptOptions } from "./options/typescript.mjs";
import { Linter } from "eslint";
//#region src/types/index.d.ts
type ConfigOverrides = Pick<Linter.Config, 'name' | 'files' | 'ignores' | 'plugins' | 'settings' | 'languageOptions'>;
interface ConfigWithOverrides<ConfigRules extends Linter.RulesRecord> {
  /**
   * Override the current configuration object.
   *
   * The properties of this object are merged with and take precedence over the properties of the default configuration object.
   *
   * @see [eslint-flat-config-utils: `mergeConfigs`](https://jsr.io/@antfu/eslint-flat-config-utils/doc/~/mergeConfigs)
   */
  overrides?: ConfigOverrides & {
    /** The rules to override in the current configuration object. */
    rules?: ConfigRules;
  };
}
/** The options passed to the `defineConfig` function. */
interface Options {
  /**
   * Automatically enable configurations based on the detected dependencies, dev-dependencies, etc. in the _package.json_ file.
   *
   * Set to `'verbose'` to log the detected dependencies.
   *
   * Use the `packageDir` option to specify the path to the _package.json_ file.
   *
   * @default true
   */
  autoDetectDeps?: boolean | 'verbose';
  /**
   * Specify the runtime environment.
   *
   * This is used by
   * - `configs.baseline` option (disabled when `env` is set to a value other than `'browser'`)
   * - [ESLint: Specifying Globals](https://eslint.org/docs/latest/use/configure/language-options#using-configuration-files)
   * - [perfectionist/sort-imports: `env` option](https://perfectionist.dev/rules/sort-imports#environment)
   *
   * @default 'browser'
   */
  env?: 'bun' | 'deno' | 'node' | 'browser';
  /**
   * Path to the _.gitignore_ file (relative to the current working directory).
   *
   * ESLint will ignore files and directories found in your _.gitignore_ file. Set to `false` to disable this behavior.
   *
   * It will fall back to the default value if set to an empty string (`''`).
   *
   * @default '.gitignore'
   *
   * @see [ESLint Ignore: Including GitIgnore Files](https://eslint.org/docs/latest/use/configure/ignore#include-gitignore-files)
   */
  gitignore?: false | string;
  /**
   * Path to directory of the _package.json_ file (relative to the current working directory).
   *
   * This is used by
   * - `autoDetectDeps` option
   * - [import-x/no-extraneous-dependencies: `packageDir` option](https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-extraneous-dependencies.md#packagedir)
   * - [storybook/no-uninstalled-addons: `packageJsonLocation` option](https://github.com/storybookjs/storybook/blob/next/code/lib/eslint-plugin/docs/rules/no-uninstalled-addons.md#packagejsonlocation)
   *
   * It will fall back to the default value if set to an empty string (`''`).
   *
   * @default '.'
   */
  packageDir?: string;
  /**
   * The path and the name of the root TypeScript config file.
   *
   * This is used by
   * - [better-tailwindcss: `tsconfig` option](https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/settings/settings.md#tsconfig)
   * - [perfectionist/sort-imports: `tsconfig` option](https://perfectionist.dev/rules/sort-imports#tsconfig)
   *
   * @default false // `{ rootDir: options.packageDir ?? '.', filename: 'tsconfig.json' }` if TypeScript integration is enabled
   */
  tsConfig?: false | {
    /**
     * The directory of the root TypeScript config file.
     *
     * It will fall back to the default value if set to an empty string (`''`).
     *
     * @default options.packageDir ?? '.'
     */
    rootDir?: string;
    /**
     * The name of the root TypeScript config file.
     *
     * It will fall back to the default value if set to an empty string (`''`).
     *
     * @default 'tsconfig.json'
     */
    filename?: string;
  };
  /*** Project ***/
  /**
   * Configuration options applied to all files. Individual configurations will override these.
   *
   * @default
   * {
   *   basePath: '.',
   *   languageOptions: {
   *     parserOptions: {},
   *     sourceType: 'module',
   *     ecmaVersion: 'latest',
   *   },
   *   linterOptions: {
   *     noInlineConfig: false,
   *     reportUnusedInlineConfigs: 'warn',
   *     reportUnusedDisableDirectives: 'warn'
   *   }
   *   name: 'shayanthenerd/project',
   * }
   */
  project?: {
    /**
     * The base path for resolving `files` and `ignores` patterns.
     *
     * Glob patterns in the configuration objects will be resolved relative to this path.
     *
     * It will fall back to the default value if set to an empty string (`''`).
     *
     * @default '.'
     *
     * @see [ESLint Configuration: Specifying Base Path](https://eslint.org/docs/latest/use/configure/configuration-files#specifying-base-path)
     */
    basePath?: string;
    /**
     * Specify global variables.
     *
     * @default
     * {
     *   astro: false, // `true` if `configs.astro` is enabled
     *   audioWorklet: false, // `true` if `env` is set to `browser`
     *   browser: true, // `true` if `env` is set to `browser`
     *   bun: false, // `true` if `env` is set to `bun`
     *   commonjs: false,
     *   deno: false, // `true` if `env` is set to `deno`
     *   node: true,
     *   nodeBuiltin: false, // `true` if `env` is set to `node`
     *   serviceworker: false, // `true` if `env` is set to `browser`
     *   sharedWorker: false, // `true` if `env` is set to `browser`
     *   vitest: false,
     *   vue: false, // `true` if `configs.vue` is enabled
     *   webextension: false, // `true` if `env` is set to `browser`
     *   worker: true,
     *   custom: {},
     * }
     *
     * @see [Language Options: Specifying Globals](https://eslint.org/docs/latest/use/configure/language-options#using-configuration-files)
     */
    globals?: {
      astro?: boolean;
      audioWorklet?: boolean;
      browser?: boolean;
      bun?: boolean;
      commonjs?: boolean;
      deno?: boolean;
      node?: boolean;
      nodeBuiltin?: boolean;
      serviceworker?: boolean;
      sharedWorker?: boolean;
      vitest?: boolean;
      vue?: boolean;
      webextension?: boolean;
      worker?: boolean;
      custom?: Linter.LanguageOptions['globals'];
    };
    /**
     * Patterns that ESLint should ignore globally. These patterns are resolved relative to the current working directory.
     *
     * @see [ESLint Configuration: Globally Ignoring Files](https://eslint.org/docs/latest/use/configure/configuration-files#globally-ignoring-files-with-ignores)
     */
    ignores?: string[];
    /**
     * Specify the linting process.
     *
     * @see [ESLint Configuration: Linter Options](https://eslint.org/docs/latest/use/configure/configuration-files#configuring-linter-options)
     */
    linterOptions?: {
      /**
       * Disallow inline (comment) configurations and disable-directives.
       *
       * @default false
       *
       * @see [ESLint Configuration: Disabling Inline Configuration](https://eslint.org/docs/latest/use/configure/configuration-files#disabling-inline-configuration)
       */
      noInlineConfig?: Linter.LintOptions['allowInlineConfig'];
      /**
       * A severity string indicating if and how unused inline configs should be tracked and reported.
       *
       * @default 'warn'
       *
       * @see [ESLint Configuration: Reporting Unused Inline Configs](https://eslint.org/docs/latest/use/configure/configuration-files#reporting-unused-inline-configs)
       */
      reportUnusedInlineConfigs?: Linter.StringSeverity;
      /**
       * A severity string indicating if and how unused disable and enable directives should be tracked and reported.
       *
       * @default 'warn'
       *
       * @see [ESLint Configuration: Reporting Unused Disable Directives](https://eslint.org/docs/latest/use/configure/configuration-files#reporting-unused-disable-directives)
       */
      reportUnusedDisableDirectives?: Linter.StringSeverity;
    };
    /**
     * A name for the configuration object. This is used in error messages and [config inspector](https://github.com/eslint/config-inspector) to help identify which configuration object is being used.
     *
     * It will fall back to the default value if set to an empty string (`''`).
     *
     * @default 'shayanthenerd/eslint-config'
     *
     * @see [ESLint Configuration: Naming Conventions](https://eslint.org/docs/latest/use/configure/configuration-files#configuration-naming-conventions)
     */
    name?: string;
    /**
     * The available rules.
     *
     * @see [ESLint Configuration: Rules](https://eslint.org/docs/latest/use/configure/configuration-files#configuring-rules)
     */
    rules?: Linter.RulesRecord;
    /**
     * Settings shared across all rules. Use this to specify information that should be available to every rule.
     *
     * @see [ESLint Configuration: Shared Settings](https://eslint.org/docs/latest/use/configure/configuration-files#configuring-shared-settings)
     */
    settings?: Linter.Config['settings'];
  };
  /*** Configs ***/
  /**
   * Enable, disable, or customize the configurations.
   *
   * `autoDetectDeps` can enable configurations that are disabled by default. However, explicitly enabling or disabling a configuration takes precedence over `autoDetectDeps`.
   */
  configs?: {
    /**
     * Use [eslint-plugin-astro](https://ota-meshi.github.io/eslint-plugin-astro) and [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) to enforce Astro best practices and accessibility guidelines.
     *
     * @default false // `true` if "astro" is detected in the dependencies when `autoDetectDeps` is enabled
     */
    astro?: boolean | ConfigWithOverrides<PluginRules<'astro'>>;
    /**
     * Use [eslint-plugin-baseline-js](https://github.com/3ru/eslint-plugin-baseline-js), [css/use-baseline](https://github.com/eslint/css/blob/main/docs/rules/use-baseline.md#options), [@html-eslint/use-baseline](https://html-eslint.org/docs/rules/use-baseline#options), and [@html-eslint/react/use-baseline](https://github.com/eslint/css/blob/main/docs/rules/use-baseline.md#options) to enforce the use of baseline features.
     *
     * @default true // `false` if `env` is set to a value other than `'browser'`
     */
    baseline?: boolean | BaselineOptions;
    /**
     * Customize JavaScript (core) rules and options.
     *
     * This configuration cannot be disabled.
     */
    javascript?: ConfigWithOverrides<JavascriptRules> & {
      /**
       * Enforce a maximum depth that blocks can be nested to reduce code complexity.
       *
       * @default 3
       *
       * @see [max-depth](https://eslint.org/docs/latest/rules/max-depth)
       */
      maxDepth?: Exclude<RuleOptions<'max-depth'>, Record<string, unknown>>;
      /**
       * Enforce a maximum depth that callbacks can be nested to increase code clarity.
       *
       * @default 3
       *
       * @see [max-nested-callbacks](https://eslint.org/docs/latest/rules/max-nested-callbacks)
       */
      maxNestedCallbacks?: Exclude<RuleOptions<'max-nested-callbacks'>, Record<string, unknown>>;
    };
    /**
     * Use [@eslint/css](https://github.com/eslint/css) to enforce CSS best practices and identify mistakes.
     *
     * @default false
     */
    css?: boolean | ConfigWithOverrides<PluginRules<'css'>>;
    /**
     * Use [@html-eslint/eslint-plugin](https://html-eslint.org) to enforce SEO and accessibility best practices, as well as some stylistic rules.
     *
     * @default false
     */
    html?: boolean | (ConfigWithOverrides<PluginRules<'@html-eslint'>> & {
      /**
       * Enforce consistent naming convention for `id` attribute values.
       *
       * @default 'snake_case'
       *
       * @see [@html-eslint/id-naming-convention](https://html-eslint.org/docs/rules/id-naming-convention)
       */
      idNamingConvention?: Exclude<RuleOptions<'@html-eslint/id-naming-convention'>, 'regex'>;
    });
    /**
     * Use [eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x) to organize imports and exports, and detect related issues.
     *
     * @default true
     */
    importX?: boolean | ConfigWithOverrides<PluginRules<'import-x'>>;
    /**
     * Use [@eslint/markdown](https://github.com/eslint/markdown) to enforce best practices for Markdown files.
     *
     * @default true
     */
    markdown?: boolean | MarkdownOptions;
    /**
     * Use [@next/eslint-plugin-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-plugin-next) to enforce Next.js best practices and catch common mistakes.
     *
     * @default false // `true` if "next" is detected in the dependencies when `autoDetectDeps` is enabled
     */
    next?: boolean | ConfigWithOverrides<PluginRules<'next'>>;
    /**
     * Use [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n) to enforce Node.js best practices and catch common mistakes.
     *
     * Some rules depend on the specified Node.js version. Visit the documentation for [version-resolution options and project-specific configurations](https://github.com/eslint-community/eslint-plugin-n#configured-nodejs-version-range).
     *
     * @default true
     */
    node?: boolean | ConfigWithOverrides<PluginRules<'n'>>;
    /**
     * Use [@nuxt/eslint-plugin](https://eslint.nuxt.com/packages/plugin) and [nuxt-link-checker (ESLint plugin)](https://nuxtseo.com/docs/link-checker/guides/eslint) to enforce Nuxt best practices and catch broken links.
     *
     * Enforce best practices and the use of Nuxt-specific components over their counterparts. For example, `<NuxtLink>` must be used instead of `<a>`, and `<NuxtTime>` instead of `<time>`.
     *
     * @default false // `true` if "nuxt" is detected in the dependencies when `autoDetectDeps` is enabled
     */
    nuxt?: boolean | NuxtOptions;
    /**
     * Use [eslint-plugin-package-json](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json) to ensure _package.json_ files are consistent, readable, and valid.
     *
     * @default true
     */
    packageJson?: boolean | ConfigWithOverrides<PluginRules<'package-json'>>;
    /**
     * Use [eslint-plugin-perfectionist](https://perfectionist.dev) to sort imports, exports, maps, union types, etc.
     *
     * @default true
     */
    perfectionist?: boolean | (ConfigWithOverrides<PluginRules<'perfectionist'>> & {
      /**
       * The type of sorting.
       *
       * @default 'line-length'
       *
       * @see [Perfectionist Settings: `type` option](https://perfectionist.dev/guide/getting-started#settings)
       */
      sortType?: Exclude<RuleOptions<'perfectionist/sort-imports'>['type'], 'type-import-first'>;
    });
    /**
     * Use [eslint-plugin-promise](https://github.com/eslint-community/eslint-plugin-promise) to enforce best practices for JavaScript promises.
     *
     * @default true
     */
    promise?: boolean | ConfigWithOverrides<PluginRules<'promise'>>;
    /**
     * Use [@eslint-react/eslint-plugin](https://eslint-react.xyz), [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y), and [@html-eslint/eslint-plugin-react](https://html-eslint.org/docs/react/getting-started) to enforce React best practices and accessibility guidelines.
     *
     * @default false // `true` if "react" is detected in the dependencies when `autoDetectDeps` is enabled
     */
    react?: boolean | ReactOptions;
    /**
     * Use [@stylistic/eslint-plugin](https://eslint.style) to enforce stylistic rules such as indentation, line length, spacing, quotes, semicolons, etc.
     *
     * @default true
     */
    stylistic?: boolean | StylisticOptions;
    /**
     * Use [eslint-plugin-better-tailwindcss](https://github.com/schoero/eslint-plugin-better-tailwindcss) to sort Tailwind classes, check for unused or conflicting ones, and enforce best practices.
     *
     * @default false
     */
    tailwind?: false | TailwindOptions;
    /**
     * Configuration options for the testing tools.
     */
    test?: TestOptions;
    /**
     * Use [@typescript-eslint](https://typescript-eslint.io) to enforce TypeScript-specific rules.
     *
     * Setting this to `false` doesn't prevent ESLint from linting TypeScript files.
     *
     * This allows
     * - [eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x) to better understand imports from TypeScript files such as ".ts", ".tsx", etc.
     * - [eslint-plugin-vue](https://eslint.vuejs.org) to enforce TypeScript-specific rules in the `<script setup lang="ts">` of Vue SFCs.
     *
     * @default false // `true` if "typescript" is detected in the dependencies when `autoDetectDeps` is enabled
     */
    typescript?: boolean | TypescriptOptions;
    /**
     * Use [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) to enforce general best practices and catch common mistakes.
     *
     * @default true
     */
    unicorn?: boolean | ConfigWithOverrides<PluginRules<'unicorn'>> & {
      /**
       * Enforce a consistent style for different types of functions.
       *
       * Object properties and functions that don't match a specified role are ignored.
       *
       * New entries are merged with the defaults and take precedence over them.
       *
       * @default
       *  {
       *    callbacks: 'arrow-function',
       *    defaultExport: 'declaration',
       *    namedExports: 'declaration',
       *    namedFunctions: 'declaration',
       *    reassignedVariables: 'arrow-function',
       *    typedVariables: 'arrow-function',
       *  }
       *
       * @see [unicorn/consistent-function-style](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-function-style.md)
       */
      functionStyle?: Partial<RuleOptions<'unicorn/consistent-function-style'>>;
    };
    /**
     * Use [eslint-plugin-vue](https://eslint.vuejs.org) to enforce Vue best practices, accessibility guidelines, stylistic rules, and identify mistakes.
     *
     * @default false // `true` if "vue" is detected in the dependencies when `autoDetectDeps` is enabled
     */
    vue?: boolean | VueOptions;
    /**
     * Use [eslint-plugin-zod](https://github.com/marcalexiei/eslint-zod/tree/main/plugins/eslint-plugin-zod) or [eslint-plugin-zod-mini](https://github.com/marcalexiei/eslint-zod/tree/main/plugins/eslint-plugin-zod-mini) to enforce best practices for defining Zod schemas.
     *
     * @default false // `true` if "zod" is detected in the dependencies when `autoDetectDeps` is enabled
     */
    zod?: boolean | ZodOptions;
  };
}
//#endregion
export type { ConfigWithOverrides, Options };