/**
 * Moral Dilemma Events
 * Complex ethical decisions with lasting consequences
 * Ported from Python events/dilemmas/moral_choices.py
 *
 * Events:
 * - bullyDilemma: Bullying intervention dilemma
 * - braceletDilemma: Stolen bracelet dilemma
 * - foundLostPet: Finding someone's lost pet
 * - friendCheating: Friend cheating on partner
 * - foundExpensiveItem: Finding expensive item in store
 * - colleagueStealingCredit: Coworker taking credit
 * - strayAnimalDecision: Stray animal needs help
 * - witnessShoplifting: Witnessing shoplifting
 * - friendBorrowMoney: Friend asks to borrow money
 * - environmentalChoice: Convenience vs environment
 * - parentCareDecision: Caring for aging parent
 * - whistleblowerDecision: Discovering unethical behavior at work
 * - plagiarismAccusation: Accused of plagiarism at school
 * - legalTrouble: Facing legal problems requiring decisions
 */

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

/**
 * Extended dilemma with custom data
 */
interface DilemmaWithData extends DilemmaClass {
  friend?: string;
  bullies?: string[];
  classmate?: string;
  animal?: string;
  parent_type?: string;
}

/**
 * Helper: Get random friend from player relationships
 */
function getRandomFriend(player: Player): Person | null {
  const friends = (player.r ?? []).filter(
    (p) => p.relationships?.includes('friend') && p.status === 'alive'
  );
  if (friends.length === 0) return null;
  return friends[Math.floor(Math.random() * friends.length)];
}

/**
 * Helper: Get random classmate from player relationships
 */
function getRandomClassmate(player: Player): Person | null {
  const classmates = (player.r ?? []).filter(
    (p) => p.relationships?.includes('classmate') && p.status === 'alive'
  );
  if (classmates.length === 0) return null;
  return classmates[Math.floor(Math.random() * classmates.length)];
}

/**
 * Helper: Get person by ID
 */
function getPerson(player: Player, personId: string): Person | null {
  return (player.r ?? []).find((p) => p.id === personId) ?? null;
}

/**
 * Bully Dilemma - Bullying intervention
 */
