/**
 * Career and Employment Events
 * Jobs, work, and career progression (ages 15+)
 *
 * Events:
 * - firstJob: First part-time job (ages 15-18)
 * - jobApplication: Post-college job application
 * - employeeOfTheMonth: Recognition at work
 * - openBankAccount: Opening first bank account (ages 15-20)
 * - jobOffer: Job opportunities for unemployed adults
 * - firstJobResponse: Handler for first job answers
 * - jobApplicationResponse: Handler for job application answers
 * - openBankAccountResponse: Handler for bank account answers
 */

import { Player } from '../../models/Player';
import { createMessageEvent, createQuestionEvent, checkProbability, createAnswerOption, type EventResult, type AnswerOption } from '../base';
import { getOccupations, getOccupationsByRequirement, setJob, type Occupation } from '../../services/jobs/job_manager.js';

/**
 * First part-time job opportunity (ages 15-18)
 * Triggers when player is old enough for work but doesn't have a job
 */
export function firstJob(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  _unused?: unknown,
  response?: { option: string; index: number }
): EventResult {
  const fname = 'firstJob';

  // Handle response
  if (type === 'answer' && response) {
    if (response.option === 'None' || response.index === undefined) {
      return createMessageEvent(
        `${fname}_declined`,
        "You decide to focus on school for now. Maybe later.",
        player,
        true
      );
    }

    // Map answer to job effects
    const jobEffects: Record<string, { salary: number; skill: string }> = {
      'Fast Food Worker': { salary: 50, skill: 'Work experience' },
      'Retail Associate': { salary: 55, skill: 'Customer service' },
      'Babysitter': { salary: 40, skill: 'Responsibility' },
      'Lawn Care': { salary: 45, skill: 'Physical fitness' }
    };

    const selectedJob = jobEffects[response.option];
    if (selectedJob) {
      // Set up part-time job
      player.character.occupation = 'work';
      player.character.job = {
        id: response.option.toLowerCase().replace(/\s+/g, '_'),
        title: response.option,
        levels: [{ level: 'Part-time', salary: selectedJob.salary }],
        requirements: 'none'
      } as Occupation;
      player.character.money += selectedJob.salary;
      player.character.happiness += 10;

      return createMessageEvent(
        `${fname}_accepted`,
        `Congratulations on your first job as a ${response.option}! You'll earn $${selectedJob.salary}/week. Time to start building that work experience!`,
        player,
        true
      );
    }
    return null;
  }

  const check = !player.askedQuestions.has(fname) &&
    !player.character.job &&
    player.character.ageYears >= 15 &&
    player.character.ageYears < 18 &&
    checkProbability(500);

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

  return createQuestionEvent(
    fname,
    "You are now old enough for your first part-time job, what would you like to do?",
    player,
    check,
    {
      answerOptions: ['Fast Food Worker', 'Retail Associate', 'Babysitter', 'Lawn Care', 'None']
    }
  );
}

/**
 * Post-college job application
 * Triggers after graduating with a degree
 */
