/**
 * @fileoverview Standards Context Injector
 *
 * Automatically loads and surfaces relevant standards content for agents.
 * Resolution order: project overrides → framework standards → content standards
 *
 * @module standards-context-injector
 */

import { readFileSync, existsSync } from 'fs';
import { join } from 'path';
import { resolveStandardsDir } from '../stacks/stack-resolver.js';

/**
 * Agent → Standards mapping
 * Maps each agent ID to relevant standard files (hierarchical paths without .md extension)
 */
const AGENT_STANDARDS_MAP = {
  // Tier 1: Orchestrators
  'standards-architect': [
    'core/architecture',
    'core/coding',
    'infrastructure/azure/azure', // Stack-specific (kept in .morph/standards/)
    'backend/dotnet/core',
    'backend/dotnet/program-cs-checklist'
  ],
  'ai-system-architect': [
    'ai-agents/setup',
    'ai-agents/workflows',
    'ai-agents/production',
    'ai-agents/blazor-ui',
    'core/architecture',
    'core/coding'
  ],
  'popm-advisor': [], // No technical standards

  // Tier 2: Domain Leaders
  'dotnet-senior': [
    'core/coding',
    'core/architecture',
    'core/testing',
    'backend/dotnet/core',
    'backend/dotnet/async',
    'backend/dotnet/di',
    'backend/database/ef-core',
    'backend/api/rest'
  ],
  'azure-architect': [
    'infrastructure/azure/azure', // Stack-specific
    'core/architecture',
    'backend/dotnet/core'
  ],
  'ui-designer': [
    'frontend/design-system/naming',
    'frontend/design-system/animations',
    'frontend/blazor/fluent-ui-setup', // Stack-specific
    'frontend/blazor/fluent-ui'
  ],

  // Tier 3: Specialists - Backend Squad
  'ef-modeler': [
    'backend/database/ef-core',
    'backend/database/migrations',
    'backend/database/repository-patterns',
    'core/architecture',
    'core/coding',
    'backend/dotnet/core'
  ],
  'event-architect': [
    'core/architecture',
    'core/coding',
    'backend/dotnet/core'
  ],
  'api-designer': [
    'backend/api/rest',
    'backend/api/validation',
    'core/architecture',
    'core/coding',
    'backend/dotnet/core'
  ],
  'nosql-cache-expert': [
    'core/architecture',
    'core/coding'
  ],
  'ddd-expert': [
    'core/architecture',
    'core/coding'
  ],
  'hangfire-orchestrator': [
    'core/architecture',
    'core/coding',
    'frontend/blazor/lifecycle', // Background jobs + Blazor lifecycle
    'backend/database/repository-patterns', // Factory pattern
    'backend/dotnet/core'
  ],
  'ms-agent-expert': [
    'ai-agents/setup',
    'ai-agents/workflows',
    'ai-agents/production',
    'ai-agents/blazor-ui',
    'core/coding',
    'core/architecture'
  ],
  'asaas-financial': [
    'core/coding',
    'core/architecture'
  ],
  'clerk-auth': [
    'core/coding',
    'core/architecture',
    'backend/authentication/passkeys' // Stack-specific
  ],
  'resend-email': [
    'core/coding',
    'core/architecture'
  ],

  // Tier 3: Specialists - Frontend Squad
  'blazor-builder': [
    'frontend/blazor/lifecycle',
    'frontend/blazor/state',
    'frontend/blazor/pitfalls',
    'frontend/blazor/html-conversion',
    'frontend/blazor/fluent-ui',
    'frontend/design-system/naming',
    'frontend/design-system/animations',
    'backend/database/ef-core', // DbContext usage
    'core/coding',
    'core/architecture'
  ],
  'nextjs-expert': [
    'core/coding'
  ],
  'css-specialist': [
    'frontend/design-system/naming',
    'frontend/design-system/animations',
    'frontend/blazor/fluent-ui'
  ],

  // Tier 3: Specialists - Infrastructure Squad
  'bicep-architect': [
    'infrastructure/azure/azure', // Stack-specific
    'core/architecture'
  ],
  'devops-engineer': [
    'infrastructure/azure/azure', // Stack-specific
    'backend/dotnet/core'
  ],
  'container-specialist': [
    'infrastructure/azure/azure', // Stack-specific
    'backend/dotnet/core'
  ],
  'observability-expert': [
    'infrastructure/azure/azure', // Stack-specific
    'core/architecture'
  ],
  'azure-identity': [
    'infrastructure/azure/azure', // Stack-specific
    'core/architecture',
    'backend/authentication/passkeys' // Stack-specific
  ],

  // Tier 3: Specialists - Quality Squad
  'testing-specialist': [
    'core/testing',
    'core/coding',
    'core/architecture',
    'backend/dotnet/core'
  ],
  'code-analyzer': [
    'core/coding',
    'core/architecture',
    'backend/dotnet/core',
    'backend/dotnet/program-cs-checklist'
  ],
  'troubleshooting-expert': [
    'core/architecture',
    'frontend/blazor/pitfalls',
    'backend/dotnet/core'
  ],
  'load-testing-expert': [
    'core/architecture',
    'infrastructure/azure/azure' // Stack-specific
  ],
  'documentation-specialist': [], // No technical standards

  // Tier 4: Validators
  'security-expert': [
    'core/coding',
    'core/architecture',
    'backend/authentication/passkeys' // Stack-specific
  ]
};

