using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules;
using UnityEngine;

namespace EscapeRoomEngine.Engine.Runtime.Requirements
{
    /// <summary>
    /// This requirement guarantees that the module faces the center of the space.
    /// </summary>
    [CreateAssetMenu(menuName = "Requirements/Face Space Center")]
    public class FaceSpaceCenter : PlacementRequirement
    {
        protected override List<Placement> FilterCandidates(List<Placement> candidates, Module module, Space space)
        {
            float width = space.rrPlacement.size.x;
            float length = space.rrPlacement.size.y;

            candidates.RemoveAll(candidate =>
            {
                var orientation = candidate.orientation;
                var center = candidate.GeometricCenter;
                var xRel = center.x / width;
                var zRel = center.z / length;
                bool keep;

                // check the space diagonals
                if (Mathf.Approximately(xRel, zRel))
                {
                    keep = Mathf.Approximately(xRel, 0.5f) ||
                           (xRel < 0.5f
                               ? orientation is Orientation.East or Orientation.North // on bottom left diagonal of space
                               : orientation is Orientation.West or Orientation.South); // on top right diagonal of space
                }
                else if (Mathf.Approximately(xRel, 1 - zRel))
                {
                    keep = xRel < 0.5f
                        ? orientation is Orientation.East or Orientation.South // on top left diagonal of space
                        : orientation is Orientation.West or Orientation.North; // on bottom right diagonal of space
                }
                else
                {
                    // check the areas between the diagonals
                    keep = orientation ==
                           (zRel > xRel
                               ? zRel > 1 - xRel
                                   ? Orientation.South
                                   : Orientation.East
                               : zRel > 1 - xRel
                                   ? Orientation.West
                                   : Orientation.North);
                }
                
                return !keep;
            });

            return candidates;
        }
    }
}