// lib/game/model/stat.dart

import '../enums.dart';

/// 스탯 수정자 클래스.
/// 특정 스탯에 적용되어 최종 값을 변경한다.
class Modifier {
  final ModifierType type;
  final double value; // Flat 값 또는 Percent 비율 (예: 0.10 for 10%)

  Modifier({required this.type, required this.value});

  @override
  String toString() {
    String sign = value >= 0 ? '+' : '';
    if (type == ModifierType.flat) {
      return '$sign${value.toInt()}';
    } else {
      return '$sign${(value * 100).toInt()}%';
    }
  }

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Modifier &&
          runtimeType == other.runtimeType &&
          type == other.type &&
          value == other.value;

  @override
  int get hashCode => type.hashCode ^ value.hashCode;
}

/// 게임 내 모든 엔티티의 스탯을 표현하는 클래스.
/// 기본 값(BaseValue)과 여러 수정자(Modifier)들을 조합하여 최종 값(Value)을 계산한다.
class Stat {
  double _baseValue;
  final List<Modifier> _modifiers = [];

  Stat({required double baseValue}) : _baseValue = baseValue {
    _recalculateValue();
  }

  /// 현재 스탯의 기본 값.
  double get baseValue => _baseValue;

  /// 기본 값을 설정한다. 이 경우 최종 값도 다시 계산된다.
  set baseValue(double newValue) {
    _baseValue = newValue;
    _recalculateValue();
  }

  /// 모든 수정자들이 적용된 최종 스탯 값.
  /// 이 값은 기본 값이나 수정자가 변경될 때마다 자동으로 다시 계산된다.
  double _value = 0.0;
  double get value => _value;

  /// 수정자를 추가하고 최종 스탯 값을 다시 계산한다.
  void addModifier(Modifier modifier) {
    _modifiers.add(modifier);
    _recalculateValue();
  }

  /// 특정 수정자를 제거하고 최종 스탯 값을 다시 계산한다.
  void removeModifier(Modifier modifier) {
    _modifiers.remove(modifier);
    _recalculateValue();
  }

  /// 모든 수정자를 제거하고 최종 스탯 값을 다시 계산한다.
  void clearModifiers() {
    _modifiers.clear();
    _recalculateValue();
  }

  /// 기본 값과 모든 수정자들을 바탕으로 최종 스탯 값을 계산한다.
  /// Flat 수정자가 먼저 적용된 후 Percent 수정자가 적용된다.
  void _recalculateValue() {
    double tempValue = _baseValue;
    double percentAdditive = 0.0;

    // Flat 수정자 먼저 적용
    for (var modifier in _modifiers) {
      if (modifier.type == ModifierType.flat) {
        tempValue += modifier.value;
      }
    }

    // Percent 수정자 값 합산 (예: 10% + 5% = 15%)
    for (var modifier in _modifiers) {
      if (modifier.type == ModifierType.percent) {
        percentAdditive += modifier.value;
      }
    }

    // 합산된 Percent 수정자 적용
    _value = tempValue * (1 + percentAdditive);
  }

  @override
  String toString() {
    return 'Stat(base: $_baseValue, final: $_value, modifiers: ${_modifiers.length})';
  }
}
