import type { SystemId } from '@/lib/rules';
import type { AbilityKey, AdvState } from './types';

/**
 * The mechanical effect a condition imposes — a declarative table, never
 * hardcoded `if`s in combat code. `deriveState` (creatureState.ts) folds these
 * into a single query the tracker and dice roller ask.
 */
/**
 * Which statistic family a PF2e value-scaled status penalty applies to. Different
 * families are independent (they target different rolls) and must never be compared
 * against each other — clumsy hits Dex-based rolls, enfeebled hits Str-based rolls, etc.
 */
export type PenaltyTarget = 'all' | 'str' | 'dex' | 'con' | 'mental';

export interface ConditionEffect {
  /** sets effective speed to 0 */
  speedZero?: boolean;
  /** this creature's attack rolls */
  attackRolls?: AdvState;
  /** attack rolls made AGAINST this creature */
  attacksAgainst?: AdvState;
  /** disadvantage on ability checks (5e) */
  abilityChecks?: boolean;
  /** per-ability save penalty (auto-fail dominates disadvantage) */
  saves?: Partial<Record<AbilityKey, 'disadvantage' | 'auto-fail'>>;
  /** cannot take actions or reactions */
  incapacitated?: boolean;
  /**
   * pf2e: a value-scaled status penalty applied to this statistic family. The
   * penalty magnitude is the condition's value; family decides which rolls it hits.
   */
  statusPenalty?: PenaltyTarget;
}

const ALL_PHYS: Partial<Record<AbilityKey, 'auto-fail'>> = { str: 'auto-fail', dex: 'auto-fail' };

/** D&D 5e condition mechanics (keys lowercased to match stored names). */
export const CONDITION_EFFECTS_5E: Record<string, ConditionEffect> = {
  blinded: { attackRolls: 'disadvantage', attacksAgainst: 'advantage' },
  frightened: { attackRolls: 'disadvantage', abilityChecks: true },
  grappled: { speedZero: true },
  incapacitated: { incapacitated: true },
  invisible: { attackRolls: 'advantage', attacksAgainst: 'disadvantage' },
  paralyzed: { incapacitated: true, speedZero: true, attacksAgainst: 'advantage', saves: ALL_PHYS },
  petrified: { incapacitated: true, speedZero: true, attacksAgainst: 'advantage', saves: ALL_PHYS },
  poisoned: { attackRolls: 'disadvantage', abilityChecks: true },
  prone: { attackRolls: 'disadvantage', attacksAgainst: 'advantage' },
  restrained: { speedZero: true, attackRolls: 'disadvantage', attacksAgainst: 'advantage', saves: { dex: 'disadvantage' } },
  stunned: { incapacitated: true, speedZero: true, attacksAgainst: 'advantage', saves: ALL_PHYS },
  unconscious: { incapacitated: true, speedZero: true, attacksAgainst: 'advantage', saves: ALL_PHYS },
};

/**
 * Pathfinder 2e condition mechanics. PF2e uses flat numeric penalties rather
 * than advantage/disadvantage; valued conditions (frightened N, clumsy N, …)
 * contribute a status penalty aggregated by `deriveState`.
 */
export const CONDITION_EFFECTS_PF2E: Record<string, ConditionEffect> = {
  blinded: { attacksAgainst: 'advantage' },
  // Each valued condition penalises a DIFFERENT statistic family (never compared):
  clumsy: { statusPenalty: 'dex' }, // AC, Reflex, Dex attacks/skills
  drained: { statusPenalty: 'con' }, // Fortitude (also reduces HP — applied separately)
  enfeebled: { statusPenalty: 'str' }, // Str attacks/damage, Athletics
  stupefied: { statusPenalty: 'mental' }, // spell attacks/DCs, mental checks
  frightened: { statusPenalty: 'all' }, // every check and DC; decays 1/turn
  sickened: { statusPenalty: 'all' }, // every check and DC
  dazzled: { attacksAgainst: 'advantage' },
  // fatigued (flat -1 AC/saves) and slowed (action loss) are NOT value-scaled — see deriveState.
  fatigued: {},
  slowed: {},
  grabbed: { speedZero: true, attacksAgainst: 'advantage' },
  immobilized: { speedZero: true },
  paralyzed: { incapacitated: true, speedZero: true, attacksAgainst: 'advantage' },
  petrified: { incapacitated: true, speedZero: true },
  prone: { attacksAgainst: 'advantage' },
  restrained: { speedZero: true, incapacitated: false, attacksAgainst: 'advantage' },
  stunned: { incapacitated: true },
  unconscious: { incapacitated: true, speedZero: true, attacksAgainst: 'advantage' },
  'off-guard': { attacksAgainst: 'advantage' },
};

export function conditionEffects(system: SystemId): Record<string, ConditionEffect> {
  return system === 'pf2e' ? CONDITION_EFFECTS_PF2E : CONDITION_EFFECTS_5E;
}
