/**
 * Family Activity Events
 * Family bonding and interaction activities (ages 5-100)
 */

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

/**
 * Get all family members from player relationships
 */
function getAllFamily(player: Player): Person[] {
  return (player.r ?? []).filter((person: Person) => {
    const relationships = person.relationships ?? [];
    return (
      relationships.includes('mother') ||
      relationships.includes('father') ||
      relationships.includes('sibling') ||
      relationships.includes('spouse') ||
      relationships.includes('child')
    );
  });
}

/**
 * Get parent from player relationships
 */
function getParent(player: Player): Person | null {
  const mother = (player.r ?? []).find((p: Person) =>
    (p.relationships ?? []).includes('mother')
  );
  const father = (player.r ?? []).find((p: Person) =>
    (p.relationships ?? []).includes('father')
  );
  return mother ?? father ?? null;
}

/**
 * Get younger siblings from player relationships
 */
function getYoungerSiblings(player: Player): Person[] {
  return (player.r ?? []).filter(
    (person: Person) =>
      (person.relationships ?? []).includes('sibling') &&
      person.ageYears < player.c.ageYears
  );
}

/**
 * Family Game Night Event
 */
export class FamilyGameNightEvent extends BaseEvent {
  readonly id = 'familyGameNight';

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

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

  getQuestion(): string {
    return 'Your family suggests starting a regular game night tradition. How often?';
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, every week!' },
      { option: 'Once a month' },
      { option: 'Too busy' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const family = getAllFamily(player);

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

      // Increase affinity with all family members
      for (const member of family) {
        member.affinity = Math.min(100, (member.affinity ?? 50) + 20);
      }

      return {
        type: 'messageEvent',
        message:
          "You've started a weekly family game night tradition! Every Friday evening, the family gathers for board games and fun.",
      };
    } else if (selectedOption === 1) {
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);
      c.social = Math.min(100, (c.social ?? 50) + 5);

      // Increase affinity with all family members
      for (const member of family) {
        member.affinity = Math.min(100, (member.affinity ?? 50) + 10);
      }

      return {
        type: 'messageEvent',
        message:
          "You've decided to have family game night once a month. It's a nice tradition!",
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 10);

      // Decrease affinity with all family members
      for (const member of family) {
        member.affinity = Math.max(0, (member.affinity ?? 50) - 5);
      }

      return {
        type: 'messageEvent',
        message:
          "You're too busy for family game night. Your family seems disappointed.",
      };
    }
  }
}

/**
 * Family Vacation Event
 */
export class FamilyVacationEvent extends BaseEvent {
  readonly id = 'familyVacation';

  getConfig(): EventConfig {
    return {
      minAge: 8,
      maxAge: 65,
      baseChance: 0.00125,
      triggerType: 'random',
    };
  }

  checkConditions(player: Player): boolean {
    const c = player.c;
    const family = getAllFamily(player);
    return (
      !player.askedQuestions.has(this.id) &&
      c.ageYears >= 8 &&
      c.ageYears <= 65 &&
      family.length > 0 &&
      (c.money ?? 0) >= 500
    );
  }

  getQuestion(): string {
    return 'Your family wants to plan a vacation together. What sounds good?';
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, big trip!', moneyCost: 2000 },
      { option: 'Weekend getaway', moneyCost: 500 },
      { option: 'Staycation at home' },
      { option: "Can't afford it" },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const family = getAllFamily(player);

    if (selectedOption === 0) {
      if ((c.money ?? 0) < 2000) {
        return {
          type: 'messageEvent',
          message: "You don't have enough money for a big trip right now.",
        };
      }
      c.money = (c.money ?? 0) - 2000;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 30);

      // Increase affinity with all family members
      for (const member of family) {
        member.affinity = Math.min(100, (member.affinity ?? 50) + 20);
      }

      return {
        type: 'messageEvent',
        message:
          "You've planned an amazing family vacation! Everyone is excited about the trip.",
      };
    } else if (selectedOption === 1) {
      c.money = (c.money ?? 0) - 500;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 20);

      // Increase affinity with all family members
      for (const member of family) {
        member.affinity = Math.min(100, (member.affinity ?? 50) + 15);
      }

      return {
        type: 'messageEvent',
        message:
          'A weekend getaway with the family sounds perfect! You\'ve booked it for a few weeks from now.',
      };
    } else if (selectedOption === 2) {
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);

      // Increase affinity with all family members
      for (const member of family) {
        member.affinity = Math.min(100, (member.affinity ?? 50) + 10);
      }

      return {
        type: 'messageEvent',
        message:
          "You've planned a staycation at home. It'll be relaxing and the family will enjoy quality time together.",
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 15);
      return {
        type: 'messageEvent',
        message: "You can't afford a vacation right now. Maybe next year.",
      };
    }
  }
}

/**
 * Teach Sibling Skill Event
 */
export class TeachSiblingSkillEvent extends BaseEvent {
  readonly id = 'teachSiblingSkill';

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

  checkConditions(player: Player): boolean {
    const c = player.c;
    const youngerSiblings = getYoungerSiblings(player);
    return (
      !player.askedQuestions.has(this.id) &&
      c.ageYears >= 10 &&
      c.ageYears <= 30 &&
      youngerSiblings.length > 0 &&
      c.energy >= 10
    );
  }

