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.
 */
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 numeric status penalty scaling with the condition's value */
  statusPenalty?: boolean;
}

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' },
  clumsy: { statusPenalty: true },
  enfeebled: { statusPenalty: true },
  frightened: { statusPenalty: true },
  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' },
  sickened: { statusPenalty: true },
  slowed: { statusPenalty: true },
  stunned: { incapacitated: true },
  stupefied: { statusPenalty: 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;
}
