import type { Condition, GameState, RuntimeContext } from './types';
import { compareValue } from './utils';

function matchesMetric(value: number, comparator?: Condition['age']): boolean {
  if (!comparator) {
    return true;
  }

  return compareValue(value, comparator);
}

export function matchesCondition(
  state: GameState,
  condition?: Condition,
  context: RuntimeContext = {},
): boolean {
  if (!condition) {
    return true;
  }

  if (condition.all && !condition.all.every((entry) => matchesCondition(state, entry, context))) {
    return false;
  }

  if (condition.any && !condition.any.some((entry) => matchesCondition(state, entry, context))) {
    return false;
  }

  if (condition.not && matchesCondition(state, condition.not, context)) {
    return false;
  }

  if (condition.phaseIn && !condition.phaseIn.includes(context.phaseId ?? state.phaseId)) {
    return false;
  }

  if (condition.actionIn && !condition.actionIn.includes(context.actionId ?? '')) {
    return false;
  }

  if (condition.stat) {
    const value = state.stats[condition.stat] ?? 0;
    if (!compareValue(value, condition)) {
      return false;
    }
  }

  if (condition.resource) {
    const value = state.resources[condition.resource] ?? 0;
    if (!compareValue(value, condition)) {
      return false;
    }
  }

  if (condition.inventory) {
    const value = state.inventory[condition.inventory] ?? 0;
    if (!compareValue(value, condition)) {
      return false;
    }
  }

  if (condition.flag) {
    const value = Boolean(state.flags[condition.flag]);
    if (!compareValue(value, condition)) {
      return false;
    }
  }

  if (condition.tag) {
    const value = state.tags.includes(condition.tag);
    if (!compareValue(value, condition)) {
      return false;
    }
  }

  if (!matchesMetric(state.age, condition.age)) {
    return false;
  }

  if (!matchesMetric(state.day, condition.day)) {
    return false;
  }

  if (!matchesMetric(state.turn, condition.turn)) {
    return false;
  }

  return true;
}
