/**
 * Context Optimizer — Selective context loading strategy
 *
 * Provides intelligent recommendations for reducing context window usage:
 * - selectStandards: pick only relevant standards for a feature type
 * - selectTemplates: pick only relevant templates
 * - suggestOptimizations: compare current vs optimal context, return savings
 *
 * Connects to standards resolver and template registry.
 */

import { readFileSync, existsSync } from 'fs';
import { join } from 'path';

const STANDARDS_DIR = join(process.cwd(), 'framework/standards');
const TEMPLATES_REGISTRY = join(process.cwd(), 'framework/templates/REGISTRY.json');

// Average token cost estimates per file type
const TOKEN_ESTIMATES = {
  standard_file: 2000,
  template_file: 1500,
  claude_md: 23000,
  spec_file: 8000,
  decisions_file: 3000
};

// Feature type → relevant standards mapping
const STANDARDS_BY_FEATURE_TYPE = {
  backend: [
    'coding.md', 'architecture.md', 'dotnet10-compatibility.md',
    'integration/api/rest-design.md'
  ],
  frontend: [
    'coding.md', 'blazor-components.md', 'blazor-state.md',
    'css-architecture.md', 'css-design-system.md'
  ],
  database: [
    'coding.md', 'ef-core.md', 'architecture.md'
  ],
  infrastructure: [
    'azure.md', 'bicep.md', 'devops.md'
  ],
  authentication: [
    'coding.md', 'architecture.md', 'dotnet10-compatibility.md',
    'integration/api/rest-design.md'
  ],
  fullstack: [
    'coding.md', 'architecture.md', 'blazor-components.md',
    'ef-core.md', 'dotnet10-compatibility.md'
  ],
  observability: [
    'observability/monitoring.md', 'observability/logging.md',
    'observability/tracing.md', 'observability/metrics.md'
  ],
  event_driven: [
    'integration/event-driven/service-bus.md',
    'integration/event-driven/cqrs.md'
  ]
};

// ============================================================================
// Standards Selection
// ============================================================================

/**
 * Select minimal relevant standards for a given feature type
 * @param {string} featureType - Feature type keyword
 * @param {Object} [opts]
 * @param {string[]} [opts.extraKeywords] - Additional keywords for selection
 * @returns {Object} { selected: string[], skipped: string[], estimatedTokens: number }
 */
export function selectStandards(featureType, { extraKeywords = [] } = {}) {
  const typeKey = detectFeatureCategory(featureType, extraKeywords);
  const selected = STANDARDS_BY_FEATURE_TYPE[typeKey] || STANDARDS_BY_FEATURE_TYPE.fullstack;

  // Check which selected files actually exist
  const existing = selected.filter(f => {
    const fullPath = join(STANDARDS_DIR, f);
    return existsSync(fullPath);
  });

  // Estimate all standard files count for skipped calculation
  const allStandards = getAllStandardsCount();
  const skippedCount = allStandards - existing.length;

  return {
    selected: existing,
    skipped: skippedCount,
    featureType: typeKey,
    estimatedTokens: existing.length * TOKEN_ESTIMATES.standard_file,
    fullLoadTokens: allStandards * TOKEN_ESTIMATES.standard_file,
    savings: skippedCount * TOKEN_ESTIMATES.standard_file
  };
}

/**
 * Select relevant templates for a feature type
 * @param {string} featureType - Feature type keyword
 * @returns {Object} { selected: string[], estimatedTokens: number }
 */
