using System.Collections.Generic;

namespace Wizard;

public abstract class AIBarrierInfoBase
{
	public int BarrierAmount { get; protected set; }

	public AIDamageType DamageType { get; protected set; }

	public List<AIBarrierStopTiming> StopTimingList { get; protected set; }

	public abstract AIBarrierType BarrierType { get; }

	public ulong Hash { get; protected set; }

	public AIBarrierInfoBase(int amount, AIDamageType damageType, AIBarrierStopTiming stopTiming = AIBarrierStopTiming.None)
	{
		BarrierAmount = amount;
		DamageType = damageType;
		if (stopTiming != AIBarrierStopTiming.None)
		{
			StopTimingList = new List<AIBarrierStopTiming> { stopTiming };
		}
		else
		{
			StopTimingList = null;
		}
	}

	public AIBarrierInfoBase(int amount, AIDamageType damageType, List<AIBarrierStopTiming> stopTimingList)
	{
		BarrierAmount = amount;
		DamageType = damageType;
		StopTimingList = stopTimingList;
	}

	public int GetDamageAmount(AIVirtualCard owner, int damage, bool isSkillDamage, bool isSpellDamage)
	{
		if (IsDamageType(isSkillDamage, isSpellDamage))
		{
			return CalcDamage(owner, damage);
		}
		return damage;
	}

	public bool IsDamageType(bool isSkillDamage, bool isSpellDamage)
	{
		if (DamageType == AIDamageType.All)
		{
			return true;
		}
		if (DamageType == AIDamageType.Skill && (isSkillDamage || isSpellDamage))
		{
			return true;
		}
		if (DamageType == AIDamageType.Spell && isSpellDamage)
		{
			return true;
		}
		if (DamageType == AIDamageType.Attack && !isSkillDamage && !isSpellDamage)
		{
			return true;
		}
		return false;
	}

	public bool IsMatchingStopTiming(AIBarrierStopTiming timing)
	{
		if (StopTimingList == null || StopTimingList.Count <= 0)
		{
			return timing == AIBarrierStopTiming.None;
		}
		for (int i = 0; i < StopTimingList.Count; i++)
		{
			if (timing == StopTimingList[i])
			{
				return true;
			}
		}
		return false;
	}

	protected virtual void UpdateHash()
	{
		Hash = AIBarrierSimulationUtility.CalculateBarrierInfoBaseHash(DamageType, BarrierType, StopTimingList);
	}

	public bool IsDuplicate(AIBarrierType barrierType, AIDamageType damageType, int barrierAmount)
	{
		if ((long)BarrierAmount * (long)AIBarrierSimulationUtility.BARRIER_AMOUNT_HASH_COEFFICIENT + (long)DamageType * (long)AIBarrierSimulationUtility.DAMAGE_TYPE_HASH_COEFFICIENT + (long)BarrierType * (long)AIBarrierSimulationUtility.BARRIER_TYPE_HASH_COEFFICIENT == (long)Hash)
		{
			return true;
		}
		return false;
	}

	public abstract AIBarrierInfoBase Clone();

	public abstract bool IsShield();

	protected abstract int CalcDamage(AIVirtualCard owner, int damage);
}
