using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace XGame.Editor.Asset.Tools
{
    public class KReorderableList
    {
        private List<IReorderableItem> _itemLst;
        private ReorderableList _reorderableList;

        private IReorderableHandler _handler;

        public bool Draggable { get => _reorderableList.draggable; set => _reorderableList.draggable = value; }
        public float TotalHeight => _reorderableList.GetHeight();

        public KReorderableList(IReorderableHandler handler)
        {
            _handler = handler;
            _itemLst = new List<IReorderableItem>();
            Init();
        }
        private void Init()
        {
            var count = _handler.DataCount;
            //Debug.Log($"KReorderableList Init Count:{count}");
            for (int i = 0; i < count; i++)
            {
                var item = _handler.CreateItem(true, i);
                _itemLst.Add(item);
            }
            _reorderableList = new ReorderableList(_itemLst, _itemLst.GetType());
            _reorderableList.drawElementCallback += OnDrawElementCallback;
            _reorderableList.drawHeaderCallback += OnHeaderCallback;
            _reorderableList.elementHeightCallback += OnElementHeightCallback;
            _reorderableList.onAddCallback += OnAddElement;
            _reorderableList.onRemoveCallback += OnRemoveElement;
            _reorderableList.onCanAddCallback += OnCanAddElement;
            _reorderableList.onCanRemoveCallback += OnCanRemoveElement;
            _reorderableList.onReorderCallbackWithDetails += OnReorderCallbackWithDetails;

        }

        private void OnHeaderCallback(Rect rect)
        {
            var style = new GUIStyle(EditorStyles.label)
            {
                alignment = TextAnchor.MiddleLeft,
                fontStyle = FontStyle.BoldAndItalic,
                fontSize = 15
            };
            EditorGUI.LabelField(rect, new GUIContent(_handler.HeaderName, _handler.HeaderTooltip), style);
        }

        private void OnDrawElementCallback(Rect rect, int index, bool isActive, bool isFocused)
        {
            //Debug.Log($"OnDrawElementCallback: {rect}");
            _itemLst[index].OnGUI(rect);
            //SerializedProperty cur = _reorderables.serializedProperty.GetArrayElementAtIndex(index);
            //EditorGUI.PropertyField(rect, cur, new GUIContent($"{index}"));
        }

        private float OnElementHeightCallback(int index)
        {
            return _itemLst[index].Height;
            //SerializedProperty cur = _reorderables.serializedProperty.GetArrayElementAtIndex(index);
            //return EditorGUI.GetPropertyHeight(cur, new GUIContent($"{index}"));
        }
        private void OnAddElement(ReorderableList list)
        {
            // list.index指当前选中的item索引
            //var index = list.index;
            //Debug.Log($"OnAddElement Index:{index}");
            var item = _handler.CreateItem(false, _itemLst.Count);
            _itemLst.Add(item);
        }
        private void OnRemoveElement(ReorderableList list)
        {
            //Debug.Log($"OnRemoveElement Index:{list.index}");
            _itemLst.RemoveAt(list.index);
            _handler.RemoveItem(list.index);
        }

        private bool OnCanRemoveElement(ReorderableList list)
        {
            //Debug.Log($"IsCanRemove Index:{list.index}, Count:{_itemLst.Count}");
            return _handler.IsCanRemove(_itemLst.Count, list.index);
        }

        private bool OnCanAddElement(ReorderableList list)
        {
            //Debug.Log($"IsCanAdd Index:{list.index}, Count:{_itemLst.Count}");
            return _handler.IsCanAdd(_itemLst.Count, list.index);
        }
        private void OnReorderCallbackWithDetails(ReorderableList list, int oldIndex, int newIndex)
        {
            //Debug.Log($"OnReorderCallbackWithDetails old:{oldIndex} new:{newIndex} index:{list.index}");
            _handler.ItemChangedIndex(oldIndex, newIndex);
        }
        public TData[] GetItemDatas<TData>()
        {
            var count = _itemLst.Count;
            TData[] datas = new TData[count];
            for (int i = 0; i < count; i++)
            {
                datas[i] = (_itemLst[i] as IReorderableItemData<TData>).Data;
            }
            return datas;
        }
        public IReorderableItem[] GetItems()
        {
            return _itemLst.ToArray();
        }
        public void DoLayoutList()
        {
            _reorderableList?.DoLayoutList();
        }
        public void DoList(Rect rect)
        {
            _reorderableList?.DoList(rect);
        }
        public float GetHeight()
        {
            return _reorderableList?.GetHeight() ?? 0;
        }
        public void Dispose()
        {
            foreach (var item in _itemLst)
            {
                (item as IDisposable)?.Dispose();
            }
            _itemLst.Clear();
            _handler = null;
            if (_reorderableList != null)
            {
                _reorderableList.drawElementCallback -= OnDrawElementCallback;
                _reorderableList.drawHeaderCallback -= OnHeaderCallback;
                _reorderableList.elementHeightCallback -= OnElementHeightCallback;
                _reorderableList.onAddCallback -= OnAddElement;
                _reorderableList.onRemoveCallback -= OnRemoveElement;
                _reorderableList.onCanAddCallback -= OnCanAddElement;
                _reorderableList.onCanRemoveCallback -= OnCanRemoveElement;
                _reorderableList = null;
            }
        }

    }
}