using OnlineMaps;
using OnlineMaps.Webservices;
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
    [ActionCategory(OnlineMapsCategories.GOOGLE)]
    [Tooltip("Find directions between locations.")]
    public class FindDirection : FsmStateAction
    {
        [Tooltip("Coordinates of the route begins.")]
        public FsmVector2 fromCoordinates;

        [Tooltip("Title of the route begins.")]
        public FsmString fromLocation;

        [Tooltip("Coordinates of the route ends.")]
        public FsmVector2 toCoordinates;

        [Tooltip("Title of the route ends.")]
        public FsmString toLocation;

        [Tooltip("Search alternative routes.")]
        public FsmBool alternativeRoutes = false;

        [Tooltip("On request complete event.")]
        public FsmEvent OnComplete;

        [Tooltip("Response as string.")]
        [UIHint(UIHint.Variable)]
        public FsmString storeResponseString;

        [Tooltip("Response as object.")]
        [UIHint(UIHint.Variable)]
        public FsmObject storeResponseObject;

        [Tooltip("Route count.")]
        [UIHint(UIHint.Variable)]
        public FsmInt storeResponseRoutesCount;

        public override void Reset()
        {
            fromCoordinates = new FsmVector2 { UseVariable = true };
            fromLocation = new FsmString { UseVariable = true };
            toCoordinates = new FsmVector2 { UseVariable = true };
            toLocation = new FsmString { UseVariable = true };
            alternativeRoutes = false;
            OnComplete = null;
            storeResponseString = null;
            storeResponseObject = null;
            storeResponseRoutesCount = null;
        }

        public override void OnEnter()
        {
            DoEnter();
            Finish();
        }

        private void DoEnter()
        {
            if (!Map.instance)
            {
                Debug.LogError("Online Maps not found.");
                return;
            }

            object from = !fromCoordinates.IsNone ? fromCoordinates.Value : fromLocation.Value;
            object to = !toCoordinates.IsNone ? toCoordinates.Value : toLocation.Value;

            if (from == null)
            {
                Debug.LogError("Origin is not set.");
                return;
            }

            if (to == null)
            {
                Debug.LogError("Destination is not set.");
                return;
            }

            new GoogleRoutingRequest(from, to)
                {
                    computeAlternativeRoutes = alternativeRoutes.Value,
                }.HandleComplete(OnRequestComplete)
                .Send();
        }

        private void OnRequestComplete(string response)
        {
            storeResponseString.Value = response;
            FindDirectionResponseWrapper wrapper = new FindDirectionResponseWrapper(GoogleRoutingResult.Parse(response));
            storeResponseObject.Value = wrapper;
            storeResponseRoutesCount.Value = wrapper.count;
            if (OnComplete != null) Fsm.Event(OnComplete);
        }
    }
}