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

public class ImageAnchor : BaseAnchor
{
    [SerializeField] public AnimationType animationType;

    GameObject holder;
    ImageLoader loader;
    protected override void Start()
    {
        ImageLoader.OnFinishLoad += OnImageAgentFinish;
        base.Start();
    }
    protected override void OnDestroy()
    {
        StopAllCoroutines();
        base.OnDestroy();
        ImageLoader.OnFinishLoad -= OnImageAgentFinish;
    }

    private void OnImageAgentFinish()
    {
        StatusUpdate();
    }

    public override void Load(AnchoringTarget target)
    {
        this.target = target;

        GameObject resource = Resources.Load<GameObject>(Defines.PrefabResourceURL.ImageContent);
        holder = Instantiate<GameObject>(resource, transform);
        holder.SetActive(false);


        int enumInt = 0;
        int.TryParse(target.animation.ToString(), out enumInt);

        animationType = (AnimationType)enumInt;

        base.Load(target);

        var size = Mathf.Max(target.boundSize.x, target.boundSize.y, target.boundSize.z);
        //ILoadingTargetAlgorithm algorithm = new DistanceLoadAlgorithm();
        //algorithm = new DistanceLoadAlgorithm(size < 2 ? 25 : 18, size < 2 ? 50 :36);
        algorithm = new DistanceHeightAlgorithm(size < 2 ? 25 : 18, size < 2 ? 30 : 22);

    }

    private void OnFinishDownload(ResponseHelper response, string CacheFile, string url)
    {
        //save file to cache path
        SaveToCache(CacheFile, response.Data);
        SetImage(url);
    }

    void applyTexture(Texture2D texture)
    {
        if (texture == null) return;
        holder.transform.localScale = new Vector3((float)texture.width / texture.height, 1, 1);
        // texture.hideFlags = HideFlags.HideAndDontSave;

        //  var sprite = Sprite.Create( texture, new Rect(0, 0, texture.width, texture.height), new Vector2(texture.width/2, texture.height/2) );

        //set image to material
        Material material = Resources.Load<Material>(Defines.MaterialResourceURL.BannerMaterial);
        Material newMaterial = new Material(material);
        // newMaterial.mainTexture = sprite.texture;
        newMaterial.mainTexture = texture;

        //set material to quad
        holder.transform.GetChild(0).gameObject.GetComponent<MeshRenderer>().material = newMaterial;
        holder.transform.GetChild(1).gameObject.GetComponent<MeshRenderer>().material = newMaterial;

        if (shouldShow())
        {
            int enumInt = 0;
            int.TryParse(target.animation.ToString(), out enumInt);
            AnimationType type = (AnimationType)enumInt;
            holder.SetActive(true);
            if (type != 0)
            {
                AnimationClip teeterClip = Resources.Load<AnimationClip>($"Animations/{type}");
                teeterClip.legacy = true;

                // Ensure the GameObject has an Animation component
                Animation anim = gameObject.GetComponentInChildren<Animation>();
                if (anim != null)
                {
                    // Check if the clip was loaded successfully
                    if (teeterClip != null)
                    {
                        // Assign the clip to the Animation component
                        anim.AddClip(teeterClip, teeterClip.name);

                        // Play the animation
                        anim.Play(teeterClip.name);
                    }
                    else
                    {
                    }
                }
            }
        }

    }

    private bool shouldShow()
    {
        if (holder.transform.GetChild(1).gameObject.GetComponent<MeshRenderer>().material.mainTexture != null)
        {
            return true;
        }
        return false;
    }

    private void ShowImage()
    {
        if (shouldShow())
        {
            base.Show();
        }
    }
    Texture2D texture;
    private async void SetImage(string url)
    {
        loader = new ImageLoader();

        if (texture == null)
            texture = await loader.GetTexture(url);
        applyTexture(texture);
        //StartCoroutine(GetTexture(url));
    }

    public override void UnLoad()
    {
        if (HasLoad)
        {
            Destroy(texture);
            texture = null;
            HasLoad = false;
            base.UnLoad();
        }
    }

    protected virtual bool isNeedEnable()
    {
        return algorithm.IsNeedLoad(target, transform);
    }

    protected async override void StatusUpdate()
    {
        //if (State.Instance.ImageLoaderAgent > 0) return;
        if (string.IsNullOrEmpty(target.id)) return;
        bool needEnable = isNeedEnable();
        if (needEnable)
        {
            if (HasLoad)
            {
                ShowImage();
                return;
            }
            State.Instance.ImageLoaderAgent++;
            HasLoad = true;

            Davinci.get().load(target.media.url).setCached(true).withDownloadedAction((path) =>
            {
                var fileData = File.ReadAllBytes(path);
                var texture = new Texture2D(2, 2);
                texture.LoadImage(fileData); //..this will auto-resize the texture dimensions.
                applyTexture(texture);
            }).start();

        }
        else
        {
            UnLoad();
        }
        bool needDispose = algorithm.IsNeedDispose(target, transform);
        if (needDispose)
            Dispose();
        base.StatusUpdate();
    }
    public override void Dispose()
    {
        // should release texture
        if (HasDispose)
        {

        }
        //Destroy(holder);
        // base.DisPose();

    }
    public void OnSpawn()
    {
    }

    public void OnDespawn()
    {

    }
}
}
