/**
 * ActivityRecord and EducationRecord models
 * Ported from Python ActivityRecord and EducationRecord classes
 *
 * Tracks activity participation, progress, and achievements.
 */

export interface ActivityRecordData {
  id: string;
  type: string;
  dateStarted?: string;
  achievements?: string[];
  performance?: number;
  level?: number;
  focus?: string;
}

/**
 * ActivityRecord - tracks participation in activities
 */
export class ActivityRecord {
  id: string;
  type: string;
  dateStarted: string;
  achievements: string[];
  performance: number;
  level: number;
  focus: string;

  constructor(data: ActivityRecordData) {
    this.id = data.id;
    this.type = data.type;
    this.dateStarted = data.dateStarted ?? new Date().toISOString().split('T')[0];
    this.achievements = data.achievements ?? [];
    this.performance = data.performance ?? 50;
    this.level = data.level ?? 1;
    this.focus = data.focus ?? 'Balanced';
  }

  /**
   * Increment performance (called when activity is performed)
   */
  incrementPerformance(amount: number = 1): void {
    this.performance = Math.min(100, this.performance + amount);

    // Level up at performance thresholds
    if (this.performance >= 90 && this.level < 5) {
      this.level += 1;
      this.performance = 50; // Reset performance for new level
    }
  }

  /**
   * Add an achievement
   */
  addAchievement(achievement: string): void {
    if (!this.achievements.includes(achievement)) {
      this.achievements.push(achievement);
    }
  }

  /**
   * Get days since activity started
   */
  getDaysSinceStart(currentDate: string): number {
    const start = new Date(this.dateStarted);
    const current = new Date(currentDate);
    const diffTime = current.getTime() - start.getTime();
    return Math.floor(diffTime / (1000 * 60 * 60 * 24));
  }

  toJSON(): ActivityRecordData {
    return {
      id: this.id,
      type: this.type,
      dateStarted: this.dateStarted,
      achievements: this.achievements,
      performance: this.performance,
      level: this.level,
      focus: this.focus,
    };
  }

  static fromJSON(data: ActivityRecordData): ActivityRecord {
    return new ActivityRecord(data);
  }
}

export interface EducationRecordData extends ActivityRecordData {
  educationLevel?: string;
  location?: string;
  major?: string;
  minor?: string;
  GPA?: number;
  credits?: number;
  graduationDate?: string;
}

/**
 * EducationRecord - extends ActivityRecord for education tracking
 */
export class EducationRecord extends ActivityRecord {
  educationLevel: string;
  location: string;
  major: string;
  minor: string;
  GPA: number;
  credits: number;
  graduationDate: string;

  constructor(data: EducationRecordData) {
    super(data);
    this.educationLevel = data.educationLevel ?? '';
    this.location = data.location ?? '';
    this.major = data.major ?? '';
    this.minor = data.minor ?? '';
    this.GPA = data.GPA ?? 75; // Default GPA (0-100 scale like Python)
    this.credits = data.credits ?? 0;
    this.graduationDate = data.graduationDate ?? '';
  }

  /**
   * Update GPA based on performance
   */
  updateGPA(testScore: number): void {
    // Weight new score with existing GPA
    this.GPA = (this.GPA * 0.8) + (testScore * 0.2);
    this.GPA = Math.max(0, Math.min(100, this.GPA));
  }

  /**
   * Add credits
   */
  addCredits(amount: number): void {
    this.credits += amount;
  }

  /**
   * Check if graduated
   */
  hasGraduated(currentDate: string): boolean {
    if (!this.graduationDate) return false;
    return new Date(currentDate) >= new Date(this.graduationDate);
  }

  /**
   * Get GPA on 4.0 scale
   */
  getGPA4Scale(): number {
    // Convert 0-100 to 0-4.0
    return (this.GPA / 100) * 4.0;
  }

  toJSON(): EducationRecordData {
    return {
      ...super.toJSON(),
      educationLevel: this.educationLevel,
      location: this.location,
      major: this.major,
      minor: this.minor,
      GPA: this.GPA,
      credits: this.credits,
      graduationDate: this.graduationDate,
    };
  }

  static fromJSON(data: EducationRecordData): EducationRecord {
    return new EducationRecord(data);
  }
}

/**
 * Helper to get activity record by ID
 */
export function getActivityRecord(
  activityRecords: ActivityRecordData[],
  activityId: string
): ActivityRecord | undefined {
  const data = activityRecords.find(r => r.id === activityId);
  return data ? new ActivityRecord(data) : undefined;
}

/**
 * Helper to check if person has activity
 */
export function hasActivity(
  activityRecords: ActivityRecordData[],
  activityType: string
): boolean {
  return activityRecords.some(r => r.type === activityType);
}

/**
 * Helper to increment activity performance
 */
export function incrementActivityPerformance(
  activityRecords: ActivityRecordData[],
  activityId: string,
  amount: number = 1
): void {
  const record = activityRecords.find(r => r.id === activityId);
  if (record) {
    const activity = new ActivityRecord(record);
    activity.incrementPerformance(amount);
    Object.assign(record, activity.toJSON());
  }
}
