using System.Collections.Generic;
using System.Linq;
using Verse;
using RimWorld;
using rjw;
using SCE.Patches;
using Verse.Profile;

namespace SCE
{
    public class PreceptComp_SexMemory : PreceptComp_SelfTookMemoryThought
    {
        public bool mayBeUnconscious;

        public bool mustNotBeRapeVictim;

        public bool mustBeInitiator;

        public bool blockedByLoveEnhancer;

        public bool allowStandardSexMemories;

        public float moodPowerFactor = 1f;

        public Dictionary<xxx.rjwSextype, ThoughtDef> thoughtOverrides;

        public Dictionary<xxx.rjwSextype, ThoughtDef> initiatorThoughtOverrides;

        public Dictionary<xxx.rjwSextype, ThoughtDef> recipientThoughtOverrides;

        private ThoughtDef SelectThought(Pawn doer, SexProps props)
        {
            ThoughtDef overrideThought;

            if (props.pawn == doer)
            {
                if (initiatorThoughtOverrides.TryGetValue(props.sexType, out overrideThought))
                {
                    return overrideThought;
                }
            }
            else if (recipientThoughtOverrides.TryGetValue(props.sexType, out overrideThought))
            {
                return overrideThought;
            }

            if (thoughtOverrides.TryGetValue(props.sexType, out overrideThought))
            {
                return overrideThought;
            }

            return thought;
        }

        public bool TryGiveSexMemory(HistoryEvent ev, Precept precept)
        {
            if (ev.def != eventDef)
            {
                return false;
            }

            if (!ShouldGiveSexMemory(ev, precept))
            {
                return false;
            }

            Pawn doer = ev.args.GetArg<Pawn>(HistoryEventArgsNames.Doer);
            SexProps props = ev.args.GetArg<SexProps>(SCEHistoryEventArgNames.SexProps);
            bool isReceiving = doer == props.partner;

            if (isReceiving)
            {
                if (mustBeInitiator)
                {
                    return false;
                }
                if (mustNotBeRapeVictim && props.isRape)
                {
                    return false;
                }
            }

            if (doer.needs?.mood?.thoughts == null)
            {
                return false;
            }

            if (onlyForNonSlaves && doer.IsSlave)
            {
                return false;
            }

            if (blockedByLoveEnhancer 
                && (props.pawn.health.hediffSet.HasHediff(HediffDefOf.LoveEnhancer) 
                    || props.partner.health.hediffSet.HasHediff(HediffDefOf.LoveEnhancer)))
            {
                return false;
            }

            if (thought.minExpectation != null 
                && ExpectationsUtility.CurrentExpectationFor(doer).order < thought.minExpectation.order)
            {
                return false;
            }

            Thought_Memory memory = ThoughtMaker.MakeThought(SelectThought(doer, props), precept);

            Pawn otherPawn = isReceiving ? props.pawn : props.partner;
            doer.needs.mood.thoughts.memories.TryGainMemory(memory, otherPawn);
            return true;
        }

        protected virtual bool ShouldGiveSexMemory(HistoryEvent ev, Precept precept)
        {
            return true;
        }

        // Thought needs to be added manually since we need to know whether to proceed with
        // RJW's think_about_sex methods.
        public override void Notify_MemberTookAction(HistoryEvent ev, Precept precept, bool canApplySelfTookThoughts)
        {
        }
    }
}