/**
 * Learning & Educational Activity Events
 * Activity events focused on learning and skill development (ages 6-100)
 */

import { BaseEvent, EventResult, AnswerOption, EventConfig } from '../base.js';
import { Player } from '../../models/index.js';

/**
 * Online Course Event
 */
export class OnlineCourseEvent extends BaseEvent {
  readonly id = 'onlineCourse';

  private getCourseTopic(player: Player): string {
    const job = player.c.job;
    if (job?.title) {
      const topics = [
        `Advanced ${job.title} Techniques`,
        'Leadership & Management',
        'Data Analysis',
        'Digital Marketing',
        'Project Management',
      ];
      return topics[Math.floor(Math.random() * topics.length)];
    }
    const topics = [
      'Web Development',
      'Graphic Design',
      'Business Analytics',
      'Digital Marketing',
      'Photography',
    ];
    return topics[Math.floor(Math.random() * topics.length)];
  }

  getConfig(): EventConfig {
    return {
      minAge: 16,
      maxAge: 100,
      baseChance: 0.001,
      triggerType: 'random',
    };
  }

  checkConditions(player: Player): boolean {
    const c = player.c;
    return (
      !player.askedQuestions.has(this.id) && c.ageYears >= 16 && c.ageYears <= 100
    );
  }

  getQuestion(player?: Player): string {
    const topic = player ? this.getCourseTopic(player) : 'a new skill';
    return `You want to take an online course in ${topic}. Enroll?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, paid course!', moneyCost: 100 },
      { option: 'Free course instead' },
      { option: 'Self-study without course' },
      { option: 'Not interested' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const topic = this.getCourseTopic(player);

    if (selectedOption === 0) {
      c.money = (c.money ?? 0) - 100;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);
      c.intelligence = Math.min(100, (c.intelligence ?? 50) + 5);

      return {
        type: 'messageEvent',
        message: `You enrolled in a paid online course in ${topic}! The structured curriculum and expert instruction will help you learn efficiently.`,
      };
    } else if (selectedOption === 1) {
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
      c.intelligence = Math.min(100, (c.intelligence ?? 50) + 3);

      return {
        type: 'messageEvent',
        message: `You found a great free course in ${topic}! It might take more self-discipline, but you're excited to learn.`,
      };
    } else if (selectedOption === 2) {
      c.intelligence = Math.min(100, (c.intelligence ?? 50) + 2);

      return {
        type: 'messageEvent',
        message: `You decide to teach yourself ${topic} through free resources. It's a slower path, but you enjoy the flexibility.`,
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
      return {
        type: 'messageEvent',
        message: "You decided learning a new skill isn't a priority right now.",
      };
    }
  }
}

/**
 * Learn Language Event
 */
export class LearnLanguageEvent extends BaseEvent {
  readonly id = 'learnLanguage';

  private getLanguage(): string {
    const languages = [
      'Spanish',
      'French',
      'Mandarin Chinese',
      'Japanese',
      'German',
      'Italian',
      'Portuguese',
      'Korean',
      'Arabic',
      'Russian',
    ];
    return languages[Math.floor(Math.random() * languages.length)];
  }

  getConfig(): EventConfig {
    return {
      minAge: 10,
      maxAge: 100,
      baseChance: 0.001,
      triggerType: 'random',
    };
  }

  checkConditions(player: Player): boolean {
    const c = player.c;
    return (
      !player.askedQuestions.has(this.id) && c.ageYears >= 10 && c.ageYears <= 100
    );
  }

