﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;

namespace Sharp.Rpg
{
	public static class InventoryExtensions
	{
		public static void InventoryAdd(this GameObject gameObject, params GameObject[] items)
		{
			gameObject.LocalMessenger.Publish(new InventoryChangeMessage
			{
				Target = gameObject,
				Items = items,
				Type = InventoryChangeType.Add
			});
		}

		public static void InventoryRemove(this GameObject gameObject, params GameObject[] items)
		{
			gameObject.LocalMessenger.Publish(new InventoryChangeMessage
			{
				Target = gameObject,
				Items = items,
				Type = InventoryChangeType.Remove
			});
		}

		public static void InventoryReset(this GameObject gameObject)
		{
			gameObject.LocalMessenger.Publish(new InventoryChangeMessage
			{
				Target = gameObject,
				Type = InventoryChangeType.Reset
			});
		}

		public static IEnumerable<GameObject> InventoryFetch(this GameObject gameObject, int fetchTimeoutMs = 2000)
		{
			var items = new List<GameObject>();
			IDisposable responseSubscription = null;
			try
			{
				gameObject.LocalMessenger.Publish(new QueryMessage
				{
					QueryType = Constants.QueryTypes.Inventory,
					Target = gameObject
				}, ctx =>
					responseSubscription = ctx.HandleResponse<QueryResultMessage<GameObject[]>>(
													queryResult => items.AddRange(queryResult.Result)));

				var sw = Stopwatch.StartNew();

				SpinWait.SpinUntil(() => items.Count > 0 || sw.ElapsedMilliseconds > fetchTimeoutMs);
			}
			finally
			{
				responseSubscription?.Dispose();
			}
			return items;
		}
	}
}
