using System;
using System.IO;
namespace XenseAR
{
    using UnityEngine;
    using UnityEngine.Events;

    public class BaseAnchor : MonoBehaviour, IAnchoringLabel
    {
        protected ILoadingTargetAlgorithm algorithm;
        protected ITrigger trigger;
        protected bool hasLoad = false;
        protected bool hasDispose = false;
        protected string BlockID;
        protected string WorldID;
        [SerializeField] protected AnchoringTarget target;

        [HideInInspector]
        public string Id = string.Empty;

        string IAnchoringLabel.Id => Id;


        public bool HasLoad
        {
            get { return hasLoad; }
            set
            {
                if (hasLoad == false && value == true)
                {
                    Debug.Log("progress invoke "+gameObject.name);
                    OnLoadAnchor?.Invoke(this);
                    hasLoad = value;
                }
               
            }
        }


        public string GetID()
        {
            return target.id;
        }

        public bool HasDispose
        {
            get { return hasDispose; }
            set
            {
                if (hasDispose == false && value == true)
                    OnDisposeAnchor?.Invoke(this);
                hasDispose = value;
            }
        }

        public GameObject LabelObject => gameObject;

        public event Action<IAnchoringLabel> OnLoadAnchor;
        public event Action<IAnchoringLabel> OnDisposeAnchor;

        protected virtual void Start()
        {
            float firstDelay = UnityEngine.Random.Range(0.1f, 1f);
            float repeatRate = UnityEngine.Random.Range(3f, 4f);
            InvokeRepeating("StatusUpdate", firstDelay, repeatRate);
        }
        protected virtual void OnDestroy()
        {
            CancelInvoke("StatusUpdate");
        }
        public virtual void Load(AnchoringTarget target)
        {
            //CreateIntantiatePlace();
            this.transform.localPosition = target.transform.position.ToUnity();
            this.transform.localRotation = target.transform.orientation.ToUnity();
            this.transform.localScale = target.transform.scale.ToUnity();

            this.Id = target.id;
            if (target.triggerRadius != 0)
                trigger = new AnchoringTrigger(target);
            //PlaceAnchor();
        }

        public virtual void UnLoad()
        {
            Hide();
        }

        public void Hide()
        {
            int childCount = this.transform.childCount;
            for (int i = 0; i < childCount; i++)
            {
                this.transform.GetChild(i).gameObject.SetActive(false);
            }
        }

        public void Show()
        {
            int childCount = this.transform.childCount;
            for (int i = 0; i < childCount; i++)
            {
                this.transform.GetChild(i).gameObject.SetActive(true);
            }
        }

        public virtual AnchoringMediaType GetType()
        {
            return target.media.Type;
        }

        protected string GetCacheFile(string url)
        {
            string CachePath = Application.persistentDataPath;

            CachePath = Path.Combine(CachePath, "AnchorCaches");
            if (!Directory.Exists(CachePath))
            {
                Directory.CreateDirectory(CachePath);
            }

            string[] token = url.Split(Defines.hostDomain);
            string[] folderNames;
            if (token.Length != 2)
            {
                Debug.Log("Something wrong with the storage!!!");
                return CachePath;
            }
            else
            {
                folderNames = token[1].Split("/");
                for (int i = 0; i < folderNames.Length - 1; i++)
                {
                    CachePath = Path.Combine(CachePath, folderNames[i]);
                    if (!Directory.Exists(CachePath))
                    {
                        Directory.CreateDirectory(CachePath);
                    }
                }
            }
            string fileName = Path.GetFileName(url);
            string CacheFile = Path.Combine(CachePath, fileName);
            return CacheFile;
        }

        protected void SaveToCache(string CacheFile, byte[] data)
        {
            if (File.Exists(CacheFile))
            {
                File.Delete(CacheFile);
            }
            File.WriteAllBytes(CacheFile, data);
        }

        protected virtual async void StatusUpdate()
        {
            if (trigger != null)
            {
                if (trigger.IsOnTriggerEnter(transform))
                {
                    API.OnTriggerEnter(target.id);
                }
                else if (trigger.IsOnTriggerExit(transform))
                {
                    API.OnTriggerExit(target.id);
                }
            }
        }

        public string GetBlockID()
        {
            return BlockID;
        }

        public void SetBlockID(string blockId)
        {
            BlockID = blockId;
        }

        public void SetWorldID(string worldId) 
        {
            WorldID = worldId;
        }

        public string GetWorldID()
        {
            return WorldID;
        }

        public virtual void Dispose()
        {
            Resources.UnloadUnusedAssets();
            HasLoad = false;
            HasDispose = true;
        }

        public virtual void Clean()
        {

        }

        public void UpdateData(AnchoringTarget target)
        {
            this.transform.localPosition = target.transform.position.ToUnity();
            this.transform.localRotation = target.transform.orientation.ToUnity();
            this.transform.localScale = target.transform.scale.ToUnity();
        }

        public AnchoringTarget GetAnchoringTarget()
        {
            return target;
        }
    }
}
