using RimWorld;
using System.Collections.Generic;
using System.Linq;
using Verse;
using System;

namespace rjw.RMB
{
	/// <summary>
	/// Generator of RMB categories for necrophilia
	/// </summary>
	static class RMB_Necro
	{
		/// <summary>
		/// Add necrophilia and reverse necrophilia options to <paramref name="opts"/>
		/// </summary>
		/// <param name="pawn">Selected pawn</param>
		/// <param name="opts">List of RMB options</param>
		/// <param name="target">Target of the right click</param>
		public static void AddFloatMenuOptions(Pawn pawn, List<FloatMenuOption> opts, LocalTargetInfo target)
		{
			if (target.Thing is not Corpse corpse)
			{
				return;
			}

			AcceptanceReport canCreateEntries = DoBasicChecks(pawn, corpse);

			if (!canCreateEntries)
			{
				if (RJWSettings.DevMode && !canCreateEntries.Reason.NullOrEmpty())
					opts.Add(new FloatMenuOption(canCreateEntries.Reason, null));

				return;
			}

			canCreateEntries = DoChecks(pawn, corpse);

			if (!canCreateEntries)
			{
				opts.Add(new FloatMenuOption("RJW_RMB_RapeCorpse".Translate(corpse) + ": " + canCreateEntries.Reason, null));
				return;
			}

			FloatMenuOption opt = GenerateCategoryOption(pawn, target);
			if (opt != null)
				opts.Add(opt);

			opt = GenerateCategoryOption(pawn, target, true);
			if (opt != null)
				opts.Add(opt);
		}

		/// <summary>
		/// Check for the things that should be obvious to the player or does not change for particular pawns.
		/// </summary>
		/// <returns>
		/// AcceptanceReport. Reason is an untranslated string and should only be shown in the DevMode
		/// </returns>
		private static AcceptanceReport DoBasicChecks(Pawn pawn, Corpse target)
		{
			if (!RJWSettings.necrophilia_enabled)
			{
				return "No necro: Disabled by the mod settings";
			}

			if (target.InnerPawn == null || target.InnerPawn == pawn)
			{
				return false;
			}

			if (!xxx.can_rape(pawn, true))
			{
				return "No necro: Pawn can't rape";
			}

			return true;
		}

		/// <summary>
		/// Check for the things that can change for particular pawns.
		/// </summary>
		/// <returns>
		/// AcceptanceReport. Reason is a translated string and should not be null.
		/// </returns>
		private static AcceptanceReport DoChecks(Pawn pawn, Corpse target)
		{
			if (!pawn.IsDesignatedHero() && !pawn.IsHeroOwner())
			{
				if (SexAppraiser.would_fuck(pawn, target.InnerPawn) < 0.1f)
				{
					return "RJW_RMB_ReasonUnappealingTarget".Translate();
				}
			}

			return true;
		}

		/// <summary>
		/// Generate one FloatMenuOption
		/// </summary>
		/// <param name="pawn"></param>
		/// <param name="target"></param>
		/// <param name="reverse"></param>
		/// <returns>Category-level item that opens a sub-menu on click</returns>
		private static FloatMenuOption GenerateCategoryOption(Pawn pawn, LocalTargetInfo target, bool reverse = false)
		{
			string text = null;
			Corpse corpse = target.Thing as Corpse;

			if (reverse)
			{
				text = "RJW_RMB_RapeCorpse_Reverse".Translate(corpse);
			}
			else
			{
				text = "RJW_RMB_RapeCorpse".Translate(corpse);
			}

			Action action = delegate ()
			{
				JobDef job = xxx.RapeCorpse;
				var validinteractions = RMB_Menu.GenerateNonSoloSexRoleOptions(pawn, target, job, true, reverse);
				if (validinteractions.Any())
					FloatMenuUtility.MakeMenu(validinteractions, (FloatMenuOption opt) => opt.Label, (FloatMenuOption opt) => opt.action);
				else
					Messages.Message("No valid interactions found for " + text, MessageTypeDefOf.RejectInput, false);
			};

			return FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text, action, MenuOptionPriority.High), pawn, target);
		}
	}
}
