/**
 * Domain Entity: Achievement
 *
 * Represents an achievement that can be earned by users.
 * Achievements are categorized by role (driver, steward, admin) and type.
 */

import { Entity } from '@core/shared/domain/Entity';

export type AchievementCategory = 'driver' | 'steward' | 'admin' | 'community';

export type AchievementRarity = 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary';

export interface AchievementProps {
  id: string;
  name: string;
  description: string;
  category: AchievementCategory;
  rarity: AchievementRarity;
  iconUrl?: string;
  points: number;
  requirements: AchievementRequirement[];
  isSecret: boolean;
  createdAt: Date;
}

export interface AchievementRequirement {
  type: 'races_completed' | 'wins' | 'podiums' | 'clean_races' | 'protests_handled' | 
        'leagues_managed' | 'seasons_completed' | 'consecutive_clean' | 'rating_threshold' |
        'trust_threshold' | 'events_stewarded' | 'members_managed' | 'championships_won';
  value: number;
  operator: '>=' | '>' | '=' | '<' | '<=';
}

export class Achievement extends Entity<string> {
  readonly name: string;
  readonly description: string;
  readonly category: AchievementCategory;
  readonly rarity: AchievementRarity;
  readonly iconUrl: string;
  readonly points: number;
  readonly requirements: AchievementRequirement[];
  readonly isSecret: boolean;
  readonly createdAt: Date;

  private constructor(props: AchievementProps) {
    super(props.id);
    
    this.name = props.name;
    this.description = props.description;
    this.category = props.category;
    this.rarity = props.rarity;
    this.iconUrl = props.iconUrl ?? '';
    this.points = props.points;
    this.requirements = props.requirements;
    this.isSecret = props.isSecret;
    this.createdAt = props.createdAt;
  }

  static create(props: Omit<AchievementProps, 'createdAt'> & { createdAt?: Date }): Achievement {
    if (!props.id || props.id.trim().length === 0) {
      throw new Error('Achievement ID is required');
    }

    if (!props.name || props.name.trim().length === 0) {
      throw new Error('Achievement name is required');
    }

    if (props.requirements.length === 0) {
      throw new Error('Achievement must have at least one requirement');
    }

    return new Achievement({
      ...props,
      createdAt: props.createdAt ?? new Date(),
    });
  }

  /**
   * Check if user stats meet all requirements
   */
  checkRequirements(stats: Record<string, number>): boolean {
    return this.requirements.every(req => {
      const value = stats[req.type] ?? 0;
      switch (req.operator) {
        case '>=': return value >= req.value;
        case '>': return value > req.value;
        case '=': return value === req.value;
        case '<': return value < req.value;
        case '<=': return value <= req.value;
        default: return false;
      }
    });
  }

  /**
   * Get rarity color for display
   */
  getRarityColor(): string {
    const colors: Record<AchievementRarity, string> = {
      common: '#9CA3AF',
      uncommon: '#22C55E',
      rare: '#3B82F6',
      epic: '#A855F7',
      legendary: '#F59E0B',
    };
    return colors[this.rarity];
  }

  /**
   * Get display text for hidden achievements
   */
  getDisplayName(): string {
    if (this.isSecret) {
      return '???';
    }
    return this.name;
  }

  getDisplayDescription(): string {
    if (this.isSecret) {
      return 'This achievement is secret. Keep playing to unlock it!';
    }
    return this.description;
  }
}
