// resolver.dart — Maps brief values → template file paths (Pillar 3, 4 improvements)

import 'models.dart';

class Resolver {
  /// Returns an ordered list of template file keys to render.
  /// Each key maps to: templates/<key>.mdc.tmpl (or SKILL.md.tmpl for skills)
  static List<String> resolve(ProjectBrief brief) {
    final files = <String>[];

    // ── Meta: rule authoring (first — governs other .mdc files) ─────────
    files.add('rules/universal/rule-authoring');

    // ── Universal (every project) ──────────────────────────────────────
    files.addAll([
      'rules/universal/flutter-core',
      'rules/universal/ui-ux-standards',
      'rules/universal/project-context',
    ]);

    // ── Theming tokens (when high contrast or extra variants) ───────────
    if (_emitThemingRule(brief)) {
      files.add('rules/theming/theming');
    }

    // ── Security (Pillar 5: always-on, not just for large/auth projects) ──
    files.add('rules/security/security-standards');

    // ── Error handling (always-on) ────────────────────────────────────
    files.add('rules/error-handling/error-handling');

    // ── State management — exactly one ───────────────────────────────
    files.add('rules/state-management/${brief.stateManagement}');

    // ── Architecture — exactly one ────────────────────────────────────
    files.add('rules/architecture/${brief.architecture}');

    // ── Backend — one or more ─────────────────────────────────────────
    for (final b in brief.backends) {
      files.add('rules/backend/$b');
    }
    if (brief.specialFeatures.contains('realtime')) {
      files.add('rules/backend/realtime');
    }

    // ── Push / deep linking ───────────────────────────────────────────
    if (brief.specialFeatures.contains('push_notifications') ||
        brief.specialFeatures.contains('deep_linking')) {
      files.add('rules/integrations/push-deeplink');
    }

    // ── Routing — exactly one ─────────────────────────────────────────
    files.add('rules/routing/${brief.routing}');

    // ── Testing — SM-matched ──────────────────────────────────────────
    files.add('rules/testing/testing-${brief.stateManagement}');
    if (brief.testingDepth == 'full' || brief.testingDepth == 'e2e') {
      files.add('rules/testing/testing-e2e-${brief.e2eTool}');
    }

    // ── Platform targets (Pillar 4) ───────────────────────────────────
    for (final platform in brief.platforms) {
      files.add('rules/platform/platform-$platform');
    }

    // ── Code generation tools (Pillar 4) ─────────────────────────────
    for (final tool in brief.codegenTools) {
      files.add('rules/codegen/codegen-$tool');
    }

    // ── Hooks (Pillar 4) — tied to codegen, not state_management ─────
    if (brief.codegenTools.isNotEmpty) {
      files.addAll([
        'hooks/hooks-json',
        'hooks/flutter-analyze',
        'hooks/grind-tests',
        'hooks/arch-guard',
      ]);
    }

    // ── Localization ──────────────────────────────────────────────────
    if (brief.i18nEnabled) {
      files.add('rules/i18n/localization');
    }

    // ── CI/CD + flavours ─────────────────────────────────────────────
    if (brief.cicd != 'none' || brief.flavors.length > 1) {
      files.add('rules/cicd/cicd');
    }

    // ── Feature-scoped rule stubs ─────────────────────────────────────
    final featureKeys = <String>{};
    for (final m in brief.featureModules) {
      final k = featureRuleKey(m);
      if (k != null) featureKeys.add(k);
    }
    files.addAll(featureKeys);

    // ── Skills ────────────────────────────────────────────────────────
    files.addAll([
      'skills/scaffold-feature',
      'skills/scaffold-screen',
      'skills/generate-tests',
      'skills/build',
      'skills/debug-issue',
      'skills/verify-change',
      'skills/explain-code',
    ]);
    if (brief.apiDocsFormat != 'none') files.add('skills/generate-api-client');
    if (brief.flavors.length > 1) files.add('skills/create-flavor');
    if (brief.cicd != 'none') files.add('skills/deploy');

    // ── Agents ────────────────────────────────────────────────────────
    files.addAll([
      'agents/code-reviewer',
      'agents/test-writer',
      'agents/ui-validator',
    ]);
    if (brief.backends.contains('rest')) files.add('agents/api-client-gen');

    // Pillar 5: Security agent as ADDITIONAL layer (rules are primary)
    if (brief.scale == 'large' || brief.auth != 'none') {
      files.add('agents/security-agent');
    }
    if (brief.stateManagement == 'getx') {
      files.add('agents/migration-agent');
    }

    // ── Cursor workspace extras (reference architecture) ────────────────
    files.addAll([
      'root/.cursorignore',
      'root/tool/cursor_audit.sh',
      'onboarding/ONBOARDING',
      'commands/build',
      'commands/debug-issue',
      'commands/verify-change',
      'commands/explain-code',
    ]);

    if (brief.mcpConfigEnabled) {
      files.add('config/mcp-json');
    }

    if (brief.telemetryOptIn) {
      files.addAll([
        'telemetry/gitignore',
        'telemetry/log-sh',
        'rules/telemetry/usage-logging',
      ]);
    }

    files.addAll(['root/AGENTS.md', 'root/lefthook.yaml']);

    return files;
  }

