/**
 * Social Activity Events
 * Activity events focused on social engagement and community (ages 8-100)
 */

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

/**
 * Join Club Event
 */
export class JoinClubEvent extends BaseEvent {
  readonly id = 'joinClub';

  private getClubType(): { name: string; description: string } {
    const clubTypes = [
      { name: 'Photography Club', description: 'Share your passion for photography' },
      { name: 'Hiking Club', description: 'Explore nature trails with others' },
      { name: 'Cooking Club', description: 'Learn new recipes together' },
      { name: 'Art Club', description: 'Express creativity through art' },
      { name: 'Music Club', description: 'Share your love of music' },
      { name: 'Film Club', description: 'Watch and discuss movies' },
      { name: 'Tech Club', description: 'Learn about technology together' },
      { name: 'Gardening Club', description: 'Grow plants and share gardening tips' },
    ];
    return clubTypes[Math.floor(Math.random() * clubTypes.length)];
  }

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

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

  getQuestion(): string {
    const club = this.getClubType();
    return `There's a ${club.name} in your area. Join?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, become a member!' },
      { option: 'Attend as guest first' },
      { option: 'Not interested' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const club = this.getClubType();

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

      // Build relationships with others
      for (const person of player.r ?? []) {
        if (person.affinity !== undefined) {
          person.affinity = Math.min(100, person.affinity + 3);
        }
      }

      return {
        type: 'messageEvent',
        message: `You joined ${club.name}! Meetings are weekly and you're already making new connections.`,
      };
    } else if (selectedOption === 1) {
      c.social = Math.min(100, (c.social ?? 50) + 10);
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);

      return {
        type: 'messageEvent',
        message: `You attended ${club.name} as a guest and enjoyed it!`,
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
      return {
        type: 'messageEvent',
        message: 'You decided not to join the club.',
      };
    }
  }
}

/**
 * Volunteer Work Event
 */
export class VolunteerWorkEvent extends BaseEvent {
  readonly id = 'volunteerWork';

  private getVolunteerType(): { name: string; description: string } {
    const volunteerTypes = [
      { name: 'Animal Shelter', description: 'Help care for animals in need' },
      { name: 'Food Bank', description: 'Sort and distribute food to those in need' },
      { name: 'Elderly Care', description: 'Visit and assist elderly community members' },
      { name: 'Environmental Cleanup', description: 'Help clean parks and public spaces' },
      { name: 'Youth Mentoring', description: 'Guide and inspire young people' },
      { name: 'Homeless Outreach', description: 'Provide support to homeless individuals' },
      { name: 'Library Assistance', description: 'Help organize and run library programs' },
    ];
    return volunteerTypes[Math.floor(Math.random() * volunteerTypes.length)];
  }

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

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

  getQuestion(): string {
    const volunteer = this.getVolunteerType();
    return `A local ${volunteer.name} needs volunteers. Help out?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, volunteer regularly!' },
      { option: 'Volunteer occasionally' },
      { option: 'Donate money instead', moneyCost: 50 },
      { option: 'Not right now' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const volunteer = this.getVolunteerType();

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

      // Build relationships with other volunteers
      for (const person of player.r ?? []) {
        if (person.affinity !== undefined) {
          person.affinity = Math.min(100, person.affinity + 4);
        }
      }

      return {
        type: 'messageEvent',
        message: `You signed up to volunteer at ${volunteer.name} regularly! Your work helps the community.`,
      };
    } else if (selectedOption === 1) {
      c.social = Math.min(100, (c.social ?? 50) + 15);
      c.happiness = Math.min(100, (c.happiness ?? 50) + 20);
      c.prestige = (c.prestige ?? 0) + 2;

      return {
        type: 'messageEvent',
        message: `You'll volunteer at ${volunteer.name} when you have time. Every bit helps!`,
      };
    } else if (selectedOption === 2) {
      if ((c.money ?? 0) < 50) {
        return {
          type: 'messageEvent',
          message: "You don't have enough money to donate right now.",
        };
      }
      c.money = (c.money ?? 0) - 50;
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);
      c.prestige = (c.prestige ?? 0) + 3;

      return {
        type: 'messageEvent',
        message: `You made a $50 donation to ${volunteer.name} to support the cause!`,
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 10);
      return {
        type: 'messageEvent',
        message: 'You decided not to volunteer right now.',
      };
    }
  }
}