export function selectTemplates(featureType) {
  const TEMPLATES_BY_TYPE = {
    backend: ['dotnet-backend-service', 'dotnet-repository', 'dotnet-api-contracts'],
    frontend: ['dotnet-blazor-component', 'dotnet-design-system'],
    database: ['dotnet-migration', 'sql-migration'],
    infrastructure: ['azure-container-app', 'azure-key-vault', 'azure-main-bicep'],
    fullstack: ['dotnet-backend-service', 'dotnet-blazor-component', 'dotnet-migration']
  };

  const typeKey = detectFeatureCategory(featureType, []);
  const selected = TEMPLATES_BY_TYPE[typeKey] || TEMPLATES_BY_TYPE.fullstack;

  // Load registry to get full template count
  let totalTemplates = 50;
  try {
    const registry = JSON.parse(readFileSync(TEMPLATES_REGISTRY, 'utf8'));
    totalTemplates = (registry.templates || []).length;
  } catch {
    // Use estimate
  }

  return {
    selected,
    skipped: totalTemplates - selected.length,
    estimatedTokens: selected.length * TOKEN_ESTIMATES.template_file,
    fullLoadTokens: totalTemplates * TOKEN_ESTIMATES.template_file,
    savings: (totalTemplates - selected.length) * TOKEN_ESTIMATES.template_file
  };
}

/**
 * Suggest context optimizations based on current vs optimal load
 * @param {Object} current - Current context state
 * @param {number} current.totalTokens - Current token count
 * @param {number} current.standardsCount - Number of standards currently loaded
 * @param {number} current.templatesCount - Number of templates currently loaded
 * @param {string} featureType - Feature type for optimal selection
 * @returns {Object} Optimization suggestions with savings estimates
 */
export function suggestOptimizations(current, featureType) {
  const optimalStandards = selectStandards(featureType);
  const optimalTemplates = selectTemplates(featureType);
  const suggestions = [];

  // Claude.md optimization
  if (current.totalTokens > 50000) {
    suggestions.push({
      type: 'priming_file',
      title: 'Use priming file instead of full CLAUDE.md',
      description: 'Replace 23K token CLAUDE.md with a 500-token priming file',
      savings: TOKEN_ESTIMATES.claude_md - 500,
      priority: 'high',
      command: 'morph-spec prime feature'
    });
  }

  // Standards optimization
  if (current.standardsCount > optimalStandards.selected.length + 3) {
    suggestions.push({
      type: 'standards_subset',
      title: `Load only ${optimalStandards.selected.length} relevant standards`,
      description: `Currently loading ${current.standardsCount} standards. Only ${optimalStandards.selected.length} are needed for ${featureType} features.`,
      savings: optimalStandards.savings,
      priority: 'medium',
      selectedStandards: optimalStandards.selected
    });
  }

  // Context bundle for large sessions
  if (current.totalTokens > 100000) {
    suggestions.push({
      type: 'context_bundle',
      title: 'Create context bundle checkpoint',
      description: 'Compress current context (180K → ~15K tokens) for session resume',
      savings: current.totalTokens - 15000,
      priority: 'critical',
      command: 'morph-spec bundle create'
    });
  }

  const totalSavings = suggestions.reduce((sum, s) => sum + s.savings, 0);
  const optimizedTokens = Math.max(current.totalTokens - totalSavings, 5000);

  return {
    currentTokens: current.totalTokens,
    optimizedTokens,
    totalSavings,
    savingsPercent: Math.round(totalSavings / current.totalTokens * 100),
    suggestions: suggestions.sort((a, b) => b.savings - a.savings)
  };
}

// ============================================================================
// Helpers
// ============================================================================

function detectFeatureCategory(featureType, extraKeywords) {
  const text = (featureType + ' ' + extraKeywords.join(' ')).toLowerCase();

  if (/auth|login|jwt|oauth|identity/.test(text)) return 'authentication';
  if (/blazor|frontend|ui|component|razor/.test(text)) return 'frontend';
  if (/migration|ef.core|database|entity/.test(text)) return 'database';
  if (/bicep|azure|infra|container|devops/.test(text)) return 'infrastructure';
  if (/service.bus|cqrs|event.sourcing|pub.sub/.test(text)) return 'event_driven';
  if (/monitor|logging|trace|metric|appinsight/.test(text)) return 'observability';
  if (/api|endpoint|controller|rest/.test(text)) return 'backend';
  return 'fullstack';
}

function getAllStandardsCount() {
  return 30; // Known approximate count
}
