/**
 * Health Events
 * Health-related events, injuries, illnesses, and conditions
 *
 * Events:
 * - minorInjury: Minor scrapes and injuries
 * - minorSickness: Common colds and illnesses
 * - breakArm: Breaking an arm
 * - healthCondition: Developing a health condition
 * - lowEnergyEvent: Low energy consequences
 * - negativeHabitEvent: Negative habit manifestations
 * - annualCheckup: Routine annual doctor's appointment
 * - allergySymptoms: Discovering seasonal allergies
 * - dentalCavity: Dentist finds a cavity
 * - dentalEmergency: Emergency dental situation
 * - mentalHealthDay: Recognizing need for mental health break
 * - sprainedAnkle: Minor sports/activity injury
 * - eyeStrain: Too much screen time effects
 * - backPain: Developing back problems
 * - chronicPain: Long-term pain management
 * - firstGrayHair: Finding first gray hair
 * - sleepDisorder: Struggling with insomnia
 * - seriousIllness: Diagnosed with serious illness
 * - injuryFromAccident: Injury from an accident
 * - foodPoisoning: Getting sick from bad food
 */

import { Player } from '../../models/Player';
import { createMessageEvent, createQuestionEvent, checkProbability, createAnswerOption, modifyStat, type EventResult } from '../base';
import { getHealthConditions, type Habit, type HealthCondition } from '../../services/health/health_manager';
import { deductEnergy } from '../../utils/statUtils.js';

export function minorInjury(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'minorInjury';
  const check = !player.askedQuestions.has(fname) &&
    player.character.ageYears > 5 &&
    player.character.ageYears < 15 &&
    checkProbability(1000000);

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

  return createQuestionEvent(
    fname,
    "You are playing outside with your friends and you fall down. You scrape your knee and it is bleeding. What do you do?",
    player,
    check,
    { answerOptions: ['Go home and tell your parents', 'Ignore it and keep playing'] }
  );
}

export function minorSickness(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'sickness';
  const check = !player.askedQuestions.has(fname) &&
    player.character.ageYears > 5 &&
    player.character.ageYears < 15 &&
    checkProbability(1000000);

  if (check) {
    player.askedQuestions.add(fname);
    deductEnergy(player.character, Math.floor(Math.random() * 10) + 1);
  }

  return createQuestionEvent(
    fname,
    "You have caught a pretty bad cold, you feel weak are coughing and sneezing.",
    player,
    check,
    { answerOptions: ['Stay home and rest', 'Go to school anyways'] }
  );
}

export function breakArm(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'breakArm';
  const check = !player.events.has(fname) &&
    player.character.ageYears >= 6 &&
    checkProbability(10000);

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

  return createMessageEvent(fname, "You fell and broke your arm", player, check);
}

export function annualCheckup(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'annualCheckup';
  const check = !player.askedQuestions.has(fname) &&
    player.character.ageYears >= 18 &&
    checkProbability(50000);

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

  return createQuestionEvent(
    fname,
    "It's time for your annual checkup. Do you go?",
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Yes, schedule it', '', 0, 0, 100),
        createAnswerOption('No, skip it'),
        createAnswerOption('Go only if sick')
      ]
    }
  );
}

export function allergySymptoms(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'allergySymptoms';
  const currentMonth = parseInt(player.date.split('-')[0], 10);
  const isSpring = currentMonth >= 3 && currentMonth <= 5;
  const check = !player.events.has(fname) &&
    player.character.ageYears >= 10 &&
    isSpring &&
    checkProbability(100000);

  if (check) {
    player.events.add(fname);
    deductEnergy(player.character, 5);
  }

  return createMessageEvent(
    fname,
    "Your eyes are itchy and you can't stop sneezing. Looks like you have seasonal allergies.",
    player,
    check
  );
}