/**
 * Book Club Event
 */
export class BookClubEvent extends BaseEvent {
  readonly id = 'bookClub';

  private getBookGenre(): { name: string; description: string } {
    const bookGenres = [
      { name: 'Mystery Book Club', description: 'Solve mysteries together through reading' },
      { name: 'Sci-Fi Book Club', description: 'Explore futuristic worlds and ideas' },
      { name: 'Romance Book Club', description: 'Discuss love stories and relationships' },
      { name: 'Classic Literature Club', description: 'Dive into timeless literary works' },
      { name: 'Biography Book Club', description: "Learn from real people's lives" },
      { name: 'Fantasy Book Club', description: 'Escape to magical worlds together' },
    ];
    return bookGenres[Math.floor(Math.random() * bookGenres.length)];
  }

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

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

  getQuestion(): string {
    const genre = this.getBookGenre();
    return `Friends are starting a ${genre.name}. Join them?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, sounds fun!' },
      { option: 'Read books but skip meetings' },
      { option: 'Not interested' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const genre = this.getBookGenre();

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

      // Build relationships with book club members
      for (const person of player.r ?? []) {
        if (person.affinity !== undefined) {
          person.affinity = Math.min(100, person.affinity + 5);
        }
      }

      return {
        type: 'messageEvent',
        message: `You joined ${genre.name}! Time to start reading and enjoy the discussions!`,
      };
    } else if (selectedOption === 1) {
      c.intelligence = Math.min(100, (c.intelligence ?? 50) + 10);
      c.happiness = Math.min(100, (c.happiness ?? 50) + 5);

      return {
        type: 'messageEvent',
        message: "You'll read the books but skip the social meetings.",
      };
    } else {
      c.social = Math.max(0, (c.social ?? 50) - 10);
      return {
        type: 'messageEvent',
        message: 'You decided not to join the book club.',
      };
    }
  }
}

/**
 * Gaming Group Event
 */
export class GamingGroupEvent extends BaseEvent {
  readonly id = 'gamingGroup';

  private getGamingType(): { name: string; description: string } {
    const gamingTypes = [
      { name: 'Board Game Night', description: 'Play board games with friends' },
      { name: 'Video Game Night', description: 'Team up for multiplayer gaming' },
      { name: 'Tabletop RPG Group', description: 'Create epic adventures together' },
      { name: 'Card Game Night', description: 'Master strategy card games' },
      { name: 'Retro Gaming Club', description: 'Relive classic video games' },
      { name: 'Party Game Night', description: 'Fun social party games' },
    ];
    return gamingTypes[Math.floor(Math.random() * gamingTypes.length)];
  }

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

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

  getQuestion(): string {
    const gaming = this.getGamingType();
    return `Friends invite you to a regular ${gaming.name}. Join?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, weekly gaming!' },
      { option: 'Join occasionally' },
      { option: 'Not my thing' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const gaming = this.getGamingType();

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

      // Build relationships with gaming buddies
      for (const person of player.r ?? []) {
        if (person.affinity !== undefined) {
          person.affinity = Math.min(100, person.affinity + 6);
        }
      }

      return {
        type: 'messageEvent',
        message: `You joined ${gaming.name}! See you at the next session. Have fun!`,
      };
    } else if (selectedOption === 1) {
      c.social = Math.min(100, (c.social ?? 50) + 15);
      c.happiness = Math.min(100, (c.happiness ?? 50) + 15);
      c.stress = Math.max(0, (c.stress ?? 0) - 5);

      return {
        type: 'messageEvent',
        message: `You'll join ${gaming.name} when you can make it!`,
      };
    } else {
      c.social = Math.max(0, (c.social ?? 50) - 10);
      return {
        type: 'messageEvent',
        message: "You decided gaming nights aren't for you.",
      };
    }
  }
}

