import type { ADR, ADRTemplate, ADRTemplateDefinition } from './types.js';

export function getNygardTemplate(): ADRTemplateDefinition {
  return {
    name: 'nygard',
    description: 'Michael Nygard\'s template - simple and effective for most decisions',
    fields: [
      'title',
      'status',
      'date',
      'deciders',
      'context',
      'decision',
      'consequences',
      'tags',
      'relatedTo',
      'supersedes',
      'supersededBy'
    ],
    requiredFields: [
      'title',
      'deciders',
      'context',
      'decision',
      'consequences'
    ],
    optionalFields: [
      'tags',
      'relatedTo',
      'supersedes',
      'supersededBy'
    ]
  };
}

export function getMADRTemplate(): ADRTemplateDefinition {
  return {
    name: 'madr',
    description: 'Markdown Architectural Decision Records - comprehensive template with structured options',
    fields: [
      'title',
      'status',
      'date',
      'deciders',
      'context',
      'decisionDrivers',
      'consideredOptions',
      'decision',
      'consequences',
      'prosAndCons',
      'links',
      'tags',
      'relatedTo',
      'supersedes',
      'supersededBy'
    ],
    requiredFields: [
      'title',
      'deciders',
      'context',
      'decisionDrivers',
      'decision',
      'consequences'
    ],
    optionalFields: [
      'consideredOptions',
      'prosAndCons',
      'links',
      'tags',
      'relatedTo',
      'supersedes',
      'supersededBy'
    ]
  };
}

export function getYStatementTemplate(): ADRTemplateDefinition {
  return {
    name: 'y-statement',
    description: 'Y-statement - simple format focusing on context, decision, and consequences',
    fields: [
      'title',
      'status',
      'date',
      'deciders',
      'context',
      'decision',
      'consequences',
      'tags'
    ],
    requiredFields: [
      'title',
      'deciders',
      'context',
      'decision',
      'consequences'
    ],
    optionalFields: [
      'tags'
    ]
  };
}

export function renderADRTemplate(adr: ADR): string {
  let markdown = `# ${adr.id}: ${adr.title}\n\n`;

  // Status
  if (adr.template === 'y-statement') {
    markdown += `## Status: ${adr.status.charAt(0).toUpperCase() + adr.status.slice(1)}\n\n`;
  } else {
    markdown += `## Status\n\n`;
    markdown += `${adr.status.charAt(0).toUpperCase() + adr.status.slice(1)}\n\n`;
  }

  // Metadata
  markdown += `**Date**: ${adr.date.toISOString().split('T')[0]}\n`;
  markdown += `**Deciders**: ${adr.deciders.join(', ')}\n`;
  if (adr.tags && adr.tags.length > 0) {
    markdown += `**Tags**: ${adr.tags.join(', ')}\n`;
  }
  markdown += '\n';

  // Context
  markdown += `## Context\n\n${adr.context}\n\n`;

  // Decision Drivers (MADR only)
  if (adr.template === 'madr' && adr.decisionDrivers && adr.decisionDrivers.length > 0) {
    markdown += `## Decision Drivers\n\n`;
    adr.decisionDrivers.forEach(driver => {
      markdown += `* ${driver}\n`;
    });
    markdown += '\n';
  }

  // Considered Options (MADR only)
  if (adr.template === 'madr' && adr.consideredOptions && adr.consideredOptions.length > 0) {
    markdown += `## Considered Options\n\n`;
    adr.consideredOptions.forEach(option => {
      markdown += `* ${option.title} - ${option.description}\n`;
    });
    markdown += '\n';
  }

  // Decision
  markdown += `## Decision\n\n${adr.decision}\n\n`;

  // Consequences
  markdown += `## Consequences\n\n${adr.consequences}\n\n`;

  // Pros and Cons per option (MADR)
  if (adr.template === 'madr' && adr.consideredOptions && adr.consideredOptions.length > 0) {
    adr.consideredOptions.forEach(option => {
      markdown += `### ${option.title}\n\n`;
      if (option.description) {
        markdown += `${option.description}\n\n`;
      }
      option.pros.forEach(pro => {
        markdown += `* Good, because ${pro}\n`;
      });
      option.cons.forEach(con => {
        markdown += `* Bad, because ${con}\n`;
      });
      markdown += '\n';
    });
  }

  // Links/Relationships
  const hasLinks = adr.supersedes?.length || adr.supersededBy || adr.relatedTo?.length;
  if (hasLinks) {
    markdown += `## Links\n\n`;
    if (adr.supersedes && adr.supersedes.length > 0) {
      markdown += `* Supersedes: ${adr.supersedes.join(', ')}\n`;
    }
    if (adr.supersededBy) {
      markdown += `* Superseded by: ${adr.supersededBy}\n`;
    }
    if (adr.relatedTo && adr.relatedTo.length > 0) {
      markdown += `* Related to: ${adr.relatedTo.join(', ')}\n`;
    }
    markdown += '\n';
  }

  // Status History
  if (adr.statusHistory && adr.statusHistory.length > 0) {
    markdown += `## Status History\n\n`;
    adr.statusHistory.forEach(change => {
      markdown += `* ${change.from} → ${change.to} on ${change.date.toISOString().split('T')[0]}`;
      markdown += ` by ${change.changedBy}`;
      if (change.reason) {
        markdown += `: ${change.reason}`;
      }
      markdown += '\n';
    });
  }

  return markdown;
}

export function getTemplateFields(template: ADRTemplate): {
  required: string[];
  optional: string[];
} {
  switch (template) {
    case 'nygard':
      return {
        required: getNygardTemplate().requiredFields,
        optional: getNygardTemplate().optionalFields
      };
    case 'madr':
      return {
        required: getMADRTemplate().requiredFields,
        optional: getMADRTemplate().optionalFields
      };
    case 'y-statement':
      return {
        required: getYStatementTemplate().requiredFields,
        optional: getYStatementTemplate().optionalFields
      };
    default:
      throw new Error(`Unknown template: ${template}`);
  }
}

export function validateTemplateData(
  template: ADRTemplate,
  data: Record<string, any>
): { valid: boolean; errors: string[] } {
  const errors: string[] = [];
  const fields = getTemplateFields(template);

  // Check required fields
  for (const field of fields.required) {
    if (!(field in data) || data[field] === undefined || data[field] === null) {
      errors.push(`Missing required field: ${field}`);
    } else if (Array.isArray(data[field]) && data[field].length === 0 && field === 'deciders') {
      errors.push(`Field "deciders" cannot be empty`);
    }
  }

  // Validate array fields
  const arrayFields = ['deciders', 'tags', 'decisionDrivers', 'consideredOptions', 'prosAndCons'];
  for (const field of arrayFields) {
    if (field in data && data[field] !== undefined && !Array.isArray(data[field])) {
      errors.push(`Field "${field}" must be an array`);
    }
  }

  // Validate consideredOptions structure
  if (data.consideredOptions && Array.isArray(data.consideredOptions)) {
    data.consideredOptions.forEach((option: any, index: number) => {
      if (!option.title || !option.description || !option.pros || !option.cons) {
        errors.push(`Option must have title, description, pros, and cons`);
      }
    });
  }

  return {
    valid: errors.length === 0,
    errors
  };
}