export function dentalCavity(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'dentalCavity';
  const check = !player.askedQuestions.has(fname) &&
    player.character.ageYears >= 8 &&
    checkProbability(100000);

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

  return createQuestionEvent(
    fname,
    "The dentist found a cavity. You need a filling.",
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Get it filled now', '', 0, 0, 200),
        createAnswerOption('Schedule for later', '', 0, 0, 200),
        createAnswerOption('Ignore it')
      ]
    }
  );
}

export function mentalHealthDay(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'mentalHealthDay';
  const check = !player.askedQuestions.has(fname) &&
    player.character.ageYears >= 16 &&
    player.character.ageYears <= 65 &&
    (player.character.happiness < 30 || player.character.energy < 20) &&
    checkProbability(10000);

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

  return createQuestionEvent(
    fname,
    "You're feeling overwhelmed and anxious. Take a mental health day?",
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Yes, take the day off'),
        createAnswerOption('No, push through'),
        createAnswerOption('Talk to someone', '', 0, 5, 0)
      ]
    }
  );
}

export function sprainedAnkle(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'sprainedAnkle';
  const check = !player.events.has(fname) &&
    player.character.ageYears >= 10 &&
    player.character.ageYears <= 50 &&
    checkProbability(100000);

  if (check) {
    player.events.add(fname);
    deductEnergy(player.character, 15);
    player.character.happiness -= 10;
  }

  return createMessageEvent(
    fname,
    "You rolled your ankle. It's not broken, but it hurts to walk for a few days.",
    player,
    check,
    { energyCost: 15 }
  );
}

export function backPain(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'backPain';
  const check = !player.events.has(fname) &&
    player.character.ageYears >= 30 &&
    checkProbability(100000);

  if (check) {
    player.events.add(fname);
    player.character.energy = modifyStat(player.character.energy, -5);
    player.character.health = modifyStat(player.character.health, -5);
  }

  return createMessageEvent(
    fname,
    "Your back has been hurting lately. Maybe you should exercise more... or sleep on a better mattress.",
    player,
    check
  );
}

export function firstGrayHair(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'firstGrayHair';
  const check = !player.events.has(fname) &&
    player.character.ageYears >= 28 &&
    player.character.ageYears <= 45 &&
    checkProbability(100000);

  if (check) {
    player.events.add(fname);
    player.character.happiness -= 5;
  }

  return createMessageEvent(
    fname,
    "You found your first gray hair. When did that happen?!",
    player,
    check
  );
}

export function sleepDisorder(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'sleepDisorder';
  const check = !player.askedQuestions.has(fname) &&
    player.character.ageYears >= 18 &&
    player.character.energy < 30 &&
    checkProbability(50000);

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

  return createQuestionEvent(
    fname,
    "You've been having trouble sleeping. What do you try?",
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Melatonin/sleep aids', '', 0, 0, 30),
        createAnswerOption('Better sleep schedule'),
        createAnswerOption('See a doctor', '', 0, 5, 150),
        createAnswerOption('Suffer through it')
      ]
    }
  );
}

export function foodPoisoning(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'foodPoisoning';
  const check = !player.events.has(fname) &&
    player.character.ageYears >= 10 &&
    checkProbability(100000);

  if (check) {
    player.events.add(fname);
    player.character.energy = modifyStat(player.character.energy, -30);
    player.character.happiness = modifyStat(player.character.happiness, -20);
    player.character.health = modifyStat(player.character.health, -10);
  }

  return createMessageEvent(
    fname,
    "Something you ate didn't agree with you. You spend the next 24 hours very sick.",
    player,
    check,
    { energyCost: 30 }
  );
}

/**
 * Developing a health condition
 * Chance increases with age, selects from available health conditions
 */