  getQuestion(player?: Player): string {
    const youngerSiblings = player ? getYoungerSiblings(player) : [];
    if (youngerSiblings.length > 0) {
      const sibling = youngerSiblings[Math.floor(Math.random() * youngerSiblings.length)];
      return `Your younger sibling ${sibling.firstname} wants you to teach them something. Help?`;
    }
    return 'Your younger sibling wants you to teach them something. Help?';
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, spend time teaching!', energyCost: 10 },
      { option: 'Quick lesson only' },
      { option: 'Too busy' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const youngerSiblings = getYoungerSiblings(player);
    const sibling =
      youngerSiblings.length > 0
        ? youngerSiblings[Math.floor(Math.random() * youngerSiblings.length)]
        : null;

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

      if (sibling) {
        sibling.affinity = Math.min(100, (sibling.affinity ?? 50) + 25);
        return {
          type: 'messageEvent',
          message: `You spent quality time teaching ${sibling.firstname}. They really appreciated it and learned a lot!`,
        };
      }

      return {
        type: 'messageEvent',
        message:
          'You spent quality time teaching your sibling. They really appreciated it and learned a lot!',
      };
    } else if (selectedOption === 1) {
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
      c.social = Math.min(100, (c.social ?? 50) + 5);

      if (sibling) {
        sibling.affinity = Math.min(100, (sibling.affinity ?? 50) + 10);
        return {
          type: 'messageEvent',
          message: `You gave ${sibling.firstname} a quick lesson. They learned something new!`,
        };
      }

      return {
        type: 'messageEvent',
        message: 'You gave a quick lesson. Your sibling learned something new!',
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);

      if (sibling) {
        sibling.affinity = Math.max(0, (sibling.affinity ?? 50) - 15);
        return {
          type: 'messageEvent',
          message: `${sibling.firstname} seems disappointed that you're too busy to help them.`,
        };
      }

      return {
        type: 'messageEvent',
        message:
          'Your sibling seems disappointed that you\'re too busy to help them.',
      };
    }
  }
}

/**
 * Help Parent Project Event
 */
export class HelpParentProjectEvent extends BaseEvent {
  readonly id = 'helpParentProject';

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

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

  getQuestion(): string {
    const projects = [
      'gardening',
      'painting the house',
      'fixing the fence',
      'organizing the garage',
      'remodeling the kitchen',
    ];
    const project = projects[Math.floor(Math.random() * projects.length)];
    return `Your parent needs help with ${project}. Want to assist?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, help all day!', energyCost: 20 },
      { option: 'Help for a bit', energyCost: 10 },
      { option: 'Too busy' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const parent = getParent(player);

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

      if (parent) {
        parent.affinity = Math.min(100, (parent.affinity ?? 50) + 25);
        return {
          type: 'messageEvent',
          message:
            "You helped your parent all day with the project. They're grateful and you feel accomplished!",
        };
      }

      return {
        type: 'messageEvent',
        message:
          "You helped all day with the project. They're grateful and you feel accomplished!",
      };
    } else if (selectedOption === 1) {
      c.energy = Math.max(0, c.energy - 10);
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);
      c.social = Math.min(100, (c.social ?? 50) + 5);

      if (parent) {
        parent.affinity = Math.min(100, (parent.affinity ?? 50) + 15);
        return {
          type: 'messageEvent',
          message:
            'You helped your parent for a while. They appreciate the assistance!',
        };
      }

      return {
        type: 'messageEvent',
        message: 'You helped for a while. They appreciate the assistance!',
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 10);

      if (parent) {
        parent.affinity = Math.max(0, (parent.affinity ?? 50) - 20);
        return {
          type: 'messageEvent',
          message: "Your parent is disappointed you're too busy to help.",
        };
      }

      return {
        type: 'messageEvent',
        message: "They're disappointed you're too busy to help.",
      };
    }
  }
}

/**
 * Family Photo Event
 */
export class FamilyPhotoEvent extends BaseEvent {
  readonly id = 'familyPhoto';

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

  checkConditions(player: Player): boolean {
    const c = player.c;
    const family = getAllFamily(player);
    return (
      !player.askedQuestions.has(this.id) &&
      c.ageYears >= 5 &&
      c.ageYears <= 100 &&
      family.length > 0 &&
      (c.money ?? 0) >= 50
    );
  }

  getQuestion(): string {
    return 'Your family wants to schedule a professional photo session together. Are you in?';
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, sounds fun!', moneyCost: 50 },
      { option: 'Okay, if I have to', moneyCost: 50 },
      { option: 'Refuse' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const family = getAllFamily(player);

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

      // Increase affinity with all family members
      for (const member of family) {
        member.affinity = Math.min(100, (member.affinity ?? 50) + 15);
      }

      return {
        type: 'messageEvent',
        message:
          "You're excited for the family photo session! It's scheduled for a few weeks from now. Should be fun!",
      };
    } else if (selectedOption === 1) {
      c.money = (c.money ?? 0) - 50;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 5);

      // Small increase in affinity with all family members
      for (const member of family) {
        member.affinity = Math.min(100, (member.affinity ?? 50) + 5);
      }

      return {
        type: 'messageEvent',
        message:
          "You agreed to participate in the family photos. It's scheduled for a few weeks from now.",
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 10);

      // Decrease affinity with all family members
      for (const member of family) {
        member.affinity = Math.max(0, (member.affinity ?? 50) - 20);
      }

      return {
        type: 'messageEvent',
        message:
          'You refused to participate in family photos. Your family is really disappointed.',
      };
    }
  }
}

// Export all family events
export const familyEvents = [
  new FamilyGameNightEvent(),
  new FamilyVacationEvent(),
  new TeachSiblingSkillEvent(),
  new HelpParentProjectEvent(),
  new FamilyPhotoEvent(),
];
