using OnlineMaps;
using OnlineMaps.Webservices;
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
    [ActionCategory(OnlineMapsCategories.GOOGLE)]
    [Tooltip("Allows you to search for up to 200 places at once, but with less detail than is typically returned from a Text Search or Nearby Search request.")]
    public class FindPlacesRadar : FsmStateAction
    {
        [RequiredField]
        [Tooltip("The latitude/longitude around which to retrieve place information. ")]
        public FsmVector2 coordinates;

        [RequiredField]
        [Tooltip("Defines the distance (in meters) within which to return place results. The maximum allowed radius is 50000 meters.")]
        public FsmInt radius = 5000;

        [Tooltip("A term to be matched against all content that Google has indexed for this place, including but not limited to name, type, and address, as well as customer reviews and other third-party content.")]
        public FsmString keyword;

        [Tooltip("One or more terms to be matched against the names of places, separated with a space character. Results will be restricted to those containing the passed name values. Note that a place may have additional names associated with it, beyond its listed name. The API will try to match the passed name value against all of these names. As a result, places may be returned in the results whose listed names do not match the search term, but whose associated names do.")]
        public FsmString _name;

        [Tooltip("Restricts the results to places matching at least one of the specified types. Types should be separated with a pipe symbol (type1|type2|etc).")]
        public FsmString types;

        [Tooltip("Restricts results to only those places within the specified range. Valid values range between 0 (most affordable) to 4 (most expensive), inclusive. The exact amount indicated by a specific value will vary from region to region.")]
        public FsmInt minPrice = -1;

        [Tooltip("Restricts results to only those places within the specified range. Valid values range between 0 (most affordable) to 4 (most expensive), inclusive. The exact amount indicated by a specific value will vary from region to region.")]
        public FsmInt maxPrice = -1;

        [Tooltip("Returns only those places that are open for business at the time the query is sent. ")]
        public FsmBool openNow = false;

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

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

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

        [UIHint(UIHint.Variable)]
        [Tooltip("Count of response results.")]
        public FsmInt storeResponseObjectCount;

        public override void Reset()
        {
            coordinates = null;
            radius = 5000;
            keyword = new FsmString { UseVariable = true };
            _name = new FsmString { UseVariable = true };
            types = new FsmString { UseVariable = true };
            minPrice = new FsmInt { UseVariable = true, Value = -1 };
            maxPrice = new FsmInt { UseVariable = true, Value = -1 };
            openNow = new FsmBool { UseVariable = true, Value = false };
            OnComplete = null;
            storeResponseString = null;
            storeResponseObject = null;
            storeResponseObjectCount = null;
        }

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

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

            string keywordValue = keyword.IsNone ? null : keyword.Value;
            string nameValue = _name.IsNone ? null : _name.Value;
            string typesValue = types.IsNone ? null : types.Value;
            int minPriceValue = minPrice.IsNone ? -1 : minPrice.Value;
            int maxPriceValue = maxPrice.IsNone ? -1 : maxPrice.Value;
            bool openNowValue = openNow.IsNone ? false : openNow.Value;
            new GooglePlacesRadarRequest(coordinates.Value, radius.Value)
            {
                keyword = keywordValue,
                name = nameValue,
                types = typesValue,
                minprice = minPriceValue,
                maxprice = maxPriceValue,
                opennow = openNowValue
            }.HandleComplete(s => 
            {
                storeResponseString.Value = s;
                FindPlaceResponseWrapper wrapper = new FindPlaceResponseWrapper(s);
                storeResponseObject.Value = wrapper;
                storeResponseObjectCount.Value = wrapper.count;

                if (OnComplete != null) Fsm.Event(OnComplete);
            }).Send();
        }
    }
}