export function jobApplication(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  _unused?: unknown,
  response?: { option: string; index: number }
): EventResult {
  const fname = 'jobApplication';

  // Handle response
  if (type === 'answer' && response) {
    if (response.option === 'None' || response.index === undefined) {
      return createMessageEvent(
        `${fname}_declined`,
        "You decide to take some time off before entering the workforce.",
        player,
        true
      );
    }

    // Job options with salary and effects
    const jobOptions: Record<string, { salary: number; prestige: number; stress: number }> = {
      'Entry Level Position': { salary: 800, prestige: 10, stress: 15 },
      'Internship': { salary: 400, prestige: 5, stress: 10 },
      'Freelance Work': { salary: 600, prestige: 8, stress: 20 }
    };

    const selectedJob = jobOptions[response.option];
    if (selectedJob) {
      // Set up the job
      player.character.occupation = 'work';
      player.character.job = {
        id: response.option.toLowerCase().replace(/\s+/g, '_'),
        title: response.option,
        levels: [{ level: 'Junior', salary: selectedJob.salary }],
        requirements: 'bachelors_degree'
      } as Occupation;
      player.character.money += selectedJob.salary;
      player.character.happiness += 15;
      player.character.stress = (player.character.stress ?? 0) + selectedJob.stress;

      const collegeName = player.character.college?.title || 'college';
      return createMessageEvent(
        `${fname}_accepted`,
        `You've landed your first post-${collegeName} job as ${response.option}! Starting salary: $${selectedJob.salary}/week. Your career has officially begun!`,
        player,
        true
      );
    }
    return null;
  }

  const check = !player.askedQuestions.has(fname) &&
    !!player.character.major &&
    !!player.character.college &&
    player.character.occupation === 'work' &&
    !player.character.job &&
    checkProbability(100);

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

  const collegeName = player.character.college?.title || 'college';
  return createQuestionEvent(
    fname,
    `You have graduated from ${collegeName} and are now applying for jobs! What position would you like to apply for?`,
    player,
    check,
    {
      answerOptions: ['Entry Level Position', 'Internship', 'Freelance Work', 'None']
    }
  );
}

/**
 * Employee of the Month recognition
 * Triggered for hard-working employees with good performance
 */
export function employeeOfTheMonth(player: Player, _type: 'message' | 'question' = 'message'): EventResult {
  const fname = 'employeeOfTheMonth';

  // Check job performance record if available
  const jobRecord = player.character.activityRecords?.find(
    (r: { type: string; id: string }) => r.type === 'job' && r.id === player.character.job?.id
  );

  // More likely if performance is good
  const performanceBonus = jobRecord && (jobRecord.performance ?? 50) >= 60;
  const probabilityDivisor = performanceBonus ? 500 : 2000;

  const check = !player.events.has(fname) &&
    !!player.character.job &&
    checkProbability(probabilityDivisor);

  if (check) {
    player.events.add(fname);
    // Award bonus
    const bonus = Math.floor((player.character.job?.levels?.[0]?.salary || 100) * 0.25);
    player.character.money += bonus;
    player.character.happiness += 20;

    // Boost job performance
    if (jobRecord) {
      jobRecord.performance = Math.min(100, (jobRecord.performance ?? 50) + 10);
      const achievement = 'Employee of the Month';
      if (!jobRecord.achievements?.includes(achievement)) {
        jobRecord.achievements = jobRecord.achievements ?? [];
        jobRecord.achievements.push(achievement);
      }
    }

    return createMessageEvent(
      fname,
      `You were named Employee of the Month! Your hard work is being recognized. You receive a $${bonus} bonus!`,
      player,
      true
    );
  }

  return null;
}

/**
 * Opening first bank account (ages 15-20)
 * A milestone in financial independence
 */
export function openBankAccount(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  _unused?: unknown,
  response?: { option: string; index: number }
): EventResult {
  const fname = 'openbankAccount';

  // Handle response
  if (type === 'answer' && response) {
    if (response.index === 0) {
      // Standard account - costs $10
      if (player.character.money >= 10) {
        player.character.money -= 10;
        player.character.hasBankAccount = true;

        return createMessageEvent(
          `${fname}_standard`,
          "You've opened your first bank account! No more stuffing cash under the mattress. Welcome to financial responsibility!",
          player,
          true,
          { moneyCost: 10 }
        );
      } else {
        return createMessageEvent(
          `${fname}_insufficient`,
          "You don't have enough money for the account fees. Maybe save up a bit more first.",
          player,
          true
        );
      }
    } else if (response.index === 1) {
      // Premium account with bonus - costs diamonds
      player.character.hasBankAccount = true;
      player.character.money += 50; // Promotional bonus

      return createMessageEvent(
        `${fname}_premium`,
        "You've opened a premium account with a $50 sign-up bonus! Smart financial move. The account also comes with better interest rates.",
        player,
        true,
        { diamondCost: 10 }
      );
    }
    return null;
  }

  const check = !player.askedQuestions.has(fname) &&
    player.character.ageYears >= 15 &&
    player.character.ageYears <= 20 &&
    !player.character.hasBankAccount &&
    checkProbability(1000);

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

  return createQuestionEvent(
    fname,
    "You're making real money now and the piggy bank isn't big enough anymore! What's next?",
    player,
    check,
    {
      answerOptions: [
        createAnswerOption('Open a new account at the local bank', '', 0, 0, 10),
        createAnswerOption('Open a new account with a promotional bonus', '', 0, 10, 0)
      ]
    }
  );
}