export function healthCondition(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'healthCondition';

  // Set a base chance and increment it based on player's age
  const baseChance = 0.0000001;  // 0.00001% base chance to trigger
  const ageMultiplier = 0.00000001;  // increase chance by 0.000001% for each year of age
  const triggerChance = baseChance + (player.character.ageYears * ageMultiplier);

  // Access healthConditions on character
  const characterAny = player.character as unknown as { healthConditions?: HealthCondition[] };
  const existingConditions = characterAny.healthConditions ?? [];

  // Only trigger health check with the given chance if player has no conditions
  if (Math.random() <= triggerChance && existingConditions.length === 0) {
    const conditions = getHealthConditions();
    if (conditions && conditions.length > 0) {
      // Sort the conditions based on healthModifier in descending order
      conditions.sort((a, b) => b.healthModifier - a.healthModifier);

      // Determine the max index for condition selection based on player's age
      const ageIndex = Math.min(player.character.ageYears, conditions.length - 1);

      // Select the condition randomly from the available range
      const condition = conditions[Math.floor(Math.random() * (ageIndex + 1))];
      condition.date = player.date;

      // Initialize healthConditions array if not present
      if (!characterAny.healthConditions) {
        characterAny.healthConditions = [];
      }
      characterAny.healthConditions.push(condition);

      const message = `You have been diagnosed with ${condition.title}.`;
      return createMessageEvent(fname, message, player, true);
    }
  }

  return null;
}

/**
 * Low energy consequences
 * Triggers when player is exhausted in the evening
 */
