﻿using RimWorld;
using System.Collections.Generic;
using System.Linq;
using Verse;
using Multiplayer.API;

namespace rjw
{
	/// <summary>
	/// Generator of RMB categories for socializing
	/// </summary>
	static class RMB_Socialize
	{
		/// <summary>
		/// Add socialize option to <paramref name="opts"/>
		/// </summary>
		/// <param name="pawn">Selected pawn</param>
		/// <param name="opts">List of RMB options</param>
		/// <param name="target">Target of right click</param>
		public static void AddFloatMenuOptions(Pawn pawn, List<FloatMenuOption> opts, LocalTargetInfo target)
		{
			AcceptanceReport canCreateEntries = DoBasicChecks(pawn, target.Pawn);

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

				return;
			}

			FloatMenuOption opt = GenerateCategoryOption(pawn, target);
			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, Pawn target)
		{
			if (!pawn.interactions.CanInteractNowWith(target))
			{
				return $"No socialize: cannot interact with {target.NameShortColored} now";
			}

			return true;
		}

		private static FloatMenuOption GenerateCategoryOption(Pawn pawn, LocalTargetInfo target)
		{
			return FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("RJW_RMB_Social".Translate(target.Pawn), delegate ()
			{
				FloatMenuUtility.MakeMenu(GenerateSocialOptions(pawn, target).Where(x => x.action != null), (FloatMenuOption opt) => opt.Label, (FloatMenuOption opt) => opt.action);
			}, MenuOptionPriority.High), pawn, target);
		}

		/// <summary>
		/// Generates sub-menu options for socializing
		/// </summary>
		/// <param name="pawn">Initiator pawn</param>
		/// <param name="target">Target pawn</param>
		/// <returns>A list of menu options, where each item represents a possible interaction</returns>
		private static List<FloatMenuOption> GenerateSocialOptions(Pawn pawn, LocalTargetInfo target)
		{
			List<FloatMenuOption> opts = new List<FloatMenuOption>();
			FloatMenuOption option = null;

			option = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("RJW_RMB_Insult".Translate(), delegate ()
			{
				Socialize(pawn, target, InteractionDefOf.Insult);
			}, MenuOptionPriority.High), pawn, target);
			opts.Add(option);

			if (!pawn.HostileTo(target.Pawn))
			{
				option = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("RJW_RMB_SocialFight".Translate(), delegate ()
				{
					SocializeFight(pawn, target);
				}, MenuOptionPriority.High), pawn, target);
				opts.Add(option);

				option = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("RJW_RMB_Chat".Translate(), delegate ()
				{
					Socialize(pawn, target, InteractionDefOf.Chitchat);
				}, MenuOptionPriority.High), pawn, target);
				opts.Add(option);

				// OP shit +12 relations, enable in cheat menu
				if (RJWSettings.Allow_RMB_DeepTalk)
				{
					option = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("RJW_RMB_DeepTalk".Translate(), delegate ()
					{
						pawn.interactions.TryInteractWith(target.Pawn, InteractionDefOf.DeepTalk);
					}, MenuOptionPriority.High), pawn, target);
					opts.Add(option);
				}

				if (!LovePartnerRelationUtility.LovePartnerRelationExists(pawn, target.Pawn))
				{
					option = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("RJW_RMB_RomanceAttempt".Translate(), delegate ()
					{
						Socialize(pawn, target, InteractionDefOf.RomanceAttempt);
					}, MenuOptionPriority.High), pawn, target);
					opts.Add(option);
				}

				if (pawn.relations.DirectRelationExists(PawnRelationDefOf.Lover, target.Pawn) || pawn.relations.DirectRelationExists(PawnRelationDefOf.Fiance, target.Pawn))
				{
					option = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("RJW_RMB_MarriageProposal".Translate(), delegate ()
					{
						Socialize(pawn, target, InteractionDefOf.MarriageProposal);
					}, MenuOptionPriority.High), pawn, target);
					opts.Add(option); 
				}
			}

			return opts;
		}

		//multiplayer synch actions

		/// <summary>
		/// Stops current job of the <paramref name="pawn"/> and starts a social fight
		/// </summary>
		/// <param name="pawn">Initiator</param>
		/// <param name="target">Target pawn</param>
		[SyncMethod]
		static void SocializeFight(Pawn pawn, LocalTargetInfo target)
		{
			pawn.interactions.StartSocialFight(target.Pawn);
		}

		/// <summary>
		/// Stops current job of the <paramref name="pawn"/> and starts an interaction
		/// </summary>
		/// <param name="pawn">Initiator</param>
		/// <param name="target">Target pawn</param>
		/// <param name="interaction">Interaction def</param>
		[SyncMethod]
		static void Socialize(Pawn pawn, LocalTargetInfo target, InteractionDef interaction)
		{
			pawn.interactions.TryInteractWith(target.Pawn, interaction);
		}
	}
}