/**
 * Template Validator - Validates Handlebars templates
 * Checks for:
 * - Required placeholders are present
 * - No deprecated pre-computed variables ({FEATURE_NAME_PASCAL})
 * - Valid Handlebars syntax
 * - Proper helper usage
 */

import { readFileSync } from 'fs';
import { getTemplateById, getAllTemplates } from './template-registry.js';

/**
 * Deprecated placeholder patterns (v1.0 pre-computed variables)
 */
const DEPRECATED_PATTERNS = [
  { pattern: /\{\{FEATURE_NAME_PASCAL\}\}/g, replacement: '{{pascalCase FEATURE_NAME}}' },
  { pattern: /\{\{FEATURE_NAME_CAMEL\}\}/g, replacement: '{{camelCase FEATURE_NAME}}' },
  { pattern: /\{\{FEATURE_NAME_SNAKE\}\}/g, replacement: '{{snakeCase FEATURE_NAME}}' },
  { pattern: /\{\{FEATURE_NAME_UPPER_SNAKE\}\}/g, replacement: '{{upperSnakeCase FEATURE_NAME}}' },
  { pattern: /\{\{FEATURE_NAME_TITLE\}\}/g, replacement: '{{titleCase FEATURE_NAME}}' },
  { pattern: /\{\{FEATURE_NAME_KEBAB\}\}/g, replacement: '{{kebabCase FEATURE_NAME}}' },
];

/**
 * Old template syntax (non-Handlebars)
 */
const OLD_SYNTAX_PATTERNS = [
  { pattern: /\{Feature\}/g, description: 'Old {Feature} syntax (use {{pascalCase FEATURE_NAME}})' },
  { pattern: /\{feature\}/g, description: 'Old {feature} syntax (use {{kebabCase FEATURE_NAME}})' },
];

/**
 * Validation result
 */
class ValidationResult {
  constructor(templateId, templatePath) {
    this.templateId = templateId;
    this.templatePath = templatePath;
    this.valid = true;
    this.errors = [];
    this.warnings = [];
    this.info = [];
  }

  addError(message) {
    this.errors.push(message);
    this.valid = false;
  }

  addWarning(message) {
    this.warnings.push(message);
  }

  addInfo(message) {
    this.info.push(message);
  }

  get hasIssues() {
    return this.errors.length > 0 || this.warnings.length > 0;
  }
}

/**
 * Validates a single template
 * @param {string} templateId - Template ID
 * @param {string} projectPath - Project root path
 * @returns {ValidationResult}
 */