export function lowEnergyEvent(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'lowEnergyEvent';

  // Check conditions: low energy, evening hours, random chance
  if (
    Math.random() < 1 / 10 &&
    player.character.energy < 10 &&
    player.hourOfDay > 18 &&
    player.hourOfDay < 23
  ) {
    const copingOptions = [
      ' To cope you end up scrolling through social media for hours.',
      ' To cope you end up watching TV for hours.',
      ' To cope you end up playing video games for hours.',
      ' To cope you end up eating junk food for hours.',
      ' To cope you end up drinking too much alcohol.',
      ' To cope you end up lighting a cigarette.',
    ];

    // Filter out age-inappropriate options for minors
    const filteredOptions = player.character.ageYears < 18
      ? copingOptions.slice(0, 4)  // Exclude alcohol and smoking
      : copingOptions;

    const message = "After a long day, you're feeling exhausted." +
      filteredOptions[Math.floor(Math.random() * filteredOptions.length)];

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

  return null;
}

/**
 * Negative habit manifestations
 * Shows consequences of player's negative habits
 */
export function negativeHabitEvent(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'negativeHabitEvent';

  if (Math.random() >= 1 / 1000) {
    return null;
  }

  // Get habits from character
  const characterAny = player.character as unknown as { habits?: Habit[] };
  const habits = characterAny.habits ?? [];

  // Filter to negative habits only
  let negativeHabits = habits.filter(habit => habit.habitType === 'negative');

  // Check for age and occupation constraints
  if (player.character.ageYears < 18) {
    negativeHabits = negativeHabits.filter(
      habit => habit.name !== 'excessive_alcohol_consumption' && habit.name !== 'smoking'
    );
  }
  if (player.character.occupation !== 'student') {
    negativeHabits = negativeHabits.filter(habit => habit.name !== 'tardiness');
  }

  if (negativeHabits.length === 0) {
    return null;
  }

  const habit = negativeHabits[Math.floor(Math.random() * negativeHabits.length)];

  // Define multiple messages for each habit
  const habitMessages: Record<string, string[]> = {
    tardiness: [
      'You are late for school again. Your teacher gives you a warning.',
      'You missed the start of the movie due to your tardiness.',
    ],
    nail_biting: [
      "You've been biting your nails again. Your fingers are sore.",
      'Your friends notice your nail biting habit.',
      "You've bitten your nails to the quick, causing discomfort.",
    ],
    overthinking: [
      'You spend hours overthinking a decision and end up feeling exhausted.',
      'Your overthinking is causing you sleepless nights.',
      'You overthink a situation to the point where it paralyzes you from taking action.',
    ],
    procrastination: [
      'You procrastinate on an important task and now have to rush to complete it.',
      'Your procrastination has resulted in a late fee on a bill.',
      "You procrastinated and now you're stuck with the least desirable options.",
    ],
    negative_thinking: [
      'You find yourself dwelling on negative thoughts, affecting your mood.',
      'Your negative thinking is affecting your relationships.',
      "You're caught in a loop of negative thinking, making it hard to see the positive.",
    ],
    overeating: [
      'You give in to emotional eating and feel guilty afterward.',
      'You overeat at dinner and feel uncomfortably full.',
      'You keep eating past the point of fullness out of boredom.',
    ],
    under_exercising: [
      "You haven't been getting much exercise lately, and you're starting to feel the effects.",
      "You've been missing your exercise routine, and your energy levels are suffering.",
      'Your lack of exercise is affecting your mood and overall health.',
    ],
    excessive_screen_time: [
      'Your eyes are tired from too much screen time.',
      "You've been on screens all day, causing headaches.",
      'Your excessive screen time is affecting your sleep pattern.',
    ],
    impulsiveness: [
      'Your impulsive action had unintended consequences.',
      'Your impulsiveness led to a poor purchase decision.',
      'Your impulsive behavior led to a risky situation.',
    ],
    indecisiveness: [
      "You've spent all day trying to make a decision, and it's causing stress.",
      'Your indecisiveness is causing delays and missed opportunities.',
      'Your indecisiveness made others make the decision for you.',
    ],
    neglecting_self_care: [
      "You've been neglecting your self-care routine and it's starting to show.",
      'Your lack of self-care is affecting your energy and mood.',
      'You feel rundown from neglecting basic self-care.',
    ],
    poor_time_management: [
      "You're scrambling to finish a project due to poor time management.",
      'Your leisure time is cut short due to your poor time management.',
    ],
    overeating_when_stressed: [
      "You've been stress eating, and it's making you feel uncomfortable.",
      "You eat more than usual when you're stressed, and it's affecting your health.",
      'Your stress eating is leading to discomfort and guilt.',
    ],
    excessive_caffeine_intake: [
      'The excessive caffeine is making it hard for you to sleep at night.',
      "You're feeling jittery from excessive caffeine intake.",
      'You have a caffeine crash from consuming too much.',
    ],
    smoking: [
      "You notice a smoker's cough developing. It's a reminder of your habit.",
      "You're short of breath during physical activities, a result of your smoking habit.",
      'Your sense of taste and smell are compromised due to smoking.',
    ],
    excessive_alcohol_consumption: [
      'Your frequent alcohol consumption is leading to regular morning hangovers.',
      "You're using alcohol as a crutch to deal with stress.",
      'Your excessive drinking is leading to forgetfulness and regret.',
    ],
  };

  const messages = habitMessages[habit.name];
  const message = messages
    ? messages[Math.floor(Math.random() * messages.length)]
    : 'Your habit is causing some issues.';

  // Adjust player attributes depending on the habit
  if (['nail_biting', 'negative_thinking'].includes(habit.name)) {
    player.character.happiness = modifyStat(player.character.happiness, -5);
  } else if ([
    'overthinking', 'procrastination', 'excessive_screen_time', 'impulsiveness',
    'indecisiveness', 'neglecting_self_care', 'poor_time_management', 'excessive_caffeine_intake'
  ].includes(habit.name)) {
    player.character.energy = modifyStat(player.character.energy, -5);
    player.character.happiness = modifyStat(player.character.happiness, -5);
  } else if ([
    'overeating', 'overeating_when_stressed', 'excessive_alcohol_consumption', 'smoking'
  ].includes(habit.name)) {
    player.character.health = modifyStat(player.character.health, -5);
    player.character.happiness = modifyStat(player.character.happiness, -5);
  }

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

/**
 * Eye strain from too much screen time
 * Only triggers if player has excessive_screen_time habit
 */
export function eyeStrain(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'eyeStrain';

  // Check if player has excessive screen time habit
  const characterAny = player.character as unknown as { habits?: Habit[] };
  const habits = characterAny.habits ?? [];
  const hasScreenHabit = habits.some(habit => habit.name === 'excessive_screen_time');

  const check = !player.events.has(fname) &&
    player.character.ageYears >= 10 &&
    hasScreenHabit &&
    checkProbability(50000);

  if (check) {
    player.events.add(fname);
    player.character.energy = modifyStat(player.character.energy, -5);
    player.character.health = modifyStat(player.character.health, -5);
  }

  return createMessageEvent(
    fname,
    'Your eyes hurt from staring at screens all day. You should probably take more breaks.',
    player,
    check
  );
}

/**
 * Dental emergency requiring immediate attention
 */
export function dentalEmergency(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'dentalEmergency';
  const check = !player.askedQuestions.has(fname) &&
    player.character.ageYears >= 12 &&
    checkProbability(200000);

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

  return createQuestionEvent(
    fname,
    "You wake up with severe tooth pain. It's unbearable!",
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Emergency dentist visit', '', 0, 0, 500),
        createAnswerOption('Try pain medication first', '', 0, 0, 20),
        createAnswerOption('Wait and hope it gets better')
      ]
    }
  );
}

