/**
 * T010d — Parenting arc: a child's adult outcome reflects accumulated parenting
 * investment (their affinity, the running proxy for warmth + interaction). A
 * neglected child grows distant; an invested child becomes supportive.
 */
import { describe, it, expect } from 'vitest';
import { Person } from '../../src/models/Person.js';
import { Player } from '../../src/models/Player.js';
import {
  getGameEngine,
  CHILD_ADULT_AGE,
  PARENTING_SUPPORTIVE_AFFINITY,
  PARENTING_DISTANT_AFFINITY,
} from '../../src/game/engine/GameEngine.js';

const engine = getGameEngine();

function makePlayer(child: Person): Player {
  return new Player({
    userId: 'p1',
    character: new Person({
      id: 'me',
      firstname: 'Parent',
      lastname: 'Me',
      sex: 'Female',
      ageYears: 45,
      status: 'alive',
    } as never),
    status: 'playing',
    controller: 'active',
    r: [child],
  });
}

function makeChild(affinity: number, ageYears: number): Person {
  const c = new Person({
    id: 'kid',
    firstname: 'Sam',
    lastname: 'Me',
    sex: 'Male',
    ageYears,
    ageDays: ageYears * 365,
    affinity,
    familyLevel: 1,
    relationships: ['child', 'family'],
  } as never);
  (c as { title?: string }).title = 'Son';
  return c;
}

describe('applyParentingArc', () => {
  it('accumulates parenting investment while the child is a minor', () => {
    const child = makeChild(80, 10);
    const player = makePlayer(child);

    const before = child.parentingInvestment ?? 0;
    const event = engine.applyParentingArc(player, child);

    expect(event).toBeNull(); // not matured yet
    expect((child.parentingInvestment ?? 0)).toBeGreaterThan(before);
    expect(child.childMaturedOutcome).toBeUndefined();
  });

  it('an invested (high-affinity) child becomes a supportive adult', () => {
    const child = makeChild(PARENTING_SUPPORTIVE_AFFINITY + 10, CHILD_ADULT_AGE);
    const player = makePlayer(child);

    const event = engine.applyParentingArc(player, child);

    expect(child.childMaturedOutcome).toBe('supportive');
    expect((child as { contactFrequency?: string }).contactFrequency).toBe('frequent');
    expect(child.affinity).toBeGreaterThan(PARENTING_SUPPORTIVE_AFFINITY);
    expect(event?.positive).toBe(true);
    expect(event?.message).toContain('supportive');
  });

  it('a neglected (low-affinity) child becomes a distant adult', () => {
    const child = makeChild(PARENTING_DISTANT_AFFINITY - 5, CHILD_ADULT_AGE);
    const player = makePlayer(child);

    const startAffinity = child.affinity;
    const event = engine.applyParentingArc(player, child);

    expect(child.childMaturedOutcome).toBe('distant');
    expect((child as { contactFrequency?: string }).contactFrequency).toBe('rare');
    expect(child.affinity).toBeLessThan(startAffinity);
    expect(event?.positive).toBe(false);
    expect(event?.message.toLowerCase()).toContain('distant');
  });

  it('is idempotent — a matured child resolves only once', () => {
    const child = makeChild(PARENTING_SUPPORTIVE_AFFINITY + 10, CHILD_ADULT_AGE);
    const player = makePlayer(child);

    const first = engine.applyParentingArc(player, child);
    const affinityAfterFirst = child.affinity;
    const second = engine.applyParentingArc(player, child);

    expect(first).not.toBeNull();
    expect(second).toBeNull();
    expect(child.affinity).toBe(affinityAfterFirst); // no double bonus
  });

  it('ignores non-child relationships', () => {
    const friend = new Person({
      id: 'f',
      firstname: 'Pat',
      lastname: 'Q',
      sex: 'Male',
      ageYears: 30,
      affinity: 90,
      relationships: ['friend'],
    } as never);
    const player = makePlayer(friend);
    expect(engine.applyParentingArc(player, friend)).toBeNull();
  });
});