/**
 * Load a single standard file with project override support
 * @param {string} standardName - Standard path without .md extension (e.g., "core/coding", "backend/database/ef-core")
 * @param {string} projectPath - Root path of the project
 * @returns {string|null} Standard content or null if not found
 */
function loadStandard(standardName, projectPath) {
  const locations = [
    // 1. Project override
    join(projectPath, '.morph/project/standards', `${standardName}.md`),
    // 2. Stack standards (for stack-specific overrides like azure.md, passkeys-auth.md)
    join(resolveStandardsDir(projectPath), `${standardName}.md`),
    // 3. Framework standards (hierarchical structure: core/, backend/, frontend/, infrastructure/)
    join(projectPath, 'framework/standards', `${standardName}.md`)
  ];

  for (const path of locations) {
    if (existsSync(path)) {
      try {
        return readFileSync(path, 'utf8');
      } catch (err) {
        // Continue to next location
      }
    }
  }

  return null;
}

/**
 * Load all relevant standards for a given agent
 * @param {string} agentId - Agent ID (e.g., 'blazor-builder')
 * @param {string} projectPath - Root path of the project
 * @returns {Object} { sections: [{standard, content}], fullContent: string }
 */
export function loadStandardsForAgent(agentId, projectPath = '.') {
  const standardNames = AGENT_STANDARDS_MAP[agentId] || [];
  const sections = [];
  const contentParts = [];

  // Load inferred standards if exists (project-specific learnings)
  const inferredPath = join(projectPath, '.morph/project/standards/inferred.md');
  if (existsSync(inferredPath)) {
    try {
      const inferredContent = readFileSync(inferredPath, 'utf8');
      sections.push({
        standard: 'inferred',
        content: inferredContent
      });
      contentParts.push(`# Project-Specific Standards (Inferred)\n\n${inferredContent}`);
    } catch (err) {
      // Ignore if can't read
    }
  }

  // Load each standard
  for (const standardName of standardNames) {
    const content = loadStandard(standardName, projectPath);
    if (content) {
      sections.push({
        standard: standardName,
        content
      });
      contentParts.push(`# ${standardName}\n\n${content}`);
    }
  }

  return {
    sections,
    fullContent: contentParts.join('\n\n---\n\n'),
    standardNames // For debugging/introspection
  };
}

/**
 * Get list of standards for an agent (without loading content)
 * @param {string} agentId - Agent ID
 * @returns {string[]} Array of standard names
 */
export function getStandardsListForAgent(agentId) {
  return AGENT_STANDARDS_MAP[agentId] || [];
}

/**
 * Check if a standard exists in any location
 * @param {string} standardName - Standard path without .md extension (e.g., "core/coding", "backend/database/ef-core")
 * @param {string} projectPath - Root path of the project
 * @returns {Object} { exists: boolean, location: string|null }
 */
export function checkStandardExists(standardName, projectPath = '.') {
  const locations = [
    { type: 'project', path: join(projectPath, '.morph/project/standards', `${standardName}.md`) },
    { type: 'stack', path: join(resolveStandardsDir(projectPath), `${standardName}.md`) },
    { type: 'framework', path: join(projectPath, 'framework/standards', `${standardName}.md`) }
  ];

  for (const loc of locations) {
    if (existsSync(loc.path)) {
      return { exists: true, location: loc.type, path: loc.path };
    }
  }

  return { exists: false, location: null, path: null };
}
