import type { Character } from '@/lib/schemas/character';
import type { RestOption } from './types';

/**
 * Compute the character changes a rest produces. Pure — returns a partial patch
 * the caller persists. Correctly distinguishes short vs long recovery, refreshes
 * spell slots / pact magic / resources by their recovery tag, and resets 5e death
 * saves + steps down exhaustion on a full rest. (The old app's short rest just
 * full-healed, ignoring all of this.)
 */
export function applyRest(c: Character, opt: RestOption): Partial<Character> {
  const patch: Partial<Character> = {};

  if (opt.restoresHp) {
    patch.hp = { ...c.hp, current: c.hp.max };
  }

  // Resources refresh when their recovery tag is covered by this rest.
  patch.resources = c.resources.map((r) =>
    opt.recovers.includes(r.recovery) ? { ...r, current: r.max } : r,
  );

  if (opt.restoresSlots || opt.restoresPact) {
    patch.spellcasting = {
      ...c.spellcasting,
      slots: opt.restoresSlots
        ? c.spellcasting.slots.map((s) => ({ ...s, current: s.max }))
        : c.spellcasting.slots,
      ...(c.spellcasting.pact
        ? {
            pact: opt.restoresPact
              ? { ...c.spellcasting.pact, current: c.spellcasting.pact.max }
              : c.spellcasting.pact,
          }
        : {}),
    };
  }

  const exhaustion =
    opt.reduceExhaustion && c.defenses.exhaustion > 0
      ? c.defenses.exhaustion - 1
      : c.defenses.exhaustion;

  if (opt.restoresHp || exhaustion !== c.defenses.exhaustion) {
    patch.defenses = {
      ...c.defenses,
      exhaustion,
      // recovering from 0 HP clears death saves (5e)
      ...(opt.restoresHp ? { deathSaves: { successes: 0, failures: 0 } } : {}),
    };
  }

  return patch;
}
