using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

using Proyecto26;

using UnityEngine;
using UnityEngine.Networking;
namespace XenseAR
{

    public class AssetbundleAnchorEditor : AssetbundleAnchor, IEditor
    {
        [SerializeField] List<string> assetNames;

        private mTransform _transform = new mTransform();

        private bool _isNew = false;

        private bool _isSaved = false;

        private bool _isUpdating = false;

        private bool _isEdited = false;

        private bool _isError = false;

        public bool isNew
        {
            get { return _isNew; }
            set { _isNew = value; }
        }

        public bool isEdited
        {
            get { return _isEdited; }
            set { _isEdited = value; }
        }

        public bool isError
        {
            get { return _isError; }
            set { _isError = value; }
        }

        public bool isSaved
        {
            get { return _isSaved; }
            set { _isSaved = value; }
        }

        public bool isUpdating
        {
            get { return _isUpdating; }
            set { _isUpdating = value; }
        }

        protected override void Awake()
        {
            base.Awake();
        }

        protected override void Start()
        {
            base.Start();
            target.media.Type = AnchoringMediaType.Assetbundle;
        }

        protected void Update()
        {
            _transform.FromUnity(gameObject.transform);
            if (!Utility.Compare(_transform, target.transform))
            {
                MarkAsEdited();
            }
        }

        void SetIsEditedAndOppositeIsSaved(bool check)
        {
            isEdited = check;
            isSaved = !isEdited;
        }
        public void MarkAsEdited() => SetIsEditedAndOppositeIsSaved(true);

        public void Fetch()
        {
            StartCoroutine(PopulateAssetBundlesNameList());
        }

        IEnumerator PopulateAssetBundlesNameList()
        {
            assetNames = new List<string>();
#if UNITY_IOS
        UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle(target.media.url+Defines.iosPostfix);
#else
            UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle(target.media.url + Defines.androidPostfix);
#endif
            yield return www.SendWebRequest();

            if (www.result != UnityWebRequest.Result.Success)
            {
                bundleObjectName = "Bundle is empty, please check Url!!!";
                Debug.Log(www.error);
            }
            else
            {
                AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(www);
                assetNames = bundle.GetAllAssetNames().ToList();
                bundle.Unload(false);
            }
        }

