import { SimplePerson } from './types.js';

export type EventCategory =
  | 'career'
  | 'social'
  | 'achievement'
  | 'education'
  | 'health'
  | 'finance'
  | 'random'
  | 'neutral'
  | 'negative';

export interface MessageEventData {
  id: string;
  message: string;
  type: string;
  date?: string;
  hour?: number;
  energyCost?: number;
  diamondCost?: number;
  moneyCost?: number;
  energyReward?: number;
  diamondReward?: number;
  moneyReward?: number;
  affinityChange?: number;
  characters?: SimplePerson[];
  claimed?: boolean;
  claimedAt?: string;
  category?: EventCategory;
}

export class MessageEvent {
  id: string;
  message: string;
  type: string;
  date: string;
  hour: number;
  energyCost: number;
  diamondCost: number;
  moneyCost: number;
  energyReward: number;
  diamondReward: number;
  moneyReward: number;
  affinityChange: number;
  characters?: SimplePerson[];
  claimed: boolean;
  claimedAt: string | null;
  category: EventCategory;

  constructor(data: MessageEventData) {
    this.id = data.id;
    this.message = data.message;
    this.type = data.type;
    this.date = data.date ?? new Date().toISOString().split('T')[0];
    this.hour = data.hour ?? 12;
    this.energyCost = data.energyCost ?? 0;
    this.diamondCost = data.diamondCost ?? 0;
    this.moneyCost = data.moneyCost ?? 0;
    this.energyReward = data.energyReward ?? 0;
    this.diamondReward = data.diamondReward ?? 0;
    this.moneyReward = data.moneyReward ?? 0;
    this.affinityChange = data.affinityChange ?? 0;
    this.characters = data.characters;
    this.claimed = data.claimed ?? false;
    this.claimedAt = data.claimedAt ?? null;
    this.category = data.category ?? this.inferCategory();
  }

  get isClaimable(): boolean {
    if (this.claimed) return false;
    return (
      this.moneyReward > 0 ||
      this.energyReward > 0 ||
      this.diamondReward > 0 ||
      this.affinityChange > 0
    );
  }

  get isNegative(): boolean {
    return (
      this.moneyCost > 0 ||
      this.energyCost > 0 ||
      this.diamondCost > 0 ||
      this.affinityChange < 0 ||
      this.category === 'negative'
    );
  }

  private inferCategory(): EventCategory {
    const msg = this.message.toLowerCase();
    if (msg.includes('job') || msg.includes('work') || msg.includes('career')) return 'career';
    if (msg.includes('friend') || msg.includes('relationship')) return 'social';
    if (msg.includes('achieve') || msg.includes('unlock')) return 'achievement';
    if (msg.includes('school') || msg.includes('learn') || msg.includes('study')) return 'education';
    if (msg.includes('health') || msg.includes('sick') || msg.includes('hospital')) return 'health';
    if (msg.includes('money') || msg.includes('$') || msg.includes('pay')) return 'finance';
    if (this.isNegative) return 'negative';
    return 'random';
  }

  toJSON(): MessageEventData {
    return {
      id: this.id,
      message: this.message,
      type: this.type,
      date: this.date,
      hour: this.hour,
      energyCost: this.energyCost,
      diamondCost: this.diamondCost,
      moneyCost: this.moneyCost,
      energyReward: this.energyReward,
      diamondReward: this.diamondReward,
      moneyReward: this.moneyReward,
      affinityChange: this.affinityChange,
      characters: this.characters,
      claimed: this.claimed,
      claimedAt: this.claimedAt ?? undefined,
      category: this.category,
    };
  }
}
