import nx from '@nx/eslint-plugin';

export default [
  ...nx.configs['flat/base'],
  ...nx.configs['flat/typescript'],
  ...nx.configs['flat/javascript'],
  {
    ignores: [
      '**/dist',
      '**/*.d.ts',
      '**/*.d.ts.map',
      '**/fixture/libs',
      'apps/e2e/**',
      '**/*.spec.ts',
      '**/*.spec.tsx',
      '**/*.test.ts',
      '**/*.test.tsx',
      '**/*.e2e.spec.ts',
      '**/*.perf.spec.ts',
      '**/*.pw.spec.ts',
      '**/__tests__/**',
      '**/__test-utils__/**',
      '**/jest.config.ts',
      '**/jest.config.js',
    ],
  },
  {
    files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
    rules: {
      '@typescript-eslint/no-explicit-any': 'warn',
      '@typescript-eslint/no-empty-function': 'off', // Many lifecycle hooks and abstract methods are intentionally empty
      '@typescript-eslint/no-empty-interface': 'off', // Used for module augmentation and marker interfaces
      '@typescript-eslint/no-empty-object-type': 'warn',
      '@typescript-eslint/no-unused-vars': [
        'warn',
        {
          argsIgnorePattern: '^_',
          varsIgnorePattern: '^_',
          caughtErrorsIgnorePattern: '^_',
        },
      ],
      '@typescript-eslint/consistent-type-imports': [
        'warn',
        {
          prefer: 'type-imports',
          fixStyle: 'inline-type-imports',
          disallowTypeAnnotations: false,
        },
      ],
      '@nx/enforce-module-boundaries': [
        'error',
        {
          enforceBuildableLibDependency: true,
          allow: [
            '^.*/eslint(\\.base)?\\.config\\.[cm]?[jt]s$',
            '@frontmcp/sdk',
            '@frontmcp/auth',
            '@frontmcp/utils',
            '@frontmcp/uipack',
            '@frontmcp/uipack/*',
            '@frontmcp/protocol',
            '@frontmcp/testing',
            '@frontmcp/observability',
            '^#(mcp-.+|crypto-.+|async-.+|event-.+|langchain-.+|sse-.+|express-.+|server-.+|stdio-.+|env|runtime-context|path)$',
          ],
          depConstraints: [
            {
              sourceTag: '*',
              onlyDependOnLibsWithTags: ['*'],
            },
          ],
        },
      ],
    },
  },
  {
    files: ['**/*.ts', '**/*.tsx', '**/*.cts', '**/*.mts', '**/*.js', '**/*.jsx', '**/*.cjs', '**/*.mjs'],
    // Override or add rules here
    rules: {
      '@typescript-eslint/no-unsafe-function-type': 'off',
    },
  },
  {
    // Relax rules for test files
    files: [
      '**/*.test.ts',
      '**/*.spec.ts',
      '**/*.e2e.ts',
      '**/*.e2e.spec.ts',
      '**/e2e/**/*.ts',
      '**/__tests__/**/*.ts',
      '**/__test-utils__/**/*.ts',
      '**/fixtures/**/*.ts',
      '**/mocks/**/*.ts',
      '**/*.mock.ts',
    ],
    rules: {
      '@typescript-eslint/no-empty-function': 'off',
      '@typescript-eslint/no-explicit-any': 'off',
      '@typescript-eslint/no-non-null-assertion': 'off',
      '@typescript-eslint/no-unused-vars': 'off',
      'no-unused-private-class-members': 'off',
    },
  },
  {
    // Block direct imports of @frontmcp/protocol in consumer code
    files: ['apps/**/*.ts', 'apps/**/*.tsx'],
    rules: {
      'no-restricted-imports': [
        'error',
        {
          paths: [
            {
              name: '@frontmcp/protocol',
              message:
                '@frontmcp/protocol is internal. Import MCP types from @frontmcp/sdk. ' +
                'For raw MCP Client in tests, use McpClient from @frontmcp/testing.',
            },
          ],
          patterns: [
            {
              group: ['@frontmcp/protocol/*'],
              message:
                '@frontmcp/protocol is internal. Import MCP types from @frontmcp/sdk. ' +
                'For raw MCP Client in tests, use McpClient from @frontmcp/testing.',
            },
          ],
        },
      ],
    },
  },
  {
    // Allow `any` in .d.ts declaration files for compatibility with external libraries (React, Handlebars, etc.)
    files: ['**/*.d.ts'],
    rules: {
      '@typescript-eslint/no-explicit-any': 'off',
    },
  },
];