/**
 * Chronic pain development
 * More common in older adults
 */
export function chronicPain(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'chronicPain';
  const check = !player.askedQuestions.has(fname) &&
    player.character.ageYears >= 35 &&
    checkProbability(150000);

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

  return createQuestionEvent(
    fname,
    "You've been experiencing persistent pain that won't go away. How do you handle it?",
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('See a specialist', '', 0, 0, 300),
        createAnswerOption('Physical therapy', '', 10, 0, 200),
        createAnswerOption('Over-the-counter medication', '', 0, 0, 30),
        createAnswerOption('Try to ignore it')
      ]
    }
  );
}

/**
 * Serious illness diagnosis
 * Rare but life-changing event
 */
export function seriousIllness(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'seriousIllness';

  // Chance increases with age
  const baseChance = 500000 - (player.character.ageYears * 2000);
  const adjustedChance = Math.max(baseChance, 100000);

  const check = !player.askedQuestions.has(fname) &&
    player.character.ageYears >= 25 &&
    checkProbability(adjustedChance);

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

  const illnesses = [
    'a chronic condition',
    'a condition that requires monitoring',
    'an autoimmune disorder',
    'a condition requiring lifestyle changes',
  ];
  const illness = illnesses[Math.floor(Math.random() * illnesses.length)];

  return createQuestionEvent(
    fname,
    `After some tests, your doctor has diagnosed you with ${illness}. How do you want to proceed?`,
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Follow all medical advice', '', 0, 0, 500),
        createAnswerOption('Get a second opinion', '', 0, 5, 300),
        createAnswerOption('Research treatment options', '', 20, 0, 0),
        createAnswerOption('Seek alternative medicine', '', 0, 0, 200)
      ]
    }
  );
}

/**
 * Injury from an accident
 * Can happen at any age above childhood
 */
export function injuryFromAccident(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'injuryFromAccident';
  const check = !player.askedQuestions.has(fname) &&
    player.character.ageYears >= 8 &&
    checkProbability(150000);

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

  const accidents = [
    { desc: 'You slipped and fell badly', injury: 'bruised hip' },
    { desc: 'You had a minor accident', injury: 'sprained wrist' },
    { desc: 'You got hurt while exercising', injury: 'pulled muscle' },
    { desc: 'You bumped into something hard', injury: 'nasty bruise' },
  ];

  // Add driving-related accidents for adults who can drive
  if (player.character.canDrive && player.character.ageYears >= 16) {
    accidents.push(
      { desc: 'You were in a fender bender', injury: 'whiplash' },
      { desc: 'You had a minor car accident', injury: 'sore neck' }
    );
  }

  const accident = accidents[Math.floor(Math.random() * accidents.length)];

  return createQuestionEvent(
    fname,
    `${accident.desc} and now you have a ${accident.injury}. What do you do?`,
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Go to the doctor', '', 0, 0, 150),
        createAnswerOption('Rest and recover at home', '', 0, 0, 0),
        createAnswerOption('Push through the pain', '', 10, 0, 0),
        createAnswerOption('Get checked at urgent care', '', 0, 0, 200)
      ]
    }
  );
}