/**
 * Community Event
 */
export class CommunityEventEvent extends BaseEvent {
  readonly id = 'communityEvent';

  private getEventType(): string {
    const eventTypes = [
      'Neighborhood Block Party',
      'Community Festival',
      'Farmers Market',
      'Charity Fundraiser',
      'Local Art Fair',
      'Music in the Park',
      'Community Cleanup Day',
      'Holiday Celebration',
      'Sports Tournament',
      'Cultural Festival',
    ];
    return eventTypes[Math.floor(Math.random() * eventTypes.length)];
  }

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

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

  getQuestion(): string {
    const eventName = this.getEventType();
    return `There's a ${eventName} this weekend. Attend?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, participate actively!', energyCost: 15 },
      { option: 'Just attend casually' },
      { option: 'Help organize it!', energyCost: 30, diamondCost: 10 },
      { option: 'Skip it' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const eventName = this.getEventType();

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

      // Build relationships with community members
      const numPeopleMet = Math.min(3, (player.r ?? []).length);
      for (let i = 0; i < numPeopleMet; i++) {
        const person = player.r?.[i];
        if (person?.affinity !== undefined) {
          person.affinity = Math.min(100, person.affinity + Math.floor(Math.random() * 6) + 3);
          person.familiarity = (person.familiarity ?? 0) + Math.floor(Math.random() * 6) + 5;
        }
      }

      return {
        type: 'messageEvent',
        message: `You actively participated in the ${eventName} and had a great time!`,
      };
    } else if (selectedOption === 1) {
      c.social = Math.min(100, (c.social ?? 50) + 10);
      c.happiness = Math.min(100, (c.happiness ?? 50) + 10);

      return {
        type: 'messageEvent',
        message: `You casually attended the ${eventName}.`,
      };
    } else if (selectedOption === 2) {
      c.social = Math.min(100, (c.social ?? 50) + 30);
      c.happiness = Math.min(100, (c.happiness ?? 50) + 25);
      c.energy = Math.max(0, c.energy - 30);
      c.prestige = (c.prestige ?? 0) + 8;

      // Higher chance of meeting and bonding with more people
      const numPeopleMet = Math.min(5, (player.r ?? []).length);
      for (let i = 0; i < numPeopleMet; i++) {
        const person = player.r?.[i];
        if (person?.affinity !== undefined) {
          person.affinity = Math.min(100, person.affinity + Math.floor(Math.random() * 8) + 5);
          person.familiarity = (person.familiarity ?? 0) + Math.floor(Math.random() * 8) + 8;
        }
      }

      // Small chance for bonus reward
      if (Math.random() < 0.3) {
        c.diamonds = (c.diamonds ?? 0) + 5;
        return {
          type: 'messageEvent',
          message: `You helped organize the ${eventName}! Everyone appreciated your hard work. The community recognized your leadership and gave you a small reward!`,
        };
      }

      return {
        type: 'messageEvent',
        message: `You helped organize the ${eventName}! Everyone appreciated your hard work.`,
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
      return {
        type: 'messageEvent',
        message: `You decided to skip the ${eventName}.`,
      };
    }
  }
}

/**
 * Networking Event
 */
export class NetworkingEvent extends BaseEvent {
  readonly id = 'networkingEvent';

  private getEventType(): { name: string; description: string } {
    const eventTypes = [
      { name: 'Industry Networking Mixer', description: 'Connect with professionals in your field' },
      { name: 'Business Breakfast', description: 'Morning networking over coffee and pastries' },
      { name: 'Professional Happy Hour', description: 'Casual after-work networking event' },
      { name: 'Career Fair', description: 'Meet potential employers and recruiters' },
      { name: 'Alumni Networking Event', description: 'Reconnect with former classmates' },
      { name: 'Entrepreneur Meetup', description: 'Network with startup founders and investors' },
      { name: 'Tech Meetup', description: 'Connect with other tech professionals' },
      { name: 'Creative Professionals Gathering', description: 'Meet artists, designers, and creatives' },
    ];
    return eventTypes[Math.floor(Math.random() * eventTypes.length)];
  }

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

  checkConditions(player: Player): boolean {
    const c = player.c;
    return (
      !player.askedQuestions.has(this.id) &&
      c.ageYears >= 18 &&
      c.ageYears <= 65 &&
      (c.occupation === 'work' || c.occupation === 'student')
    );
  }

  getQuestion(): string {
    const event = this.getEventType();
    return `There's a ${event.name} happening nearby. Attend?`;
  }

