/**
 * School Milestone Events
 * Major school milestone events for fast mode gameplay (ages 5-17)
 * These are significant life moments: report cards, dances, prom, science fair, college prep
 */

import { Player } from '../../models/Player';
import {
  createMessageEvent,
  createQuestionEvent,
  createAnswerOption,
  createDilemma,
  checkProbability,
  modifyStat,
  type DilemmaClass,
  type EventResult,
} from '../base';
import { deductEnergy } from '../../utils/statUtils.js';

// ──────────────────────────────────────────────
// Report Card Day
// ──────────────────────────────────────────────

export function reportCardDay(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = `reportCardDay_${player.character.ageYears}`;
  const check = !player.askedQuestions.has(fname) &&
    player.character.occupation === 'student' &&
    player.character.ageYears >= 6 &&
    player.character.ageYears <= 17 &&
    (player.monthOfYear === 1 || player.monthOfYear === 6) &&
    checkProbability(5);

  if (check) {
    player.askedQuestions.add(fname);
  }

  const intelligence = player.character.intelligence ?? 50;
  let gradeMsg: string;
  if (intelligence >= 80) {
    gradeMsg = "straight A's! Your parents are thrilled.";
  } else if (intelligence >= 60) {
    gradeMsg = "mostly B's with a couple A's. Solid work.";
  } else if (intelligence >= 40) {
    gradeMsg = "a mix of B's and C's. Room for improvement.";
  } else {
    gradeMsg = "mostly C's and D's. Your parents want to have a talk.";
  }

  return createQuestionEvent(
    fname,
    `Report cards are in! You got ${gradeMsg} How do you react?`,
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Show it off proudly', '', 0, 0, 0),
        createAnswerOption('Promise to study harder next semester', '', 10, 0, 0),
        createAnswerOption('Hide it from your parents', '', 0, 5, 0),
        createAnswerOption('Ask for a tutor', '', 0, 0, 50),
      ],
    }
  );
}

// ──────────────────────────────────────────────
// School Dance
// ──────────────────────────────────────────────

export function schoolDance(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = `schoolDance_${player.character.ageYears}`;
  const check = !player.askedQuestions.has(fname) &&
    player.character.occupation === 'student' &&
    player.character.ageYears >= 12 &&
    player.character.ageYears <= 17 &&
    checkProbability(80);

  if (check) {
    player.askedQuestions.add(fname);
  }

  return createQuestionEvent(
    fname,
    "There's a school dance coming up this weekend! What's your plan?",
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Go with a date - buy a new outfit', '', 10, 0, 75),
        createAnswerOption('Go with friends - keep it casual', '', 5, 0, 25),
        createAnswerOption('Go solo and just have fun', '', 5, 0, 0),
        createAnswerOption('Skip it and stay home', '', 0, 0, 0),
      ],
    }
  );
}

// ──────────────────────────────────────────────
// Prom (multi-stage via dilemma)
// ──────────────────────────────────────────────

interface PromDilemma extends DilemmaClass {
  promChoice?: string;
}

