// ESLint v9 flat config. Mirrors the rule set from
// docs/superpowers/plans/2026-04-14-phase-1a1-skeleton.md (Task 4).
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import unusedImports from "eslint-plugin-unused-imports";
import boundaries from "eslint-plugin-boundaries";

export default [
  {
    ignores: [
      "dist/**",
      "node_modules/**",
      "ClientApp/**",
      "wwwroot/**",
      "**/*.cjs",
      "pnpm-lock.yaml",
    ],
  },
  js.configs.recommended,
  ...tseslint.configs.recommended,
  {
    files: ["src/**/*.{ts,tsx}"],
    languageOptions: {
      parser: tseslint.parser,
      parserOptions: {
        ecmaVersion: 2023,
        sourceType: "module",
        project: "./tsconfig.json",
        ecmaFeatures: { jsx: true },
      },
    },
    plugins: {
      "unused-imports": unusedImports,
    },
    rules: {
      "@typescript-eslint/no-unused-vars": "off",
      "unused-imports/no-unused-imports": "error",
      "unused-imports/no-unused-vars": [
        "warn",
        {
          vars: "all",
          varsIgnorePattern: "^_",
          args: "after-used",
          argsIgnorePattern: "^_",
        },
      ],
      "@typescript-eslint/consistent-type-imports": [
        "error",
        { prefer: "type-imports" },
      ],
      "@typescript-eslint/no-explicit-any": "warn",
      "@typescript-eslint/no-non-null-assertion": "warn",
      "no-console": ["warn", { allow: ["warn", "error"] }],
    },
  },
  {
    files: ["src/**/*.{ts,tsx}"],
    plugins: {
      boundaries,
    },
    settings: {
      "import/resolver": {
        node: {
          extensions: [".ts", ".tsx", ".js", ".jsx"],
        },
      },
      "boundaries/elements": [
        { type: "routes", pattern: "src/routes/*" },
        { type: "mf", pattern: "src/mf/*" },
        { type: "features", pattern: "src/features/*", capture: ["feature"] },
        { type: "ui", pattern: "src/ui/*" },
        { type: "shared", pattern: "src/shared/*" },
        { type: "observability", pattern: "src/observability/*" },
        { type: "i18n", pattern: "src/i18n/*" },
        { type: "env", pattern: "src/env/*" },
      ],
    },
    rules: {
      // Design spec §1.2 layered dependency direction:
      // features/ cannot import routes/ or mf/
      // ui/ cannot import features/
      // shared/ cannot import features/, routes/, mf/, observability/
      // observability/ cannot import features/, routes/, mf/
      "boundaries/element-types": [
        "error",
        {
          default: "allow",
          rules: [
            {
              from: "features",
              disallow: ["routes", "mf"],
              message: "Features must not import from routes/ or mf/. Use the HostContract or a shared module instead.",
            },
            {
              from: "ui",
              disallow: ["features", "routes", "mf"],
              message: "UI layer must not import from features/, routes/, or mf/. UI is consumed by features, not the other way around.",
            },
            {
              from: "shared",
              disallow: ["features", "routes", "mf", "observability"],
              message: "Shared modules must not import from features/, routes/, mf/, or observability/.",
            },
            {
              from: "observability",
              disallow: ["features", "routes", "mf"],
              message: "Observability modules must not import from features/, routes/, or mf/.",
            },
          ],
        },
      ],
    },
  },
  // --- Restricted imports (master plan §1A-3) ---
  // OTel SDK internals + react-i18next: merged into one block so ESLint 9
  // flat config doesn't override one rule with the other.
  // otel.ts is allowed to import OTel SDK; provider.tsx is allowed to import react-i18next.
  // Neither file needs the other's exemption, so combining ignores is safe.
  {
    files: ["src/**/*.{ts,tsx}"],
    ignores: ["src/observability/metrics/otel.ts", "src/observability/metrics/otel.test.ts", "src/i18n/provider.tsx"],
    rules: {
      "no-restricted-imports": [
        "error",
        {
          paths: [
            {
              name: "@opentelemetry/sdk-metrics",
              message: "Import from @opentelemetry/api or use getMeter() from @/observability/metrics/otel instead. Direct SDK access is restricted to src/observability/metrics/otel.ts.",
            },
            {
              name: "@opentelemetry/sdk-node",
              message: "Import from @opentelemetry/api or use getMeter()/getTracer() from @/observability/metrics/otel instead. Direct SDK access is restricted to src/observability/metrics/otel.ts.",
            },
            {
              name: "react-i18next",
              message: "Import useTranslation from @/i18n/provider instead. Direct react-i18next imports are restricted to src/i18n/provider.tsx.",
            },
          ],
        },
      ],
    },
  },
  // @microsoft/signalr: forbidden in files that run during SSR.
  // SSR-bundle = routes/ and server/ directories. Features + shared/hooks are client-side.
  {
    files: ["src/routes/**/*.{ts,tsx}", "src/server/**/*.{ts,tsx}"],
    rules: {
      "no-restricted-imports": [
        "error",
        {
          paths: [
            {
              name: "@microsoft/signalr",
              message: "SignalR must not be imported in SSR-bundle files (routes/, server/). Use dynamic import in a useEffect or a client-only wrapper.",
            },
          ],
        },
      ],
    },
  },
  // window.localStorage / window.sessionStorage: only src/shared/storage.ts
  {
    files: ["src/**/*.{ts,tsx}"],
    ignores: ["src/shared/storage.ts", "src/shared/storage.test.ts"],
    rules: {
      "no-restricted-globals": [
        "error",
        {
          name: "localStorage",
          message: "Use the storage module from @/shared/storage instead. Direct localStorage access is restricted to src/shared/storage.ts.",
        },
        {
          name: "sessionStorage",
          message: "Use the storage module from @/shared/storage instead. Direct sessionStorage access is restricted to src/shared/storage.ts.",
        },
      ],
    },
  },
];
