﻿using System;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace TyphoonUI
{
    /// <summary>
    /// 拓展Image,传入source url 异步加载sprite
    /// </summary>
    [AddComponentMenu("Typhoon/UI/UrlImage", 11)]
    public class UrlImage : Image
    {
        [SerializeField] private string m_sourceUrl = "";          //资源路径
        [SerializeField] private Sprite m_transitionSprite = null; //加载时过渡的 sprite
        [SerializeField] private Sprite m_keepSprite = null;       //default sprite
        [SerializeField] private bool m_keepInExport = false;      //发布时保留

        //开始加载时触发
        public event Action OnLoadingStart;

        //加载完成时触发
        public event Action OnLoadingEnd;

        public string SourceUrl
        {
            get { return m_sourceUrl; }
            set
            {
                if (Application.isPlaying)
                {
                    _initialized = true;
                    //修改初始化状态
                    if (m_sourceUrl == value)
                    {
                        //资源路径相同，直接返回
                        return;
                    }

                    m_sourceUrl = value;
                    //更新sprite
                    LoadSourceSprite();
                }
                else
                {
#if UNITY_EDITOR
                    Debug.LogError("只支持在运行时使用");
#endif
                }
            }
        }

        public Sprite TransitionSprite => m_transitionSprite;
        public Sprite KeepSprite => m_keepSprite;
        public bool KeepInExport => m_keepInExport;

        private bool _initialized = false;

        //加载
        private AsyncOperationHandle<Sprite> _operationHandle;
        private ActionHandler<Sprite> _actionHandler;


        private void Awake()
        {
#if UNITY_EDITOR
            //运行过程中
            if (Application.isPlaying)
            {
                //清理override sprite
                overrideSprite = null;
            }
#endif
        }

        protected override void OnEnable()
        {
            base.OnEnable();
            if (Application.isPlaying)
            {
                if (!_initialized)
                {
                    _initialized = true;
                    //优先使用常驻的sprite
                    if (m_keepSprite != null)
                    {
                        sprite = m_keepSprite;
                    }
                    else
                    {
                        //加载sourceUrl
                        LoadSourceSprite();
                    }
                }
            }
        }

        protected override void OnDestroy()
        {
            base.OnDestroy();
            if (Application.isPlaying)
            {
                if (_operationHandle.IsValid())
                {
                    Addressables.Release(_operationHandle);
                }

                _actionHandler?.Clear();
            }

            //清空加载回调
            OnLoadingStart = null;
            OnLoadingEnd = null;
        }

        protected void LoadSourceSprite()
        {
            OnLoadingStart?.Invoke();
            if (_operationHandle.IsValid())
            {
                Addressables.Release(_operationHandle);
            }

            _actionHandler?.Clear();
            if (string.IsNullOrEmpty(m_sourceUrl))
            {
                sprite = null;
                return;
            }

            var handler = new ActionHandler<Sprite>((s) =>
            {
                sprite = s;
                OnLoadingEnd?.Invoke();
            });
            _actionHandler = handler;
            //设置加载过渡精灵
            sprite = m_transitionSprite;
            Addressables.LoadAssetAsync<Sprite>(m_sourceUrl).Completed += (res) => { handler?.Invoke(res.Result); };
        }


#if UNITY_EDITOR


        private bool InEditorMode => !EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying &&
                                     !EditorApplication.isCompiling;

        [SerializeField] private Sprite _previewSprite;
        public Sprite PreviewSprite => _previewSprite;

        protected override void OnValidate()
        {
            base.OnValidate();
            if (InEditorMode)
            {
                m_sourceUrl = _previewSprite == null ? string.Empty : AssetDatabase.GetAssetPath(_previewSprite);
                if (_previewSprite != null)
                {
                    overrideSprite = _previewSprite;
                }
                else
                {
                    if (m_transitionSprite != null)
                    {
                        overrideSprite = m_transitionSprite;
                    }
                }
            }
        }
#endif
    }
}