export function bullyDilemma(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'bullyDilemma';
  const check =
    !player.askedQuestions.has(fname) &&
    (player.c.location ?? '').includes('school') &&
    player.c.ageYears >= 10 &&
    player.c.ageYears < 18 &&
    checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Stand up for your friend', '', 5),
    createAnswerOption("Don't do anything", '', 0),
    createAnswerOption('Join in on the bullying', '', 5),
  ];

  if (check && type !== 'answer') {
    const friend = getRandomFriend(player);
    if (friend) {
      const classmate1 = getRandomClassmate(player);
      const classmate2 = getRandomClassmate(player);
      if (classmate1 && classmate2) {
        const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
        dilemmaObj.friend = friend.id;
        dilemmaObj.bullies = [classmate1.id, classmate2.id];
        player.activeDilemmas.push(dilemmaObj);

        const message = `Your friend ${friend.firstname} ${friend.lastname} is being bullied by popular kids, ${classmate1.firstname} ${classmate1.lastname} and ${classmate2.firstname} ${classmate2.lastname}. What do you do?`;
        return createQuestionEvent(fname, message, player, true, { answerOptions });
      }
    }
  }

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

  if (dilemma && dilemma.step === 2) {
    const friend = getPerson(player, dilemma.friend ?? '');
    let message = '';

    if (dilemma.answer?.option === answerOptions[0].option) {
      message = `You stand up for your friend ${friend?.firstname ?? 'them'} and tell the bullies to stop. They stop and leave your friend alone.`;
      player.c.happiness = Math.min(100, (player.c.happiness ?? 50) + 10);
      if (friend) friend.affinity = Math.min(100, (friend.affinity ?? 50) + 20);
    } else if (dilemma.answer?.option === answerOptions[1].option) {
      message = `You don't do anything about the bullying and your friend ${friend?.firstname ?? 'them'} continues to be bullied.`;
      player.c.happiness = Math.max(0, (player.c.happiness ?? 50) - 10);
      if (friend) friend.affinity = Math.max(0, (friend.affinity ?? 50) - 15);
    } else if (dilemma.answer?.option === answerOptions[2].option) {
      message = `You join in on the bullying and your friend ${friend?.firstname ?? 'them'} continues to be bullied.`;
      player.c.happiness = Math.max(0, (player.c.happiness ?? 50) - 20);
      if (friend) friend.affinity = Math.max(0, (friend.affinity ?? 50) - 30);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Bracelet Dilemma - Stolen bracelet
 */
export function braceletDilemma(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'braceletDilemma';
  const check =
    !player.askedQuestions.has(fname) &&
    (player.c.location ?? '').includes('school') &&
    player.c.ageYears >= 5 &&
    player.c.ageYears < 18 &&
    checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Confront her directly about it', '', 5),
    createAnswerOption('Tell the teacher about it', '', 3),
    createAnswerOption("Don't do anything", '', 0),
  ];

  if (check && type !== 'answer') {
    const classmate = getRandomClassmate(player);
    if (classmate) {
      const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
      dilemmaObj.classmate = classmate.id;
      player.activeDilemmas.push(dilemmaObj);

      const message = `You received a bracelet from your grandmother and wear it to school, but one day it went missing. Today you saw that ${classmate.firstname} ${classmate.lastname} is wearing it. What do you do?`;
      return createQuestionEvent(fname, message, player, true, { answerOptions });
    }
  }

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

  if (dilemma && dilemma.step === 2 && dilemma.answer) {
    const classmate = getPerson(player, dilemma.classmate ?? '');
    const classmateName = classmate
      ? `${classmate.firstname} ${classmate.lastname}`
      : 'the classmate';
    let message = '';

    if (dilemma.answer.option === answerOptions[0].option) {
      message = `You confront ${classmateName} about the bracelet and she says that she found it on the ground and thought it was pretty. She apologizes and gives it back to you.`;
      player.c.happiness = Math.min(100, (player.c.happiness ?? 50) + 10);
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message = `You tell the teacher about the bracelet and she takes it from ${classmateName} and returns it to you.`;
      player.c.happiness = Math.min(100, (player.c.happiness ?? 50) + 5);
    } else {
      message = `You decide not to do anything about the bracelet and ${classmateName} continues to wear it.`;
      player.c.happiness = Math.max(0, (player.c.happiness ?? 50) - 10);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Found Lost Pet Dilemma
 */
export function foundLostPet(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'foundLostPet';
  const check =
    !player.askedQuestions.has(fname) && player.c.ageYears >= 8 && checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Take it to vet to scan chip', '', 15),
    createAnswerOption('Post on social media', '', 0),
    createAnswerOption('Keep the dog', '', 0),
    createAnswerOption('Leave it, not your problem', '', 0),
  ];

  if (check && type !== 'answer') {
    const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
    player.activeDilemmas.push(dilemmaObj);
    const message = 'You found a lost dog with a collar but no one around. What do you do?';
    return createQuestionEvent(fname, message, player, true, { answerOptions });
  }

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

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

    if (dilemma.answer.option === answerOptions[0].option) {
      message =
        'You take the dog to the vet. They scan the chip and contact the owner. The family is overjoyed to be reunited with their pet and thanks you profusely!';
      c.happiness = Math.min(100, (c.happiness ?? 50) + 20);
      c.social = Math.min(100, (c.social ?? 50) + 15);
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message =
        "You post photos of the dog on social media. Within hours, the owners see your post and come to pick up their beloved pet. They're so grateful!";
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
      c.social = Math.min(100, (c.social ?? 50) + 10);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message =
        "You decide to keep the dog. It's adorable and friendly, but you can't shake the feeling that somewhere, a family is heartbroken looking for their pet.";
      c.happiness = Math.min(100, (c.happiness ?? 50) + 30);
      c.social = Math.max(0, (c.social ?? 50) - 20);
    } else {
      message =
        'You leave the dog and walk away. You hope it finds its way home, but you wonder if you should have done more.';
      c.happiness = Math.max(0, (c.happiness ?? 50) - 10);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Friend Cheating Dilemma
 */
export function friendCheating(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'friendCheating';
  const check =
    !player.askedQuestions.has(fname) && player.c.ageYears >= 16 && checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Tell the partner', '', 10),
    createAnswerOption('Confront your friend', '', 15),
    createAnswerOption('Stay out of it', '', 0),
    createAnswerOption('Support your friend regardless', '', 0),
  ];

  if (check && type !== 'answer') {
    const friend = getRandomFriend(player);
    if (friend) {
      const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
      dilemmaObj.friend = friend.id;
      player.activeDilemmas.push(dilemmaObj);

      const message = `You discover that your friend ${friend.firstname} ${friend.lastname} is cheating on their partner. What do you do?`;
      return createQuestionEvent(fname, message, player, true, { answerOptions });
    }
  }

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

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

    if (dilemma.answer.option === answerOptions[0].option) {
      message = `You tell ${friend?.firstname ?? 'your friend'}'s partner about the cheating. They're devastated but grateful you told them. ${friend?.firstname ?? 'Your friend'} is furious with you and your friendship is severely damaged.`;
      if (friend) friend.affinity = Math.max(0, (friend.affinity ?? 50) - 30);
      c.social = Math.max(0, (c.social ?? 50) - 10);
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message = `You confront ${friend?.firstname ?? 'your friend'} about the cheating. They're defensive but eventually admit they need to make a choice. Your friendship is strained.`;
      if (friend) friend.affinity = Math.max(0, (friend.affinity ?? 50) - 10);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message = `You decide to stay out of it. It's not your place to get involved. But you feel guilty every time you see ${friend?.firstname ?? 'them'} and their partner together.`;
      c.happiness = Math.max(0, (c.happiness ?? 50) - 10);
    } else {
      message = `You support ${friend?.firstname ?? 'your friend'} no matter what. They appreciate your loyalty, but you feel uncomfortable condoning their behavior.`;
      if (friend) friend.affinity = Math.min(100, (friend.affinity ?? 50) + 10);
      c.happiness = Math.max(0, (c.happiness ?? 50) - 15);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Found Expensive Item Dilemma
 */
export function foundExpensiveItem(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'foundExpensiveItem';
  const check =
    !player.askedQuestions.has(fname) && player.c.ageYears >= 10 && checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Turn it in to store', '', 0),
    createAnswerOption('Look for owner yourself', '', 20),
    createAnswerOption('Keep it', '', 0),
    createAnswerOption('Leave it where it is', '', 0),
  ];

  if (check && type !== 'answer') {
    const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
    player.activeDilemmas.push(dilemmaObj);
    const message = 'You find an expensive phone in a store. What do you do?';
    return createQuestionEvent(fname, message, player, true, { answerOptions });
  }

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

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

    if (dilemma.answer.option === answerOptions[0].option) {
      message =
        "You turn the phone in to the store's lost and found. A week later, the owner contacts you to thank you and gives you a $50 reward for your honesty!";
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);
      c.social = Math.min(100, (c.social ?? 50) + 20);
      c.money = (c.money ?? 0) + 50;
      c.diamonds = (c.diamonds ?? 0) + 10;
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message =
        "You look through the phone to find the owner's contact info and call them. They're incredibly grateful and meet you to get it back. It feels good to help someone.";
      c.happiness = Math.min(100, (c.happiness ?? 50) + 25);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message =
        "You keep the phone. It's nice, but you feel guilty every time you use it, wondering who you took it from.";
      c.happiness = Math.max(0, (c.happiness ?? 50) - 30);
      c.money = (c.money ?? 0) + 200;
    } else {
      message =
        "You leave it where it is. Maybe the owner will come back for it. You hope they find it.";
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Colleague Stealing Credit Dilemma
 */
export function colleagueStealingCredit(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'colleagueStealingCredit';
  const check =
    !player.askedQuestions.has(fname) &&
    player.c.ageYears >= 22 &&
    player.c.ageYears <= 65 &&
    player.c.occupation === 'work' &&
    checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Call them out publicly', '', 0),
    createAnswerOption('Talk to them privately', '', 10),
    createAnswerOption('Tell your boss', '', 0),
    createAnswerOption('Let it go', '', 0),
  ];

  if (check && type !== 'answer') {
    const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
    player.activeDilemmas.push(dilemmaObj);
    const message = 'A coworker presented your idea as their own in a meeting. How do you respond?';
    return createQuestionEvent(fname, message, player, true, { answerOptions });
  }

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

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

    if (dilemma.answer.option === answerOptions[0].option) {
      message =
        "You call out your coworker in front of everyone. The room gets awkward. Your boss looks uncomfortable. You're right, but you've made an enemy.";
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
      c.social = Math.max(0, (c.social ?? 50) - 20);
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message =
        'You pull your coworker aside and tell them you know what happened. They apologize and agree to set the record straight. Your boss later acknowledges your contribution.';
      c.social = Math.min(100, (c.social ?? 50) + 5);
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message =
        'You tell your boss privately that it was your idea. They investigate and confirm it. Your coworker is reprimanded, and your boss knows they can trust you.';
      c.social = Math.max(0, (c.social ?? 50) - 10);
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);
    } else {
      message =
        "You let it go. It eats at you, but you decide it's not worth the conflict. Your coworker gets praised for 'their' work.";
      c.happiness = Math.max(0, (c.happiness ?? 50) - 20);
      c.social = Math.max(0, (c.social ?? 50) - 5);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Stray Animal Decision Dilemma
 */
export function strayAnimalDecision(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'strayAnimalDecision';
  const check =
    !player.askedQuestions.has(fname) && player.c.ageYears >= 10 && checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Adopt it', '', 15, 0, 200),
    createAnswerOption('Take to shelter', '', 10),
    createAnswerOption('Feed it but leave it', '', 0, 0, 50),
    createAnswerOption('Nothing', '', 0),
  ];

  if (check && type !== 'answer') {
    const animal = Math.random() < 0.5 ? 'cat' : 'dog';
    const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
    dilemmaObj.animal = animal;
    player.activeDilemmas.push(dilemmaObj);
    const message = `There's a skinny stray ${animal} in your neighborhood. It looks hungry and sad. What do you do?`;
    return createQuestionEvent(fname, message, player, true, { answerOptions });
  }

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

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

    if (dilemma.answer.option === answerOptions[0].option) {
      message = `You adopt the ${animal}! It takes some time and money to get them healthy, but they become a loving companion. Your life is enriched by their presence.`;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 30);
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message = `You take the ${animal} to a shelter where they can get proper care and hopefully find a home. It's the responsible choice.`;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message = `You start feeding the ${animal} regularly. They're healthier now, but you wonder if they'd be better off in a real home.`;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
    } else {
      message = `You do nothing. You see the ${animal} around sometimes, still looking thin and sad. You feel guilty.`;
      c.happiness = Math.max(0, (c.happiness ?? 50) - 10);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Witness Shoplifting Dilemma
 */
export function witnessShoplifting(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'witnessShoplifting';
  const check =
    !player.askedQuestions.has(fname) && player.c.ageYears >= 12 && checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Tell store employee', '', 0),
    createAnswerOption('Offer to buy them food', '', 0, 5, 20),
    createAnswerOption('Look the other way', '', 0),
    createAnswerOption('Talk to them about it', '', 10),
  ];

  if (check && type !== 'answer') {
    const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
    player.activeDilemmas.push(dilemmaObj);
    const message =
      'You see a teen shoplifting food from a grocery store. They look hungry. What do you do?';
    return createQuestionEvent(fname, message, player, true, { answerOptions });
  }

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

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

    if (dilemma.answer.option === answerOptions[0].option) {
      message =
        'You tell a store employee. They confront the teen, who looks scared and embarrassed. You followed the rules, but you feel bad.';
      c.social = Math.max(0, (c.social ?? 50) - 10);
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message =
        "You approach the teen and offer to buy them food. They're surprised but grateful. They explain they're going through a hard time. You help them find resources for assistance.";
      c.happiness = Math.min(100, (c.happiness ?? 50) + 25);
      c.social = Math.min(100, (c.social ?? 50) + 10);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message =
        "You look away and pretend you didn't see anything. You understand that sometimes people are desperate.";
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
    } else {
      message =
        'You talk to them about their situation. They open up about their struggles, and you help direct them to food banks and support services.';
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);
      c.social = Math.min(100, (c.social ?? 50) + 10);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Friend Borrow Money Dilemma
 */
export function friendBorrowMoney(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'friendBorrowMoney';
  const check =
    !player.askedQuestions.has(fname) &&
    player.c.ageYears >= 18 &&
    (player.c.money ?? 0) >= 500 &&
    checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Yes, give them money', '', 0, 0, 500),
    createAnswerOption('Yes, but make contract', '', 0, 5, 500),
    createAnswerOption('Offer smaller amount', '', 0, 0, 100),
    createAnswerOption('Say no', '', 0),
  ];

  if (check && type !== 'answer') {
    const friend = getRandomFriend(player);
    if (friend) {
      const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
      dilemmaObj.friend = friend.id;
      player.activeDilemmas.push(dilemmaObj);
      const message = `Your friend ${friend.firstname} ${friend.lastname} asks to borrow $500. They're in a tough spot. Do you lend it?`;
      return createQuestionEvent(fname, message, player, true, { answerOptions });
    }
  }

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

  if (dilemma && dilemma.step === 2 && dilemma.answer) {
    const friend = getPerson(player, dilemma.friend ?? '');
    const c = player.c;
    let message = '';
    const repayChance = Math.random();

    if (dilemma.answer.option === answerOptions[0].option) {
      if (repayChance > 0.5) {
        message = `${friend?.firstname ?? 'Your friend'} pays you back a few months later. They're grateful for your help and your friendship is stronger.`;
        c.money = (c.money ?? 0) + 500;
        if (friend) friend.affinity = Math.min(100, (friend.affinity ?? 50) + 20);
      } else {
        message = `Months pass and ${friend?.firstname ?? 'your friend'} hasn't paid you back. You're too uncomfortable to bring it up. Your friendship feels strained.`;
        if (friend) friend.affinity = Math.max(0, (friend.affinity ?? 50) - 10);
        c.happiness = Math.max(0, (c.happiness ?? 50) - 10);
      }
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message = `${friend?.firstname ?? 'Your friend'} agrees to sign a simple contract. They pay you back on schedule. Your friendship remains strong and the professionalism helped.`;
      c.money = (c.money ?? 0) + 500;
      if (friend) friend.affinity = Math.min(100, (friend.affinity ?? 50) + 10);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message = `You give ${friend?.firstname ?? 'your friend'} $100. It's not what they needed, but they appreciate the help. They seem disappointed but understanding.`;
      if (friend) friend.affinity = Math.min(100, (friend.affinity ?? 50) + 10);
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
    } else {
      message = `You tell ${friend?.firstname ?? 'your friend'} you can't lend them money. They're disappointed and the friendship feels awkward now.`;
      if (friend) friend.affinity = Math.max(0, (friend.affinity ?? 50) - 15);
      c.happiness = Math.max(0, (c.happiness ?? 50) - 10);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Environmental Choice Dilemma
 */
export function environmentalChoice(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'environmentalChoice';
  const check =
    !player.askedQuestions.has(fname) && player.c.ageYears >= 16 && checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Cheap flight', '', 30, 0, 200),
    createAnswerOption('Eco-friendly option', '', 0, 0, 400),
    createAnswerOption("Don't fly at all", '', 0),
    createAnswerOption('Train/bus instead', '', 40, 0, 150),
  ];

  if (check && type !== 'answer') {
    const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
    player.activeDilemmas.push(dilemmaObj);
    const message =
      'You need to travel across the country. You can take a cheap flight with multiple connections or pay more for a direct eco-friendlier option. What do you choose?';
    return createQuestionEvent(fname, message, player, true, { answerOptions });
  }

  if (type === 'answer' && player.activeDilemmas.length > 0) {
    const currentDilemma = player.activeDilemmas[
      player.activeDilemmas.length - 1
    ] as DilemmaWithData;
    currentDilemma.answer = answerOptions.find((opt) => opt.option === response?.option) ?? null;
    deductEnergy(player.c, currentDilemma.answer?.energyCost ?? 0);
    player.c.money = (player.c.money ?? 0) - (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 =
        "You take the cheap flight with multiple layovers. It's exhausting and takes all day, but you saved money. You try not to think about the carbon footprint.";
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message =
        'You pay extra for the more efficient direct flight. It costs more, but you feel good about making a more environmentally conscious choice.';
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message =
        "You decide not to make the trip at all. It's disappointing, but you feel you made the right environmental choice.";
      c.happiness = Math.max(0, (c.happiness ?? 50) - 10);
      c.social = Math.max(0, (c.social ?? 50) - 10);
    } else {
      message =
        "You take a train instead. It takes much longer and you're exhausted, but you enjoyed seeing the countryside and feel good about the lower environmental impact.";
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Parent Care Decision Dilemma
 */
export function parentCareDecision(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'parentCareDecision';
  const check =
    !player.askedQuestions.has(fname) &&
    player.c.ageYears >= 40 &&
    player.c.ageYears <= 70 &&
    checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Nursing home', '', 0, 0, 3000),
    createAnswerOption('Live with you', '', 30, 0, 500),
    createAnswerOption('Hire in-home care', '', 0, 0, 2000),
    createAnswerOption('Rely on siblings', '', 0),
  ];

  if (check && type !== 'answer') {
    const parentType = Math.random() < 0.5 ? 'mother' : 'father';
    const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
    dilemmaObj.parent_type = parentType;
    player.activeDilemmas.push(dilemmaObj);
    const message = `Your ${parentType} can no longer live alone safely. What's the best option?`;
    return createQuestionEvent(fname, message, player, true, { answerOptions });
  }

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

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

    if (dilemma.answer.option === answerOptions[0].option) {
      message = `You move your ${parentType} into a nursing home. They're well cared for, but you feel guilty every time you visit. They seem sad but understanding.`;
      c.happiness = Math.max(0, (c.happiness ?? 50) - 20);
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message = `Your ${parentType} moves in with you. It's challenging and exhausting, but you get to spend quality time together. They're grateful and you have no regrets.`;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message = `You hire in-home care for your ${parentType}. They can stay in their home with professional help. It's expensive but feels like the right balance.`;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 5);
    } else {
      message = `You arrange for your siblings to share care responsibilities. But they feel you're not doing your part, and family tensions increase.`;
      c.happiness = Math.max(0, (c.happiness ?? 50) - 15);
      c.social = Math.max(0, (c.social ?? 50) - 15);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Whistleblower Decision Dilemma
 */
export function whistleblowerDecision(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'whistleblowerDecision';
  const check =
    !player.askedQuestions.has(fname) &&
    player.c.ageYears >= 25 &&
    player.c.ageYears <= 65 &&
    player.c.occupation === 'work' &&
    checkProbability(1000);

  const answerOptions = [
    createAnswerOption('Report to authorities', '', 0, 20, 0),
    createAnswerOption('Report internally', '', 0),
    createAnswerOption('Look for new job first', '', 30),
    createAnswerOption('Stay silent', '', 0, 0, -500), // Negative = gain
  ];

  if (check && type !== 'answer') {
    const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
    player.activeDilemmas.push(dilemmaObj);
    const message = 'You discover your company is doing something unethical. Report it?';
    return createQuestionEvent(fname, message, player, true, { answerOptions });
  }

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

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

    if (dilemma.answer.option === answerOptions[0].option) {
      const outcome = Math.random();
      if (outcome > 0.5) {
        message =
          "You report to authorities. There's an investigation and the company is held accountable. You lose your job but you're protected as a whistleblower and find a better position. You did the right thing.";
        c.happiness = Math.min(100, (c.happiness ?? 50) + 30);
        c.occupation = 'unemployed';
      } else {
        message =
          "You report to authorities but the investigation goes nowhere. Your company finds out it was you and you're quietly let go. It was the right thing to do, but it cost you.";
        c.happiness = Math.min(100, (c.happiness ?? 50) + 20);
        c.occupation = 'unemployed';
      }
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message =
        "You report internally through proper channels. The company addresses the issue quietly. You keep your job but you're watched closely now.";
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
      c.social = Math.max(0, (c.social ?? 50) - 10);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message =
        'You start looking for a new job before saying anything. You find a position elsewhere and leave quietly. The unethical practices likely continue.';
      c.happiness = Math.max(0, (c.happiness ?? 50) - 10);
    } else {
      message =
        "You stay silent and keep collecting your paycheck. You rationalize it, but the guilt weighs on you. You're complicit now.";
      c.happiness = Math.max(0, (c.happiness ?? 50) - 30);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Plagiarism Accusation Dilemma
 * Accused of plagiarism at school - must defend yourself
 */
export function plagiarismAccusation(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'plagiarismAccusation';
  const check =
    !player.askedQuestions.has(fname) &&
    player.c.occupation === 'student' &&
    player.c.ageYears >= 14 &&
    player.c.ageYears <= 22 &&
    checkProbability(3000);

  const answerOptions = [
    createAnswerOption('Prove it was your own work', '', 30),
    createAnswerOption('Accept partial blame', '', 0),
    createAnswerOption('Fight the accusation aggressively', '', 40),
    createAnswerOption('Request a meeting with the accuser', '', 15),
  ];

  if (check && type !== 'answer') {
    const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
    player.activeDilemmas.push(dilemmaObj);
    const message =
      "You're accused of plagiarism on an important assignment. The accusation could affect your academic record. How do you respond?";
    return createQuestionEvent(fname, message, player, true, { answerOptions });
  }

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

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

    if (dilemma.answer.option === answerOptions[0].option) {
      message =
        'You spent hours gathering evidence, showing drafts and revision history. The accusation was dropped and your integrity is restored, but the ordeal was exhausting.';
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);
      c.social = Math.min(100, (c.social ?? 50) + 10);
    } else if (dilemma.answer.option === answerOptions[1].option) {
      message =
        "You admitted to poor citation practices. It's over quickly, but your grade suffers and you feel the weight of the mark on your record.";
      c.happiness = Math.max(0, (c.happiness ?? 50) - 20);
      c.social = Math.max(0, (c.social ?? 50) - 5);
    } else if (dilemma.answer.option === answerOptions[2].option) {
      message =
        'You fought back aggressively, accusing the teacher of unfair treatment. The process was draining, and your relationships with faculty suffered. The accusation was eventually dropped, but at a cost.';
      c.happiness = Math.min(100, (c.happiness ?? 50) + 5);
      c.social = Math.max(0, (c.social ?? 50) - 25);
    } else {
      message =
        'You requested a calm meeting with your teacher. You explained your process and showed your work. The misunderstanding was cleared up, and you earned respect for handling it maturely.';
      c.happiness = Math.min(100, (c.happiness ?? 50) + 20);
      c.social = Math.min(100, (c.social ?? 50) + 15);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * Legal Trouble Dilemma
 * Facing legal problems - must decide how to handle them
 */
export function legalTrouble(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  response?: { option?: string },
  dilemma?: DilemmaWithData
): EventResult {
  const fname = 'legalTrouble';
  const check =
    !player.askedQuestions.has(fname) &&
    player.c.ageYears >= 16 &&
    player.c.ageYears <= 100 &&
    checkProbability(5000);

  const answerOptions = [
    createAnswerOption('Hire expensive lawyer', '', 0, 0, 5000),
    createAnswerOption('Use public defender', '', 0),
    createAnswerOption('Represent yourself', '', 50),
    createAnswerOption('Settle out of court', '', 0, 0, 2000),
  ];

  if (check && type !== 'answer') {
    const dilemmaObj = createDilemma(fname, answerOptions) as DilemmaWithData;
    player.activeDilemmas.push(dilemmaObj);
    const message =
      "You're facing legal problems that could have serious consequences. How do you handle this situation?";
    return createQuestionEvent(fname, message, player, true, { answerOptions });
  }

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

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

    if (dilemma.answer.option === answerOptions[0].option) {
      if (outcome > 0.3) {
        message =
          'Your expensive lawyer mounted an excellent defense. The case was dismissed and your record remains clean. The cost was high, but worth it.';
        c.happiness = Math.min(100, (c.happiness ?? 50) + 20);
      } else {
        message =
          'Despite the expensive lawyer, the case went poorly. You have a mark on your record, but the penalties were minimized.';
        c.happiness = Math.max(0, (c.happiness ?? 50) - 10);
      }
    } else if (dilemma.answer.option === answerOptions[1].option) {
      if (outcome > 0.5) {
        message =
          'Your overworked public defender did their best. The outcome was acceptable, though the stress was immense.';
        c.happiness = Math.max(0, (c.happiness ?? 50) - 15);
      } else {
        message =
          "The public defender couldn't dedicate enough time to your case. The outcome was worse than you hoped, leaving you stressed and frustrated.";
        c.happiness = Math.max(0, (c.happiness ?? 50) - 30);
      }
    } else if (dilemma.answer.option === answerOptions[2].option) {
      if (outcome > 0.7) {
        message =
          'Representing yourself was incredibly stressful, but you studied hard and made compelling arguments. Against all odds, you won the case!';
        c.happiness = Math.min(100, (c.happiness ?? 50) + 30);
        c.social = Math.min(100, (c.social ?? 50) + 10);
      } else {
        message =
          'Representing yourself was overwhelming. The legal system is complex and you made mistakes. The outcome was not in your favor.';
        c.happiness = Math.max(0, (c.happiness ?? 50) - 40);
        c.social = Math.max(0, (c.social ?? 50) - 15);
      }
    } else {
      message =
        'You negotiated a settlement out of court. It cost you money, but the matter is resolved without going to trial. You feel relieved but financially strained.';
      c.happiness = Math.min(100, (c.happiness ?? 50) + 5);
    }

    const dilemmaIndex = player.activeDilemmas.indexOf(dilemma);
    if (dilemmaIndex > -1) player.activeDilemmas.splice(dilemmaIndex, 1);

    return createMessageEvent(fname, message, player, true);
  }

  return null;
}

/**
 * All legacy dilemma event functions.
 * @deprecated Use events/v2/catalog/dilemmas.ts in the v2 event runtime.
 */
export const dilemmaEvents = {
  bullyDilemma,
  braceletDilemma,
  foundLostPet,
  friendCheating,
  foundExpensiveItem,
  colleagueStealingCredit,
  strayAnimalDecision,
  witnessShoplifting,
  friendBorrowMoney,
  environmentalChoice,
  parentCareDecision,
  whistleblowerDecision,
  plagiarismAccusation,
  legalTrouble,
};
