using System.Collections.Generic;
using System.Linq;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Utilities;

namespace EscapeRoomEngine.Engine.Runtime.Requirements
{
    /// <summary>
    /// The main class any placement requirement inherits from. To place a module, every possible placement inside the space is put into a list of candidates that is then filtered by all placement requirements.
    /// </summary>
    public abstract class PlacementRequirement : Requirement<Placement>
    {
        protected abstract override List<Placement> FilterCandidates(List<Placement> candidates, Module module, Space space);

        public static bool TryPlacing(Module module, Space space)
        {
            if (module.description.placementRequirements.Count == 0)
            {
                // don't evaluate requirements if there are none
                return true;
            }
            
            var placementCandidates = Candidates(
                module.srPlacement.EveryPlacementInSpace(space),
                module.description.placementRequirements,
                module, space);
            
            Logger.Log($"placement candidates: {string.Join(", ", placementCandidates.ToList().ConvertAll(c => c.ToStringShort()))}", LogType.RequirementResolution);
            
            if (placementCandidates.Count > 0)
            {
                module.Place(placementCandidates.RandomElement());
                return true;
            }
            // ReSharper disable once RedundantIfElseBlock
            else
            {
                Logger.Log($"Could not find suitable placement for {module}", LogType.RequirementResolution);
                return false;
            }
        }
    }
}