/**
 * Get jobs available for player based on education
 */
function getAvailableJobs(player: Player): Occupation[] {
  const education = player.character.education || '';
  let availableJobs: Occupation[] = [];

  // Jobs with no requirements are always available
  availableJobs = availableJobs.concat(getOccupationsByRequirement('none'));

  // Add high school jobs if qualified
  if (education.includes('high_school') || education.includes('10th') ||
      education.includes('11th') || education.includes('12th') ||
      education.includes('bachelor') || education.includes('doctor')) {
    availableJobs = availableJobs.concat(getOccupationsByRequirement('high_school'));
  }

  // Add bachelor's degree jobs if qualified
  if (education.includes('bachelor') || education.includes('doctor')) {
    availableJobs = availableJobs.concat(getOccupationsByRequirement('bachelors_degree'));
  }

  // Add doctorate jobs if qualified
  if (education.includes('doctor')) {
    availableJobs = availableJobs.concat(getOccupationsByRequirement('doctorate_degree'));
  }

  return availableJobs;
}

/**
 * Job offer event for unemployed adults
 * Triggers periodically for adults without jobs, offering random positions
 */
export function jobOffer(
  player: Player,
  type: 'message' | 'question' | 'answer' = 'message',
  _unused?: unknown,
  response?: { option: string; index: number }
): EventResult {
  const fname = 'jobOffer';

  // Early exit if player already has a job
  if (player.character.job) {
    return null;
  }

  // Handle response
  if (type === 'answer' && response) {
    // If "Not interested" was selected, just return
    if (response.option === 'Not interested' || response.index === undefined) {
      return null;
    }

    // Find the job by title from available jobs
    const availableJobs = getAvailableJobs(player);
    const selectedJob = availableJobs.find(j => j.title === response.option);

    if (selectedJob) {
      setJob(player.character, selectedJob, player.date);
      return createMessageEvent(
        `${fname}_accepted`,
        `Congratulations! You've been hired as a ${selectedJob.levels[0].level} at ${selectedJob.title}. Your starting salary is $${selectedJob.levels[0].salary}/week.`,
        player,
        true
      );
    }
    return null;
  }

  // Check if event should trigger - only for unemployed adults
  const isUnemployed = !player.character.occupation ||
    player.character.occupation === 'unemployed';

  // Only trigger for adults 18+ who are unemployed
  const isAdult = player.character.ageYears >= 18;

  const check = isUnemployed &&
    isAdult &&
    checkProbability(2000); // Less frequent - once per ~83 game days on average

  if (!check) return null;

  // Get random job offers based on education
  const availableJobs = getAvailableJobs(player);
  if (availableJobs.length === 0) return null;

  // Pick 3-5 random jobs to offer
  const numOffers = Math.min(availableJobs.length, 3 + Math.floor(Math.random() * 3));
  const shuffled = [...availableJobs].sort(() => Math.random() - 0.5);
  const jobOffers = shuffled.slice(0, numOffers);

  // Create answer options with job titles
  const answerOptions: AnswerOption[] = jobOffers.map(job =>
    createAnswerOption(job.title, job.id)
  );
  answerOptions.push(createAnswerOption('Not interested', 'decline'));

  return createQuestionEvent(
    fname,
    "You've been looking for work and some opportunities have come up! Which job would you like to apply for?",
    player,
    true,
    { answerOptions }
  );
}