export function promEvent(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: PromDilemma
): EventResult {
  const fname = 'promEvent';
  const check = !player.askedQuestions.has(fname) &&
    player.character.occupation === 'student' &&
    player.character.ageYears >= 16 &&
    player.character.ageYears <= 18 &&
    player.monthOfYear >= 4 &&
    player.monthOfYear <= 5 &&
    checkProbability(10);

  const answerOptions = [
    createAnswerOption('Go all out - limo, fancy outfit, the works', '', 15, 0, 300),
    createAnswerOption('Keep it simple but still attend', '', 5, 0, 75),
    createAnswerOption('Ask someone special to be your date', '', 10, 10, 100),
    createAnswerOption('Skip prom entirely', '', 0, 0, 0),
  ];

  if (check && type !== 'answer') {
    player.askedQuestions.add(fname);
    const dilemmaObj = createDilemma(fname, answerOptions) as PromDilemma;
    player.activeDilemmas.push(dilemmaObj);
    return createQuestionEvent(
      fname,
      "Prom is around the corner! This is one of the biggest nights of high school. How do you want to handle it?",
      player,
      true,
      { answerOptions }
    );
  }

  if (type === 'answer' && player.activeDilemmas.length > 0) {
    const currentDilemma = player.activeDilemmas[player.activeDilemmas.length - 1] as PromDilemma;
    currentDilemma.answer = answerOptions.find(opt => opt.option === response?.option) ?? null;
    currentDilemma.promChoice = currentDilemma.answer?.option;
    deductEnergy(player.c, currentDilemma.answer?.energyCost ?? 0);
    player.money -= currentDilemma.answer?.moneyCost ?? 0;
  }

  if (dilemma && dilemma.step === 2 && dilemma.answer) {
    const c = player.c;
    let message = '';

    if (dilemma.answer.option === answerOptions[0].option) {
      message = "Prom night was unforgettable! The limo, the outfit, the dancing - you felt like a movie star. Everyone was impressed and you made memories that will last a lifetime.";
      c.happiness = modifyStat(c.happiness, 25);
      c.social = modifyStat(c.social, 15);
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message = "You had a great time at prom without breaking the bank. The music was fun, the decorations were nice, and you danced the night away with friends.";
      c.happiness = modifyStat(c.happiness, 15);
      c.social = modifyStat(c.social, 10);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      const accepted = Math.random() > 0.3;
      if (accepted) {
        message = "They said yes! Prom with your date was magical. You slow-danced, took photos, and had the best night of high school.";
        c.happiness = modifyStat(c.happiness, 30);
        c.social = modifyStat(c.social, 20);
      } else {
        message = "They said they already had plans. You went with friends instead and still had fun, but it stung a little.";
        c.happiness = modifyStat(c.happiness, 5);
        c.social = modifyStat(c.social, 5);
      }
    } else {
      message = "You skipped prom. Your friends sent photos and it looked fun, but you enjoyed a quiet night in. No regrets... mostly.";
      c.happiness = modifyStat(c.happiness, -5);
    }

    const idx = player.activeDilemmas.indexOf(dilemma);
    if (idx > -1) player.activeDilemmas.splice(idx, 1);
    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

// ──────────────────────────────────────────────
// Science Fair (multi-stage via dilemma)
// ──────────────────────────────────────────────

interface ScienceFairDilemma extends DilemmaClass {
  projectType?: string;
}

export function scienceFair(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: ScienceFairDilemma
): EventResult {
  const fname = 'scienceFair';
  const check = !player.askedQuestions.has(fname) &&
    player.character.occupation === 'student' &&
    player.character.ageYears >= 10 &&
    player.character.ageYears <= 16 &&
    checkProbability(120);

  const answerOptions = [
    createAnswerOption('Build an elaborate volcano model', '', 20, 0, 40),
    createAnswerOption('Design a coding project', '', 15, 0, 20),
    createAnswerOption('Do a simple poster board experiment', '', 5, 0, 10),
    createAnswerOption('Partner with the class genius', '', 0, 10, 15),
  ];

  if (check && type !== 'answer') {
    player.askedQuestions.add(fname);
    const dilemmaObj = createDilemma(fname, answerOptions) as ScienceFairDilemma;
    player.activeDilemmas.push(dilemmaObj);
    return createQuestionEvent(
      fname,
      "The annual science fair is coming up and your teacher says participation counts for 20% of your grade! What kind of project will you do?",
      player,
      true,
      { answerOptions }
    );
  }

  if (type === 'answer' && player.activeDilemmas.length > 0) {
    const currentDilemma = player.activeDilemmas[player.activeDilemmas.length - 1] as ScienceFairDilemma;
    currentDilemma.answer = answerOptions.find(opt => opt.option === response?.option) ?? null;
    currentDilemma.projectType = currentDilemma.answer?.option;
    deductEnergy(player.c, currentDilemma.answer?.energyCost ?? 0);
    player.money -= currentDilemma.answer?.moneyCost ?? 0;
  }

  if (dilemma && dilemma.step === 2 && dilemma.answer) {
    const c = player.c;
    const intelligence = c.intelligence ?? 50;
    const placementRoll = Math.random() * 100 + intelligence * 0.3;
    let message = '';

    if (dilemma.answer.option === answerOptions[0].option) {
      if (placementRoll > 80) {
        message = "Your volcano was the talk of the fair! The eruption was spectacular and you won first place. The judges loved your detailed research.";
        c.intelligence = modifyStat(c.intelligence, 10);
        c.happiness = modifyStat(c.happiness, 20);
        player.diamonds += 5;
      } else {
        message = "Your volcano looked great but the eruption fizzled. You got an honorable mention. Still, you learned a lot about chemistry!";
        c.intelligence = modifyStat(c.intelligence, 5);
        c.happiness = modifyStat(c.happiness, 5);
      }
    } else if (dilemma.answer.option === answerOptions[1].option) {
      if (placementRoll > 70) {
        message = "Your coding project impressed the judges with its creativity! You won second place and your teacher asked you to present it to other classes.";
        c.intelligence = modifyStat(c.intelligence, 12);
        c.happiness = modifyStat(c.happiness, 15);
        player.diamonds += 3;
      } else {
        message = "Your coding project had a few bugs during the demo, but the concept was solid. You got a good grade and learned a lot.";
        c.intelligence = modifyStat(c.intelligence, 8);
      }
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message = "Your poster board was neat and well-organized. It wasn't flashy, but you got a decent grade without too much stress.";
      c.intelligence = modifyStat(c.intelligence, 3);
      c.happiness = modifyStat(c.happiness, 5);
    } else {
      if (Math.random() > 0.5) {
        message = "Your partner did most of the work and your project won third place. You got a good grade, but you know you didn't really earn it.";
        c.happiness = modifyStat(c.happiness, -5);
        c.intelligence = modifyStat(c.intelligence, 2);
      } else {
        message = "Your partner flaked and you had to scramble to finish alone. The project was mediocre, but at least you learned self-reliance.";
        c.intelligence = modifyStat(c.intelligence, 5);
        c.happiness = modifyStat(c.happiness, -10);
      }
    }

    const idx = player.activeDilemmas.indexOf(dilemma);
    if (idx > -1) player.activeDilemmas.splice(idx, 1);
    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

// ──────────────────────────────────────────────
// Bullying Event
// ──────────────────────────────────────────────

export function schoolBullying(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'schoolBullying';
  const check = !player.askedQuestions.has(fname) &&
    player.character.occupation === 'student' &&
    player.character.ageYears >= 8 &&
    player.character.ageYears <= 16 &&
    checkProbability(300);

  if (check) {
    player.askedQuestions.add(fname);
  }

  return createQuestionEvent(
    fname,
    "Someone at school has been spreading rumors about you and it's getting worse. Kids are laughing when you walk by. What do you do?",
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Tell a teacher or counselor', '', 5, 0, 0),
        createAnswerOption('Confront the bully directly', '', 15, 0, 0),
        createAnswerOption('Ignore it and hope it passes', '', 0, 0, 0),
        createAnswerOption('Tell your parents', '', 0, 5, 0),
      ],
    }
  );
}

// ──────────────────────────────────────────────
// Class President Election
// ──────────────────────────────────────────────

export function classPresident(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'classPresident';
  const check = !player.askedQuestions.has(fname) &&
    player.character.occupation === 'student' &&
    player.character.ageYears >= 12 &&
    player.character.ageYears <= 17 &&
    (player.character.social ?? 50) >= 40 &&
    checkProbability(200);

  if (check) {
    player.askedQuestions.add(fname);
  }

  return createQuestionEvent(
    fname,
    "Student council elections are coming up and a friend nominates you for class president! Do you run?",
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Run a serious campaign - make posters, give speeches', '', 20, 0, 30),
        createAnswerOption('Run casually - see what happens', '', 5, 0, 0),
        createAnswerOption('Decline the nomination', '', 0, 0, 0),
        createAnswerOption('Run as a joke candidate', '', 5, 5, 10),
      ],
    }
  );
}

