import js from "@eslint/js";
import tseslint from "typescript-eslint";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import prettier from "eslint-config-prettier";
import globals from "globals";

// Flat config (ESLint 9). Deliberately NARROW: the high-value rule here is
// react-hooks/exhaustive-deps — 33 suppressions across the app exist for it, and until this
// sprint nothing ran to make them mean anything. tsc already owns unused vars, undefined names
// and types (noUnusedLocals/Parameters + strict), so typescript-eslint's non-type-checked
// `recommended` is layered on but its overlap with tsc is turned off below to avoid double-reporting
// and a churny diff. `eslint-config-prettier` is LAST so formatting rules never fight Prettier.
//
// reportUnusedDisableDirectives: a `// eslint-disable` that no longer suppresses anything is itself
// an error — that is what keeps inert disable comments from re-accumulating (the S1b mandate).
export default tseslint.config(
  { ignores: ["dist", "node_modules", "playwright-report", "test-results", "e2e/.auth"] },
  {
    files: ["src/**/*.{ts,tsx}"],
    extends: [js.configs.recommended, ...tseslint.configs.recommended],
    languageOptions: {
      ecmaVersion: 2022,
      globals: { ...globals.browser },
    },
    plugins: {
      "react-hooks": reactHooks,
      "react-refresh": reactRefresh,
    },
    linterOptions: {
      reportUnusedDisableDirectives: "error",
    },
    rules: {
      ...reactHooks.configs.recommended.rules,
      "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
      // tsc already enforces these under strict + noUnusedLocals/Parameters — let it own them so a
      // finding is reported once, by one tool, and this config stays about hooks + refresh safety.
      "@typescript-eslint/no-unused-vars": "off",
      "no-undef": "off",
      // R7 S3a eliminated every explicit `any` (api.ts prefs/data bags → Record<string, unknown>;
      // catch clauses → unknown + HttpError narrowing; the YouTube IFrame boundary → lib/youtube.ts
      // types; i18n `t` props → TFunction), so the rule is now enforced to keep new ones from
      // creeping back in. Prefer `unknown` + narrowing, or a typed boundary, over `any`.
      "@typescript-eslint/no-explicit-any": "error",
      // Side-effect ternaries/short-circuits are an established idiom here (`cond ? a() : b()`,
      // `v.paused ? v.play() : v.pause()`) — allow them rather than rewrite working code to if/else.
      "@typescript-eslint/no-unused-expressions": [
        "error",
        { allowShortCircuit: true, allowTernary: true },
      ],
    },
  },
  prettier,
);
