using System.Linq;
using Verse;
using Verse.AI;
using RimWorld;

namespace SCE
{
    // Because RitualPosition_VerticalThingCentre helpfully forbids pawns from standing on the target even if it's a spot or similar
    public class RitualPosition_OnThingCentre : RitualPosition
    {
        public IntVec3 offset;
        public Rot4 facing = Rot4.Invalid;

        public override PawnStagePosition GetCell(IntVec3 spot, Pawn p, LordJob_Ritual ritual)
        {
            // This looks silly, but I think it might be necessary to check that the target is where it's
            // supposed to be. At the very least, most vanilla positions seem to think it's important.
            var thing = spot.GetThingList(p.Map).FirstOrDefault((Thing t) => t == ritual.selectedTarget.Thing);
            var map = p.MapHeld;

            IntVec3 cell = offset.RotatedBy(thing.Rotation) + thing.PositionHeld;

            if (!Validator(cell))
            {
                cell = GetFallbackSpot(thing.OccupiedRect(), spot, p, ritual, Validator);
            }

            return new PawnStagePosition(cell, thing, facing.RotatedBy(thing.Rotation), highlight);


			bool Validator(IntVec3 c)
			{
				return c.Standable(map) && WanderUtility.InSameRoom(c, spot, map)
                        && p.CanReserveAndReach(c, PathEndMode.OnCell, p.NormalMaxDanger());
            }
        }

        public override bool CanUse(IntVec3 spot, Pawn p, LordJob_Ritual ritual)
        {
            return ritual.selectedTarget.HasThing && ritual.selectedTarget.Thing.def.passability == Traversability.Standable;
        }

        public override void ExposeData()
        {
            base.ExposeData();
            Scribe_Values.Look(ref offset, "offset");
            Scribe_Values.Look(ref facing, "facing", Rot4.Invalid);
        }
    }
}