using System;
using System.Collections.Generic;
using UnityEngine;

namespace FairyGUI
{
    public interface IGListItemHandle
    {
        /// <summary>
        /// 激活
        /// </summary>
        void Enable(object intent = null);
        /// <summary>
        /// 隐藏
        /// </summary>
        void Disable();
        /// <summary>
        /// 当前索引
        /// </summary>
        int ItemIndex { get;}
        void OnRefresh(int index, object data);
    }
    public enum EGListType
    {
        /// <summary>
        /// 默认，实列表
        /// </summary>
        None = 0,
        /// <summary>
        /// 虚拟列表
        /// </summary>
        Virtual,
        /// <summary>
        /// 循环虚拟列表
        /// </summary>
        VirtualAndLoop,
    }
    public partial class GList
    {
        private Dictionary<GObject, IGListItemHandle> _itemHandleMap;
        /// <summary>
        /// ListItem的类型
        /// 业务不要用
        /// </summary>
        private Type _itemViewType;
        private Func<Type, GObject, IGListItemHandle> _listItemCreator;
        public void Init(Type itemViewType, Func<Type, GObject, IGListItemHandle> listItemCreator)
        {
            _itemViewType = itemViewType;
            _listItemCreator = listItemCreator;
            _itemHandleMap = new Dictionary<GObject, IGListItemHandle>();
        }
        private EGListType _listType = EGListType.None;
        public EGListType ListType
        {
            get => _listType;
            set
            {
                if (_listType == value)
                {
                    return;
                }
                _listType = value;
                switch (value)
                {
                    case EGListType.Virtual:
                        SetVirtual();
                        break;
                    case EGListType.VirtualAndLoop:
                        SetVirtualAndLoop();
                        break;
                }
            }
        }
        private Action<int> _itemClickEvent;
        /// <summary>
        /// Item对象的选中事件
        /// 返回选中Item在列表的逻辑索引
        /// </summary>
        public Action<int> ItemClickEvent
        {
            get => _itemClickEvent;
            set
            {
                _itemClickEvent = value;
                onClickItem.Remove(__OnClickItem);
                if (value != null)
                {
                    onClickItem.Add(__OnClickItem);
                }
            }
        }
        public void BindDatas<TData>(IList<TData> datas)
        {
            itemRenderer = (index, gObj) =>
            {
                try
                {
                    if (TryGetHandle(gObj, out var itemHandle))
                    {
                        itemHandle.OnRefresh(index, datas[index]);
                    }
                    else
                    {
                        Debug.LogError($"GList<{displayObject.gameObject.name}> 刷新错误. Index:{index}");
                    }
                }
                catch (Exception ex)
                {
                    Debug.LogException(ex);
                }
            };
            numItems = datas.Count;
        }
        private bool TryGetHandle(GObject item, out IGListItemHandle handle)
        {
            if (_itemHandleMap != null && _itemHandleMap.TryGetValue(item, out handle))
            {
                return true;
            }
            handle = default;
            return false;
        }
        private void OnAddChild(GObject child)
        {
            //构造listItem
            if (_itemHandleMap?.TryGetValue(child, out var itemHandle) ?? false)
            {
                itemHandle.Enable();
            }
            else if (_listItemCreator != null)
            {
                itemHandle = _listItemCreator.Invoke(_itemViewType, child);
                if (itemHandle != null)
                {
                    _itemHandleMap.Add(child, itemHandle);
                    itemHandle.Enable();
                }
                else
                    Debug.LogError($"IGListItemHandle create failed. Type:{_itemViewType}");
            }
            //Debug.LogError($"GList OnAddChild. Name:${child.displayObject.gameObject.GetInstanceID()}");
        }
        private void OnRemoveChild(GObject child, bool dispose)
        {
            //Debug.Log($"GList OnRemoveChild. Name:${displayObject.gameObject.name}");
            if (_itemHandleMap == null) return;
            if (_itemHandleMap.TryGetValue(child, out var itemHandle))
            {
                itemHandle.Disable();
                if (dispose)
                {
                    _itemHandleMap.Remove(child);
                    (itemHandle as IDisposable)?.Dispose();
                }
            }
        }
        private void OnDispose()
        {
            _itemClickEvent = null;
            _itemViewType = null;
            _listItemCreator = null;
            if (_itemHandleMap != null)
            {
                foreach (var itemHandle in _itemHandleMap.Values)
                {
                    itemHandle?.Disable();
                    (itemHandle as IDisposable)?.Dispose();
                }
                _itemHandleMap.Clear();
            }
        }
        private void __OnClickItem(EventContext context)
        {
            if (TryGetHandle((GObject)context.data, out var handle))
            {
                ItemClickEvent?.Invoke(handle.ItemIndex);
            }
            else
            {
                Debug.LogError($"GList<{displayObject.gameObject.name}> onClickItem Error: 没有初始化ItemHandler.");
            }
        }
    }
}