export function validateTemplate(templateId, projectPath = process.cwd()) {
  const template = getTemplateById(templateId, projectPath);

  if (!template) {
    const result = new ValidationResult(templateId, null);
    result.addError(`Template not found: ${templateId}`);
    return result;
  }

  const result = new ValidationResult(templateId, template.path);

  // Read template content
  let content;
  try {
    const fullPath = `${projectPath}/framework/templates/${template.path}`;
    content = readFileSync(fullPath, 'utf-8');
  } catch (error) {
    result.addError(`Failed to read template: ${error.message}`);
    return result;
  }

  // Check for deprecated pre-computed variables
  for (const { pattern, replacement } of DEPRECATED_PATTERNS) {
    const matches = content.match(pattern);
    if (matches) {
      result.addError(
        `Deprecated placeholder found: ${matches[0]} (use ${replacement} instead)`
      );
    }
  }

  // Check for old non-Handlebars syntax
  for (const { pattern, description } of OLD_SYNTAX_PATTERNS) {
    const matches = content.match(pattern);
    if (matches) {
      const count = matches.length;
      result.addWarning(
        `${count} occurrence(s) of old syntax: ${description}`
      );
    }
  }

  // Check for required placeholders if specified
  if (template.placeholders && template.placeholders.length > 0) {
    const missingPlaceholders = [];

    for (const placeholder of template.placeholders) {
      // Check for exact placeholder or helper usage
      const exactMatch = new RegExp(`\\{\\{${placeholder}\\}\\}`, 'g');
      const helperMatch = new RegExp(`\\{\\{\\w+\\s+${placeholder}\\}\\}`, 'g');

      if (!exactMatch.test(content) && !helperMatch.test(content)) {
        missingPlaceholders.push(placeholder);
      }
    }

    if (missingPlaceholders.length > 0) {
      result.addWarning(
        `Template declares placeholders but they're not used: ${missingPlaceholders.join(', ')}`
      );
    }
  }

  // Check for balanced Handlebars blocks
  const openBlocks = (content.match(/\{\{#\w+/g) || []).length;
  const closeBlocks = (content.match(/\{\{\/\w+/g) || []).length;

  if (openBlocks !== closeBlocks) {
    result.addError(
      `Unbalanced Handlebars blocks: ${openBlocks} opening, ${closeBlocks} closing`
    );
  }

  // Info: Count Handlebars placeholders
  const placeholderMatches = content.match(/\{\{[^}]+\}\}/g) || [];
  const uniquePlaceholders = [...new Set(placeholderMatches)];
  result.addInfo(`Found ${uniquePlaceholders.length} unique Handlebars expressions`);

  // Info: Check if template uses helpers
  const helperMatches = content.match(/\{\{(pascalCase|camelCase|snakeCase|titleCase|kebabCase|upperSnakeCase|pluralize|singularize|formatDate|uppercase|lowercase|capitalize|trim|replace|concat|substr|startsWith|endsWith|contains|length|add|subtract|multiply|divide|mod|round|join|first|last|slice|now|year|default|json)/g) || [];
  if (helperMatches.length > 0) {
    const uniqueHelpers = [...new Set(helperMatches.map(m => m.replace('{{', '')))];
    result.addInfo(`Uses helpers: ${uniqueHelpers.join(', ')}`);
  }

  return result;
}

/**
 * Validates all templates
 * @param {string} projectPath - Project root path
 * @param {Object} options - Validation options
 * @returns {Array<ValidationResult>}
 */
export function validateAllTemplates(projectPath = process.cwd(), options = {}) {
  const {
    skipDeprecated = true,
    category = null,
    technology = null,
  } = options;

  const templates = getAllTemplates(projectPath);
  const results = [];

  for (const template of templates) {
    // Skip deprecated if requested
    if (skipDeprecated && template.deprecated) {
      continue;
    }

    // Filter by category if specified
    if (category && template.category !== category) {
      continue;
    }

    // Filter by technology if specified
    if (technology && template.technology !== technology) {
      continue;
    }

    const result = validateTemplate(template.id, projectPath);
    results.push(result);
  }

  return results;
}

/**
 * Generates a validation summary
 * @param {Array<ValidationResult>} results - Validation results
 * @returns {Object}
 */
export function summarizeValidation(results) {
  const summary = {
    total: results.length,
    valid: 0,
    hasErrors: 0,
    hasWarnings: 0,
    errors: [],
    warnings: [],
  };

  for (const result of results) {
    if (result.valid && result.warnings.length === 0) {
      summary.valid++;
    }

    if (result.errors.length > 0) {
      summary.hasErrors++;
      summary.errors.push({
        templateId: result.templateId,
        errors: result.errors,
      });
    }

    if (result.warnings.length > 0) {
      summary.hasWarnings++;
      summary.warnings.push({
        templateId: result.templateId,
        warnings: result.warnings,
      });
    }
  }

  return summary;
}

/**
 * Formats validation results for display
 * @param {Array<ValidationResult>} results - Validation results
 * @param {Object} options - Display options
 * @returns {string}
 */
export function formatValidationResults(results, options = {}) {
  const { showInfo = false, showValid = false } = options;

  let output = '';
  let validCount = 0;
  let errorCount = 0;
  let warningCount = 0;

  for (const result of results) {
    if (result.valid && result.warnings.length === 0) {
      validCount++;
      if (showValid) {
        output += `✅ ${result.templateId}\n`;
      }
      continue;
    }

    if (result.errors.length > 0) {
      errorCount++;
      output += `\n❌ ${result.templateId}\n`;
      output += `   Path: ${result.templatePath}\n`;
      for (const error of result.errors) {
        output += `   ERROR: ${error}\n`;
      }
    }

    if (result.warnings.length > 0) {
      warningCount++;
      if (result.errors.length === 0) {
        output += `\n⚠️  ${result.templateId}\n`;
        output += `   Path: ${result.templatePath}\n`;
      }
      for (const warning of result.warnings) {
        output += `   WARNING: ${warning}\n`;
      }
    }

    if (showInfo && result.info.length > 0) {
      for (const info of result.info) {
        output += `   INFO: ${info}\n`;
      }
    }
  }

  // Summary
  output += `\n${'='.repeat(60)}\n`;
  output += `SUMMARY:\n`;
  output += `  Total templates: ${results.length}\n`;
  output += `  ✅ Valid: ${validCount}\n`;
  output += `  ❌ Errors: ${errorCount}\n`;
  output += `  ⚠️  Warnings: ${warningCount}\n`;

  return output;
}