  getAnswerOptions(): AnswerOption[] {
    return [
      { option: 'Yes, network actively!', energyCost: 15 },
      { option: 'Attend but stay low-key' },
      { option: 'Bring business cards', moneyCost: 20, energyCost: 20 },
      { option: 'Not interested' },
    ];
  }

  processAnswer(player: Player, selectedOption: number): EventResult {
    const c = player.c;
    const event = this.getEventType();

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

      // Build relationships with professionals
      const numContacts = Math.min(3, (player.r ?? []).length);
      for (let i = 0; i < numContacts; i++) {
        const person = player.r?.[i];
        if (person?.affinity !== undefined) {
          person.affinity = Math.min(100, person.affinity + Math.floor(Math.random() * 5) + 3);
          person.familiarity = (person.familiarity ?? 0) + Math.floor(Math.random() * 8) + 5;
        }
      }

      // Chance to boost career
      if (c.occupation === 'work' && Math.random() < 0.25) {
        c.money = (c.money ?? 0) + 100;
        return {
          type: 'messageEvent',
          message: `You attended the ${event.name} and made some great connections! One of the contacts led to a small freelance opportunity earning you $100.`,
        };
      }

      return {
        type: 'messageEvent',
        message: `You attended the ${event.name} and actively networked! You exchanged contact info with several interesting professionals and expanded your network.`,
      };
    } else if (selectedOption === 1) {
      c.social = Math.min(100, (c.social ?? 50) + 10);
      c.happiness = Math.min(100, (c.happiness ?? 50) + 5);

      return {
        type: 'messageEvent',
        message: `You attended the ${event.name} but stayed mostly in the background. You observed and learned, making a few casual connections.`,
      };
    } else if (selectedOption === 2) {
      c.money = (c.money ?? 0) - 20;
      c.energy = Math.max(0, c.energy - 20);
      c.social = Math.min(100, (c.social ?? 50) + 35);
      c.happiness = Math.min(100, (c.happiness ?? 50) + 20);
      c.prestige = (c.prestige ?? 0) + 10;

      // Build more relationships with professional approach
      const numContacts = Math.min(5, (player.r ?? []).length);
      for (let i = 0; i < numContacts; i++) {
        const person = player.r?.[i];
        if (person?.affinity !== undefined) {
          person.affinity = Math.min(100, person.affinity + Math.floor(Math.random() * 8) + 5);
          person.familiarity = (person.familiarity ?? 0) + Math.floor(Math.random() * 10) + 8;
        }
      }

      // Higher chance for career opportunity
      if (c.occupation === 'work' && Math.random() < 0.4) {
        c.money = (c.money ?? 0) + 200;
        return {
          type: 'messageEvent',
          message: `You came prepared with professional business cards to the ${event.name}! Your polished approach impressed several people. A new contact reached out with a lucrative opportunity worth $200!`,
        };
      }

      return {
        type: 'messageEvent',
        message: `You came prepared with professional business cards to the ${event.name}! Your polished approach impressed several people and you made meaningful professional connections.`,
      };
    } else {
      c.happiness = Math.max(0, (c.happiness ?? 50) - 5);
      return {
        type: 'messageEvent',
        message: `You decided to skip the ${event.name}. Networking can be exhausting anyway.`,
      };
    }
  }
}

// Export all social events
export const socialEvents = [
  new JoinClubEvent(),
  new VolunteerWorkEvent(),
  new BookClubEvent(),
  new GamingGroupEvent(),
  new CommunityEventEvent(),
  new NetworkingEvent(),
];