  /// `lib/features/<slug>/` ↔ `rules/features/<slug>.mdc`
  static String? featureRuleKey(String module) {
    var s = module
        .trim()
        .toLowerCase()
        .replaceAll(RegExp(r'[^a-z0-9]+'), '_');
    s = s.replaceAll(RegExp(r'_+'), '_');
    s = s.replaceAll(RegExp(r'(^_+|_+$)'), '');
    if (s.isEmpty) return null;
    return 'rules/features/$s';
  }

  static bool _emitThemingRule(ProjectBrief brief) {
    return brief.themeVariants.contains('high_contrast') ||
        brief.themeVariants.length > 2;
  }

  /// Returns human-readable description of why each file was included
  static Map<String, String> resolveWithReasons(ProjectBrief brief) {
    final resolved = resolve(brief);
    final reasons = <String, String>{};
    for (final f in resolved) {
      reasons[f] = _reason(f, brief);
    }
    return reasons;
  }

  static String _reason(String key, ProjectBrief brief) {
    if (key == 'rules/universal/rule-authoring') {
      return 'Always included — meta rules for authoring .cursor/rules';
    }
    if (key.contains('universal')) return 'Always included';
    if (key == 'rules/theming/theming') {
      return 'Theme variants include high contrast or extended set';
    }
    if (key.contains('security')) {
      return 'Always included — Pillar 5';
    }
    if (key.contains('error-handling')) return 'Always included';
    if (key.contains('state-management')) {
      return 'Matches stack.state_management: ${brief.stateManagement}';
    }
    if (key.contains('architecture')) {
      return 'Matches stack.architecture: ${brief.architecture}';
    }
    if (key == 'rules/integrations/push-deeplink') {
      return 'features.special includes push_notifications or deep_linking';
    }
    if (key.contains('routing')) {
      return 'Matches stack.routing: ${brief.routing}';
    }
    if (key.contains('testing-e2e')) {
      return 'testing.depth includes e2e';
    }
    if (key.contains('testing')) {
      return 'Matches state_management testing patterns';
    }
    if (key.contains('platform')) {
      return 'Matches stack.platforms';
    }
    if (key.startsWith('hooks/')) {
      return 'stack.codegen non-empty — Cursor hooks for analyze, boundaries, and tests';
    }
    if (key.contains('codegen')) {
      return 'Matches stack.codegen';
    }
    if (key.contains('i18n')) {
      return 'localization.enabled: true';
    }
    if (key == 'rules/cicd/cicd') {
      return 'environments.cicd is set or multiple flavors';
    }
    if (key.startsWith('rules/features/')) {
      return 'Listed under features.modules in project-brief.yaml';
    }
    if (key.contains('migration')) {
      return 'state_management is GetX — migration guidance included';
    }
    if (key.contains('security-agent')) {
      return 'scale: ${brief.scale} or auth is configured';
    }
    if (key == 'skills/build') {
      return 'Always included — universal TDD-first feature implementation command';
    }
    if (key == 'skills/debug-issue') {
      return 'Always included — structured bug triage and evidence-first debugging';
    }
    if (key == 'skills/verify-change') {
      return 'Always included — pre-PR verification checklist without full /build lifecycle';
    }
    if (key == 'skills/explain-code') {
      return 'Always included — explain-only walkthrough of code paths and stack behavior';
    }
    if (key.contains('api-client')) {
      return 'api_docs.format is set';
    }
    if (key.contains('realtime')) {
      return 'features.special contains realtime';
    }
    if (key == 'root/.cursorignore') {
      return 'Root ignore patterns for Cursor indexing';
    }
    if (key == 'root/tool/cursor_audit.sh') {
      return 'Maintenance script for rule drift checks';
    }
    if (key == 'onboarding/ONBOARDING') {
      return 'Team onboarding for Cursor layout and slash skills';
    }
    if (key.startsWith('commands/')) {
      return 'Project slash command → skill mapping';
    }
    if (key == 'config/mcp-json') {
      return 'integrations.mcp.enabled: true in project-brief.yaml';
    }
    if (key == 'telemetry/gitignore' ||
        key == 'telemetry/log-sh' ||
        key == 'rules/telemetry/usage-logging') {
      return 'telemetry_opt_in: true — local usage logging helpers';
    }
    if (key.startsWith('root/')) {
      return 'Repo-level companion files';
    }
    return 'Included';
  }
}