  getQuestion(): string {
    const language = this.getLanguage();
    return `You want to learn ${language}. Start?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, formal classes!', moneyCost: 150 },
      { option: 'Use language app', moneyCost: 10 },
      { option: 'Study on own' },
      { option: 'Too hard' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const language = this.getLanguage();

    if (selectedOption === 0) {
      c.money = (c.money ?? 0) - 150;
      c.social = Math.min(100, (c.social ?? 50) + 10);
      c.intelligence = Math.min(100, (c.intelligence ?? 50) + 5);

      return {
        type: 'messageEvent',
        message: `You enrolled in formal ${language} classes! Having a teacher and classmates will make learning more effective.`,
      };
    } else if (selectedOption === 1) {
      c.money = (c.money ?? 0) - 10;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
      c.intelligence = Math.min(100, (c.intelligence ?? 50) + 3);

      return {
        type: 'messageEvent',
        message: `You downloaded a ${language} learning app! A few minutes of practice each day should help you progress.`,
      };
    } else if (selectedOption === 2) {
      c.intelligence = Math.min(100, (c.intelligence ?? 50) + 2);

      return {
        type: 'messageEvent',
        message: `You gathered textbooks and online resources to teach yourself ${language}. It'll be challenging, but you're determined!`,
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 10);
      return {
        type: 'messageEvent',
        message: 'You decided learning a new language is too difficult right now.',
      };
    }
  }
}

/**
 * Coding Bootcamp Event
 */
export class CodingBootcampEvent extends BaseEvent {
  readonly id = 'codingBootcamp';

  private getSpecialization(): string {
    const specializations = [
      'Full-Stack Web Development',
      'Data Science & Machine Learning',
      'Mobile App Development',
      'Cybersecurity',
      'DevOps Engineering',
    ];
    return specializations[Math.floor(Math.random() * specializations.length)];
  }

  getConfig(): EventConfig {
    return {
      minAge: 16,
      maxAge: 50,
      baseChance: 0.001,
      triggerType: 'random',
    };
  }

  checkConditions(player: Player): boolean {
    const c = player.c;
    return (
      !player.askedQuestions.has(this.id) && c.ageYears >= 16 && c.ageYears <= 50
    );
  }

  getQuestion(): string {
    const specialization = this.getSpecialization();
    return `There's a ${specialization} bootcamp starting. Interested?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, full-time bootcamp!', moneyCost: 3000, energyCost: 40 },
      { option: 'Part-time evening classes', moneyCost: 1500, energyCost: 20 },
      { option: 'Learn coding online free' },
      { option: 'Not for me' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const specialization = this.getSpecialization();

    if (selectedOption === 0) {
      c.money = (c.money ?? 0) - 3000;
      c.energy = Math.max(0, c.energy - 40);
      c.intelligence = Math.min(100, (c.intelligence ?? 50) + 10);

      return {
        type: 'messageEvent',
        message: `You enrolled in an intensive full-time ${specialization} bootcamp! The next few months will be exhausting but you'll gain valuable programming skills.`,
      };
    } else if (selectedOption === 1) {
      c.money = (c.money ?? 0) - 1500;
      c.energy = Math.max(0, c.energy - 20);
      c.intelligence = Math.min(100, (c.intelligence ?? 50) + 5);

      return {
        type: 'messageEvent',
        message: `You signed up for part-time evening ${specialization} classes! It'll be challenging to balance with everything else, but you're excited to learn.`,
      };
    } else if (selectedOption === 2) {
      c.intelligence = Math.min(100, (c.intelligence ?? 50) + 3);

      return {
        type: 'messageEvent',
        message: `You found free coding tutorials online for ${specialization}. It'll take longer without structure, but you can learn at your own pace.`,
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
      return {
        type: 'messageEvent',
        message: "You decided coding isn't something you want to pursue right now.",
      };
    }
  }
}

/**
 * Music Lessons Event
 */
export class MusicLessonsEvent extends BaseEvent {
  readonly id = 'musicLessons';

  private getInstrument(age: number): string {
    if (age < 10) {
      const instruments = ['piano', 'violin', 'ukulele', 'recorder'];
      return instruments[Math.floor(Math.random() * instruments.length)];
    } else if (age < 18) {
      const instruments = ['piano', 'guitar', 'violin', 'drums', 'saxophone', 'trumpet'];
      return instruments[Math.floor(Math.random() * instruments.length)];
    } else {
      const instruments = [
        'piano',
        'guitar',
        'violin',
        'drums',
        'saxophone',
        'bass guitar',
        'cello',
      ];
      return instruments[Math.floor(Math.random() * instruments.length)];
    }
  }

  getConfig(): EventConfig {
    return {
      minAge: 6,
      maxAge: 100,
      baseChance: 0.001,
      triggerType: 'random',
    };
  }

