/**
 * Friendship V2 player actions. `hangOut` is the direct-invest lever: the
 * player spends energy to actively grow a SPECIFIC friendship instead of
 * waiting on ambient beats. Pairs with the iOS "Hang Out" button on the NPC
 * profile (agent-native parity: one WS command, both UIs).
 */
import type { PlayerSession } from '../game/PlayerSession.js';
import { isFriendNpc, recordFriendInteraction } from '../services/relationships/friendship_manager.js';
import { clamp } from '../utils/statUtils.js';

export const HANGOUT_ENERGY_COST = 15;
export const HANGOUT_AFFINITY_GAIN = 6;
export const HANGOUT_HAPPINESS_GAIN = 3;
export const HANGOUT_COOLDOWN_DAYS = 3;
// Mirrors the iOS gate (button shown at affinity >= 30, the friend-tier
// promote threshold) so a modified client can't spam-befriend acquaintances.
export const HANGOUT_MIN_AFFINITY = 30;

export async function handleHangOut(payload: unknown, session: PlayerSession): Promise<void> {
  const personId =
    payload && typeof payload === 'object'
      ? String((payload as { personId?: unknown }).personId ?? '')
      : '';
  if (!personId) {
    session.send({ type: 'error', message: 'hangOut requires a personId.' });
    return;
  }

  const player = session.player;
  const person = (player.r ?? []).find((p) => p.id === personId);
  if (!person) {
    session.send({ type: 'error', message: 'That person is not in your life.' });
    return;
  }
  if (!isFriendNpc(person)) {
    session.send({ type: 'error', message: 'You can only hang out with friends.' });
    return;
  }
  if ((person.affinity ?? 50) < HANGOUT_MIN_AFFINITY) {
    session.send({
      type: 'error',
      message: `You and ${person.firstname} aren't close enough to hang out yet.`,
    });
    return;
  }

  const today = Math.floor(player.c.ageDays ?? 0);
  if (
    person.lastHangOutDay !== undefined &&
    today - person.lastHangOutDay < HANGOUT_COOLDOWN_DAYS
  ) {
    session.send({
      type: 'error',
      message: `You just spent time with ${person.firstname}. Give it a few days.`,
    });
    return;
  }

  if ((player.c.energy ?? 0) < HANGOUT_ENERGY_COST) {
    session.send({ type: 'error', message: 'Too tired to hang out right now.' });
    return;
  }

  player.c.energy = clamp((player.c.energy ?? 0) - HANGOUT_ENERGY_COST, 0, 100);
  player.c.happiness = clamp((player.c.happiness ?? 50) + HANGOUT_HAPPINESS_GAIN, 0, 100);
  person.affinity = clamp((person.affinity ?? 50) + HANGOUT_AFFINITY_GAIN, -100, 100);
  recordFriendInteraction(player, person);
  person.lastHangOutDay = today;

  await session.savePlayer();
  session.sendPlayerObject();
  session.send({
    type: 'hangOutResult',
    success: true,
    personId,
    name: person.firstname,
    affinity: person.affinity,
    friendshipTier: person.friendshipTier ?? null,
  });
}