// ──────────────────────────────────────────────
// Detention
// ──────────────────────────────────────────────

export function detention(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'detention';
  const check = !player.askedQuestions.has(fname) &&
    player.character.occupation === 'student' &&
    player.character.ageYears >= 10 &&
    player.character.ageYears <= 17 &&
    checkProbability(250);

  if (check) {
    player.askedQuestions.add(fname);
  }

  const reasons = [
    "talking in class",
    "being late too many times",
    "using your phone during a test",
    "passing notes",
    "arguing with a teacher",
  ];
  const reason = reasons[Math.floor(Math.random() * reasons.length)];

  return createQuestionEvent(
    fname,
    `You got detention for ${reason}! How do you handle it?`,
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Serve it quietly and learn your lesson', '', 10, 0, 0),
        createAnswerOption('Try to talk your way out of it', '', 5, 5, 0),
        createAnswerOption('Skip detention', '', 0, 10, 0),
        createAnswerOption('Use the time to study', '', 15, 0, 0),
      ],
    }
  );
}

// ──────────────────────────────────────────────
// College Prep (multi-stage via dilemma)
// ──────────────────────────────────────────────

interface CollegePrepDilemma extends DilemmaClass {
  prepStyle?: string;
}

export function collegePrep(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: CollegePrepDilemma
): EventResult {
  const fname = 'collegePrep';
  const check = !player.askedQuestions.has(fname) &&
    player.character.occupation === 'student' &&
    player.character.ageYears >= 16 &&
    player.character.ageYears <= 17 &&
    checkProbability(50);

  const answerOptions = [
    createAnswerOption('Hire a college admissions consultant', '', 10, 0, 500),
    createAnswerOption('Study hard and apply broadly', '', 25, 0, 100),
    createAnswerOption('Focus on extracurriculars for your application', '', 15, 0, 50),
    createAnswerOption('Not sure about college yet', '', 0, 0, 0),
  ];

  if (check && type !== 'answer') {
    player.askedQuestions.add(fname);
    const dilemmaObj = createDilemma(fname, answerOptions) as CollegePrepDilemma;
    player.activeDilemmas.push(dilemmaObj);
    return createQuestionEvent(
      fname,
      "Junior year is winding down and college applications are on the horizon. Your guidance counselor wants to know your plan. How do you approach college prep?",
      player,
      true,
      { answerOptions }
    );
  }

  if (type === 'answer' && player.activeDilemmas.length > 0) {
    const currentDilemma = player.activeDilemmas[player.activeDilemmas.length - 1] as CollegePrepDilemma;
    currentDilemma.answer = answerOptions.find(opt => opt.option === response?.option) ?? null;
    currentDilemma.prepStyle = currentDilemma.answer?.option;
    deductEnergy(player.c, currentDilemma.answer?.energyCost ?? 0);
    player.money -= currentDilemma.answer?.moneyCost ?? 0;
  }

  if (dilemma && dilemma.step === 2 && dilemma.answer) {
    const c = player.c;
    let message = '';

    if (dilemma.answer.option === answerOptions[0].option) {
      message = "The consultant helped polish your essays and target the right schools. You feel confident about your applications, though your wallet is lighter.";
      c.intelligence = modifyStat(c.intelligence, 5);
      c.happiness = modifyStat(c.happiness, 10);
      c.stress = modifyStat(c.stress, -10);
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message = "You spent months studying for standardized tests and writing essays late into the night. It was exhausting, but you applied to a wide range of schools and feel good about your chances.";
      c.intelligence = modifyStat(c.intelligence, 10);
      c.happiness = modifyStat(c.happiness, 5);
      c.stress = modifyStat(c.stress, 15);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message = "You doubled down on your extracurriculars - leading clubs, volunteering, and competing. Your application tells a great story of leadership.";
      c.social = modifyStat(c.social, 10);
      c.happiness = modifyStat(c.happiness, 10);
    } else {
      message = "You decided to keep your options open. Maybe college, maybe trade school, maybe something else entirely. Your parents are a bit worried, but you feel free.";
      c.happiness = modifyStat(c.happiness, -5);
      c.stress = modifyStat(c.stress, -5);
    }

    const idx = player.activeDilemmas.indexOf(dilemma);
    if (idx > -1) player.activeDilemmas.splice(idx, 1);
    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

// ──────────────────────────────────────────────
// Graduation Day
// ──────────────────────────────────────────────

export function graduationDay(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'graduationDay';
  const check = !player.events.has(fname) &&
    player.character.occupation === 'student' &&
    player.character.ageYears === 17 &&
    player.monthOfYear === 6 &&
    checkProbability(5);

  if (check) {
    player.events.add(fname);
    player.c.happiness = modifyStat(player.c.happiness, 25);
    player.c.social = modifyStat(player.c.social, 10);
    player.diamonds += 10;
    // Thread the graduating student's actual GPA so the `straight_a` achievement
    // ("Graduate with a 4.0 GPA") can fire. GPA on the education record is stored
    // on a 0-100 scale (default 50, see education_manager.handleEducation), so we
    // convert to the 0-4.0 scale here at the source — keeping the achievement
    // check's `>= 4.0` correct (100/100 => 4.0). A missing record reads as 0.
    const eduGpa100 = (player.character.current_education?.gpa as number | undefined) ?? 0;
    const gpa4Scale = (eduGpa100 / 100) * 4.0;
    player.lifecycleQueue.push({ type: 'graduation', data: { level: 'high school', gpa: gpa4Scale } });
  }

  return createMessageEvent(
    fname,
    "You did it! You throw your cap in the air as the crowd cheers. High school is over. Your family is beaming with pride and the future is full of possibility.",
    player,
    check,
    { diamondCost: -10 }
  );
}

/**
 * All school milestone event functions
 */
export const schoolMilestoneEvents = {
  reportCardDay,
  schoolDance,
  promEvent,
  scienceFair,
  schoolBullying,
  classPresident,
  detention,
  collegePrep,
  graduationDay,
};