  checkConditions(player: Player): boolean {
    const c = player.c;
    return (
      !player.askedQuestions.has(this.id) && c.ageYears >= 6 && c.ageYears <= 100
    );
  }

  getQuestion(player?: Player): string {
    const instrument = player ? this.getInstrument(player.c.ageYears) : 'an instrument';
    return `You want to learn to play the ${instrument}. Take lessons?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, professional teacher!', moneyCost: 100 },
      { option: 'Learn from YouTube' },
      { option: 'Buy instrument, figure it out', moneyCost: 200 },
      { option: 'Not interested' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const instrument = this.getInstrument(c.ageYears);

    if (selectedOption === 0) {
      c.money = (c.money ?? 0) - 100;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 25);
      c.stress = Math.max(0, (c.stress ?? 0) - 10);

      return {
        type: 'messageEvent',
        message: `You signed up for professional ${instrument} lessons! Having a teacher will help you develop proper technique and avoid bad habits.`,
      };
    } else if (selectedOption === 1) {
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);
      c.stress = Math.max(0, (c.stress ?? 0) - 5);

      return {
        type: 'messageEvent',
        message: `You're learning ${instrument} from YouTube tutorials! It's free and flexible, though progress might be slower without feedback.`,
      };
    } else if (selectedOption === 2) {
      c.money = (c.money ?? 0) - 200;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);

      return {
        type: 'messageEvent',
        message: `You bought a ${instrument} and are teaching yourself! It'll be a journey of trial and error, but you enjoy the independence.`,
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
      return {
        type: 'messageEvent',
        message: "You decided learning an instrument isn't for you right now.",
      };
    }
  }
}

/**
 * Cooking Classes Event
 */
export class CookingClassesEvent extends BaseEvent {
  readonly id = 'cookingClasses';

  private getClassType(age: number): string {
    if (age < 18) {
      const types = ['Basic Cooking Skills', 'Baking Fundamentals', 'Teen Chef Program'];
      return types[Math.floor(Math.random() * types.length)];
    }
    const types = [
      'Italian Cuisine',
      'French Cooking',
      'Asian Fusion',
      'Baking & Pastry',
      'Vegetarian Cooking',
      'Culinary Techniques',
    ];
    return types[Math.floor(Math.random() * types.length)];
  }

  getConfig(): EventConfig {
    return {
      minAge: 12,
      maxAge: 100,
      baseChance: 0.001,
      triggerType: 'random',
    };
  }

  checkConditions(player: Player): boolean {
    const c = player.c;
    return (
      !player.askedQuestions.has(this.id) && c.ageYears >= 12 && c.ageYears <= 100
    );
  }

  getQuestion(player?: Player): string {
    const classType = player ? this.getClassType(player.c.ageYears) : 'cooking';
    return `${classType} classes are available at community center. Join?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, sign up!', moneyCost: 75 },
      { option: 'Learn from cookbooks' },
      { option: 'Watch cooking videos' },
      { option: 'Not interested' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const classType = this.getClassType(c.ageYears);

    if (selectedOption === 0) {
      c.money = (c.money ?? 0) - 75;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 20);
      c.social = Math.min(100, (c.social ?? 50) + 10);

      return {
        type: 'messageEvent',
        message: `You enrolled in ${classType} classes! You'll learn new techniques and recipes while meeting fellow food enthusiasts.`,
      };
    } else if (selectedOption === 1) {
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
      c.intelligence = Math.min(100, (c.intelligence ?? 50) + 3);

      return {
        type: 'messageEvent',
        message:
          "You checked out some cookbooks from the library. You'll teach yourself by trying new recipes at home.",
      };
    } else if (selectedOption === 2) {
      c.happiness = Math.min(100, (c.happiness ?? 50) + 5);

      return {
        type: 'messageEvent',
        message:
          'You found some cooking channels online. Watching chefs in action is a great way to pick up tips and tricks.',
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
      return {
        type: 'messageEvent',
        message: "You decided cooking classes aren't for you right now.",
      };
    }
  }
}

// Export all learning events
export const learningEvents = [
  new OnlineCourseEvent(),
  new LearnLanguageEvent(),
  new CodingBootcampEvent(),
  new MusicLessonsEvent(),
  new CookingClassesEvent(),
];
