/**
 * T010d — NPC-death grief + inheritance + memorial.
 *
 * When a relationship NPC dies in the GameEngine path:
 *  - the player takes a happiness hit scaled to their affinity (grief = love),
 *  - a high-affinity family member leaves an affinity-scaled inheritance,
 *  - a memorial life event / message is logged.
 * Player-death handleDeath is NOT involved.
 */
import { describe, it, expect } from 'vitest';
import { Person } from '../../src/models/Person.js';
import { Player } from '../../src/models/Player.js';
import {
  getGameEngine,
  computeNpcInheritance,
  GRIEF_HAPPINESS_MAX,
} from '../../src/game/engine/GameEngine.js';

const engine = getGameEngine();

function makePlayer(): Player {
  const player = new Player({
    userId: 'p1',
    character: new Person({
      id: 'me',
      firstname: 'You',
      lastname: 'Me',
      sex: 'Male',
      ageYears: 40,
      ageDays: 40 * 365,
      happiness: 80,
      money: 1000,
      status: 'alive',
    } as never),
    status: 'playing',
    controller: 'active',
    r: [],
  });
  return player;
}

describe('computeNpcInheritance', () => {
  it('returns half the estate plus an affinity bonus', () => {
    // affinity 100 => 1.2x of 50% of estate; estate 1000 -> 500 * 1.2 = 600
    expect(computeNpcInheritance(1000, 100)).toBe(600);
    // affinity 0 => no bonus -> 500
    expect(computeNpcInheritance(1000, 0)).toBe(500);
    // negative net worth -> 0
    expect(computeNpcInheritance(-500, 100)).toBe(0);
  });
});

describe('handleNpcDeath (grief / inheritance / memorial)', () => {
  it('applies grief proportional to affinity (high-affinity loss hurts more)', () => {
    const player = makePlayer();
    const lovedOne = new Person({
      id: 'mom',
      firstname: 'Mary',
      lastname: 'Me',
      sex: 'Female',
      ageYears: 70,
      affinity: 100,
      familyLevel: 1,
      relationships: ['mother', 'family'],
      money: 0,
    } as never);
    player.r.push(lovedOne);
    (lovedOne as { title?: string }).title = 'Mother';

    const startHappiness = player.c.happiness;
    const event = engine.handleNpcDeath(player, lovedOne);

    expect(lovedOne.status).toBe('dead');
    expect(player.c.happiness).toBe(startHappiness - GRIEF_HAPPINESS_MAX);
    expect(player.c.mood).toBe('Depressed');
    expect(event?.message).toContain('has died');
    expect(player.messageQueue.some((m) => m.includes('has died'))).toBe(true);
    // Player death untouched.
    expect(player.c.status).toBe('alive');
    expect(player.controller).toBe('active');
  });

  it('barely grieves a low-affinity acquaintance', () => {
    const player = makePlayer();
    const acquaintance = new Person({
      id: 'acq',
      firstname: 'Stranger',
      lastname: 'X',
      sex: 'Male',
      ageYears: 80,
      affinity: 5,
      relationships: ['acquaintance'],
    } as never);
    player.r.push(acquaintance);

    const startHappiness = player.c.happiness;
    engine.handleNpcDeath(player, acquaintance);

    // affinity 5 -> happiness hit round(5/100 * 40) = 2
    expect(player.c.happiness).toBe(startHappiness - 2);
    expect(player.c.mood).not.toBe('Depressed');
  });

  it('transfers an affinity-scaled inheritance from high-affinity family', () => {
    const player = makePlayer();
    const richDad = new Person({
      id: 'dad',
      firstname: 'Frank',
      lastname: 'Me',
      sex: 'Male',
      ageYears: 75,
      affinity: 90,
      familyLevel: 1,
      relationships: ['father', 'family'],
      money: 10000,
    } as never);
    (richDad as { title?: string }).title = 'Father';
    player.r.push(richDad);

    const startMoney = player.c.money;
    const expected = computeNpcInheritance(10000, 90);
    const event = engine.handleNpcDeath(player, richDad);

    expect(expected).toBeGreaterThan(0);
    expect(player.c.money).toBe(startMoney + expected);
    expect(event?.message).toContain('inheritance');
  });

  it('does NOT pay inheritance for a low-affinity family member', () => {
    const player = makePlayer();
    const estrangedFamily = new Person({
      id: 'unc',
      firstname: 'Cold',
      lastname: 'Me',
      sex: 'Male',
      ageYears: 75,
      affinity: 10,
      familyLevel: 1,
      relationships: ['father', 'family'],
      money: 10000,
    } as never);
    player.r.push(estrangedFamily);

    const startMoney = player.c.money;
    engine.handleNpcDeath(player, estrangedFamily);

    expect(player.c.money).toBe(startMoney);
  });

  it('does NOT pay inheritance for a high-affinity non-family friend', () => {
    const player = makePlayer();
    const richFriend = new Person({
      id: 'fr',
      firstname: 'Buddy',
      lastname: 'Pal',
      sex: 'Male',
      ageYears: 75,
      affinity: 95,
      familyLevel: 0,
      relationships: ['friend'],
      money: 10000,
    } as never);
    player.r.push(richFriend);

    const startMoney = player.c.money;
    engine.handleNpcDeath(player, richFriend);

    expect(player.c.money).toBe(startMoney);
  });
});