        public void Save()
        {
            if (isUpdating) return;

            string blockID = GetComponentInParent<ARWorldBlockInfo>().GetInfo().ID;
            SetBlockID(blockID);

            string worldID = GetComponentInParent<WorldSelector>().GetWorldID();
            SetWorldID(worldID);

            isNew = false;
            isError = false;
            isSaved = false;
            isUpdating = true;

            if (string.IsNullOrEmpty(target.id))
                isNew = true;
            if (isNew)
            {
                target.media.id = System.Guid.NewGuid().ToString();
                target.media.name = "Default Name";

                target.transform.FromUnity(transform);
                target.boundSize = Vector3.one;
                target.id = System.Guid.NewGuid().ToString();
                target.media.name = bundleObjectName;

                string jsonStr = JsonUtility.ToJson(target);

                BackendServices.Instance.Post(new RequestHelper
                {
                    SimpleForm = new Dictionary<string, string>()
                    {
                        {"type","AddNewAnchoringTarget" },
                        {"BlockID",this.GetBlockID() },
                        {"worldId", this.GetWorldID()},
                        {"anchoringTargetData",jsonStr},
                    },
                    //            Uri = "",
                }).Then(res => OnFinishSave(res))
                .Catch(err =>
                {
                    NotifySaveError($"Save Error (New Target - Backend Post): {err}");
                });

                Dictionary<string, object> parameters = new Dictionary<string, object>()
                {
                    { "targetID", target.id},
                    { "blockID", this.GetBlockID()},
                    { "targetName", target.media.name},
                    { "targetType", target.media.Type},
                    { "positionX", target.transform.position.x},
                    { "positionY", target.transform.position.y},
                    { "positionZ", target.transform.position.z},
                    { "rotationX", target.transform.orientation.x},
                    { "rotationY", target.transform.orientation.y},
                    { "rotationZ", target.transform.orientation.z},
                    { "rotationW", target.transform.orientation.w},
                    { "scaleX", target.transform.scale.x},
                    { "scaleY", target.transform.scale.y},
                    { "scaleZ", target.transform.scale.z},
                    { "dateCreated", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")},
                };
                AnalyticsSender.Instance.SendEvent("createTarget", parameters);

            }
            else
            {
                target.media.name = bundleObjectName;
                target.transform.FromUnity(transform);
                target.boundSize = Utility.GetBound(gameObject).size;
                if (target.boundSize == Vector3.zero)
                {
                    target.boundSize = Vector3.one;
                }

                string jsonStr = JsonUtility.ToJson(target);
                BackendServices.Instance.Post(new RequestHelper
                {
                    SimpleForm = new Dictionary<string, string>()
            {
                {"type","UpdateAnchoringTarget" },
                {"anchoringTargetId",target.id },
                {"anchoringTargetData",jsonStr},
            },
                    //            Uri = "",
                }).Then(res => OnFinishSave(res))
                .Catch(err =>
                {
                    NotifySaveError($"Save Error (Update Target - Backend Post): {err}");
                });

                Dictionary<string, object> parameters = new Dictionary<string, object>()
                {
                    { "targetID", target.id},
                    { "blockID", this.GetBlockID()},
                    { "worldId", this.GetWorldID()},
                    { "targetName", target.media.name},
                    { "targetType", target.media.Type},
                    { "positionX", target.transform.position.x},
                    { "positionY", target.transform.position.y},
                    { "positionZ", target.transform.position.z},
                    { "rotationX", target.transform.orientation.x},
                    { "rotationY", target.transform.orientation.y},
                    { "rotationZ", target.transform.orientation.z},
                    { "rotationW", target.transform.orientation.w},
                    { "scaleX", target.transform.scale.x},
                    { "scaleY", target.transform.scale.y},
                    { "scaleZ", target.transform.scale.z},
                    { "dateUpdated", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")},
                };
                AnalyticsSender.Instance.SendEvent("updateTarget", parameters);
            }
        }

        void NotifySaveError(string errorMessage)
        {
            Debug.LogError(errorMessage);
            isError = true;
            isUpdating = false;
        }

        public void Load()
        {
            if (isNew || target == null || string.IsNullOrEmpty(target.id)) return;
            BackendServices.Instance.Post(new RequestHelper
            {
                SimpleForm = new Dictionary<string, string>()
            {
                {"type","GetAnchoringTarget" },
                {"anchoringTargetId", target.id},
            },
                //            Uri = "",
            }).Then(res => OnFinishLoad(res));
        }

        public void Remove()
        {
            if (isNew || target == null || string.IsNullOrEmpty(target.id)) return;
            BackendServices.Instance.Post(new RequestHelper
            {
                SimpleForm = new Dictionary<string, string>()
            {
                {"type","DeleteAnchoringTarget" },
                {"anchoringTargetId", target.id},
            },
                //            Uri = "",
            }).Then(res => OnFinishRemove(res));
            Dictionary<string, object> parameters = new Dictionary<string, object>()
            {
                { "targetID", target.id},
                { "blockID", this.GetBlockID()},
                { "targetName", target.media.name},
                { "targetType", target.media.Type},
                { "dateDeleted", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")},
            };
            AnalyticsSender.Instance.SendEvent("deleteTarget", parameters);
        }

        private void OnFinishSave(ResponseHelper helper)
        {
            isError = false;
            isUpdating = false;
            if (!isError) SetIsEditedAndOppositeIsSaved(false);
            Load(target);
            Debug.Log(helper.Text);
        }

        private void OnFinishLoad(ResponseHelper helper)
        {
            Debug.Log(helper.Text);
        }

        private void OnFinishRemove(ResponseHelper helper)
        {
            Debug.Log(helper.Text);
            Destroy(this.gameObject);
        }
        public AnchoringTarget GetTarget() => target;
        public string GetBundleObjectName() => bundleObjectName;
    }
}
