using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;

public class gridView : MonoBehaviour
{
    public string perfabPath = "perfabs/testGridItem";
    public List<String> perfabPaths = new List<string>();
    private bool isFirstSetData = true;
    public bool LockCellWidthEqHeight = true;//锁定宽==高
    void Start()
    {
        if(perfabPaths.Count == 0)
        {
            perfabPaths.Add(perfabPath);
        }
    }
    void checkFirstSetData(bool useVec)
    {
        if(isFirstSetData)
        {
            isFirstSetData = false;
            GameObject gameObjectContext = GetComponent<ScrollRect>().content.gameObject;
            var gridLayout = gameObjectContext.GetComponent<GridLayoutGroup>();
            if(gridLayout != null)
            {
                Vector2 temp;
                utilsTools.DeviceAdaptationSize(gridLayout.cellSize, out temp);
                if (LockCellWidthEqHeight)
                {
                    if (useVec)
                    {
                        temp.y = temp.x;
                    }
                    else
                    {
                        temp.x = temp.y;
                    }
                }
                gridLayout.cellSize = temp;
                Vector2 lt = new Vector2(gridLayout.padding.left, gridLayout.padding.top);
                Vector2 rd = new Vector2(gridLayout.padding.right, gridLayout.padding.bottom);
                utilsTools.DeviceAdaptationSize(lt, out temp);
                gridLayout.padding.left = (int)temp.x;
                gridLayout.padding.top = (int)temp.y;
                utilsTools.DeviceAdaptationSize(rd, out temp);
                gridLayout.padding.left = (int)temp.x;
                gridLayout.padding.bottom = (int)temp.y;
                utilsTools.DeviceAdaptationSize(gridLayout.spacing, out temp);
                gridLayout.spacing = temp;
            }
        }
    }
    public GameObject getObjectById(int id)
    {
        GameObject gameObjectContext = this.gameObject.GetComponent<ScrollRect>().content.gameObject;
        string name = $"auto_title_{id}";
        var transfromitem = gameObjectContext.transform.Find(name);
        if (transfromitem == null)
        {
            return null;
        }
        return transfromitem.gameObject;
    }
    virtual public Vector2 getOffset()
    {
        var gameObjectContext = GetComponent<ScrollRect>();
        return gameObjectContext.normalizedPosition;
    }
    virtual public void setOffset(Vector2 vector2)
    {
        var gameObjectContext = GetComponent<ScrollRect>();
        gameObjectContext.normalizedPosition = vector2;
    }
    virtual public Vector2 getCellSize()
    {
        Vector2 vector2 = new Vector2();
        GameObject gameObjectContext = GetComponent<ScrollRect>().content.gameObject;
        var gridLayout = gameObjectContext.GetComponent<GridLayoutGroup>();
        if(gridLayout != null )
        {
            vector2 = gridLayout.cellSize;
        }
        return vector2;
    }
    virtual public void setData(int size,gradViewBack back,bool useVec = true, GetGradViewInfo getGradViewInfo = null)
    {
        checkFirstSetData(useVec);
        if (perfabPaths.Count == 0)
        {
            perfabPaths.Add(perfabPath);
        }
        GameObject gameObjectContext = GetComponent<ScrollRect>().content.gameObject;
        var gridLayout = gameObjectContext.GetComponent<GridLayoutGroup>();
        string firstKey = "";
        Dictionary<string, Tuple<string,GameObject>> dicts = new Dictionary<string, Tuple<string, GameObject>>();
        foreach (var item in perfabPaths)
        {
            string[] names = item.Split("/");
            string key = names[names.Length - 1];
            if(firstKey.Equals(""))
            {
                firstKey = key;
            }
            dicts.Add(key, new Tuple<string, GameObject>(item, Resources.Load<GameObject>(item)));
        }
        var rectTransform = gameObjectContext.GetComponent<RectTransform>();
        int count = gridLayout.constraintCount;

        List<Tuple<string, float>> infos = new List<Tuple<string, float>>();
        float coutPixel = 0;
        if (getGradViewInfo == null)
        {
            if (useVec)
            {
                coutPixel = Mathf.Ceil(size/count) * gridLayout.cellSize.y;
            }
            else
                coutPixel = Mathf.Ceil(size / count) * gridLayout.cellSize.x;
        }
        else {
            string itemKey = "";
            float itemHeight = 0;
            for (int i = 0; i < size; i++)
            {
                getGradViewInfo(i, ref itemKey, ref itemHeight);
                if(itemHeight < 1 || dicts.ContainsKey(itemKey) == false)
                {
                    Debug.LogError("param error " + itemKey + "  height " + itemHeight.ToSafeString());
                    return ;
                }
                coutPixel = coutPixel + itemHeight;
                infos.Add(new Tuple<string, float>(itemKey, itemHeight));
            }
        }
        if (useVec)
        {
            float h = GetComponent<RectTransform>().rect.height;
            float spacingLen = 0;
            if (size > count)
            {
                spacingLen = gridLayout.spacing.y * (Mathf.Ceil(size / count) - 1);
            }
            float height = spacingLen + coutPixel + gridLayout.padding.top + gridLayout.padding.bottom;
            if (height > h)
            {
                h = height - h;
            }
            rectTransform.sizeDelta = new Vector2(rectTransform.sizeDelta.x, h);
        }
        else
        {
            float w = GetComponent<RectTransform>().rect.width;
            float spacingLen = 0;
            if (size > count)
            {
                spacingLen = gridLayout.spacing.x * (Mathf.Ceil(size / count) - 1);
            }
            float width = spacingLen + coutPixel + gridLayout.padding.left + gridLayout.padding.right;
            if (width > w)
            {
                w = width - w;
            }
            rectTransform.sizeDelta = new Vector2(w,rectTransform.sizeDelta.y);
        }
        Vector3 vector3 = new Vector3();
        utilsTools.setGDataByKey("listViewTempCellSize", new Vector2(gridLayout.cellSize.x, gridLayout.cellSize.y));
        for (int i = 0; i < size; i++)
        {
            string name = $"auto_title_{i}";
            var childTransform = gameObjectContext.transform.Find(name);
            string newItemType = firstKey;
            
            if(infos.Count > 0)
            {
                newItemType = infos[i].Item1;
            }
            GameObject itemObject = null;
            if (childTransform != null)
            {
                itemObject = childTransform.gameObject;
                string oldItemType = "";
                if(true == utilsTools.getUserData<string>(itemObject, "scrollViewItemType",out oldItemType, "") && newItemType.Equals(oldItemType))
                {
                    back(itemObject, i, ListViewBackTypeEnum.update);
                    continue;
                }
                childTransform.SetParent(null);
                GameObject.Destroy(childTransform.gameObject);
            }
            itemObject = Instantiate(dicts[newItemType].Item2);
            utilsTools.setUserData(itemObject, "scrollViewItemType", "");
            itemObject.name = name;
            itemObject.transform.SetParent(gameObjectContext.transform);
            back(itemObject, i, ListViewBackTypeEnum.create);
        }
        for (int i = size; i < 100000000; i++)
        {
            string name = $"auto_title_{i}";
            var childTransform = gameObjectContext.transform.Find(name);
            if (childTransform == null)
            {
                break;
            }
            childTransform.SetParent(null);
            GameObject.Destroy(childTransform.gameObject);
        }
    }
    //只支持一个预制体
    virtual public void setDataNoGrid(int size,float widthItem,float heightItem,float interval,gradViewBack back, bool useVec = true, GetGradViewInfo getGradViewInfo = null,float offset1 = 0.0f)
    {
        Vector2 shipei = new Vector2 (widthItem,heightItem);
        utilsTools.DeviceAdaptationSize(ref shipei);
        widthItem = shipei.x;
        heightItem = shipei.y;
        shipei.x = interval;
        shipei.y = offset1;
        utilsTools.DeviceAdaptationSize(ref shipei);
        interval = shipei.x;
        offset1 = shipei.y; 
        if (perfabPaths.Count == 0)
        {
            perfabPaths.Add(perfabPath);
        }
        GameObject gameObjectContext = this.gameObject.GetComponent<ScrollRect>().content.gameObject;
        string firstKey = "";
        Dictionary<string, Tuple<string, GameObject>> dicts = new Dictionary<string, Tuple<string, GameObject>>();
        foreach (var item in perfabPaths)
        {
            string[] names = item.Split("/");
            string key = names[names.Length - 1];
            if (firstKey.Equals(""))
            {
                firstKey = key;
            }
            dicts.Add(key, new Tuple<string, GameObject>(item, Resources.Load<GameObject>(item)));
        }
        var rectTransform = gameObjectContext.GetComponent<RectTransform>();
        

        List<Tuple<string, float>> infos = new List<Tuple<string, float>>();
        float coutPixel = 0;
        if (getGradViewInfo == null)
        {
            if (useVec)
            {
                coutPixel = size * heightItem;
            }
            else
                coutPixel = size * widthItem;
        }
        else
        {
            string itemKey = "";
            float itemHeight = 0;
            for (int i = 0; i < size; i++)
            {
                getGradViewInfo(i, ref itemKey, ref itemHeight);
                if (itemHeight < 1 || dicts.ContainsKey(itemKey) == false)
                {
                    Debug.LogError("param error " + itemKey + "  height " + itemHeight.ToSafeString());
                    return;
                }
                coutPixel = coutPixel + itemHeight;
                infos.Add(new Tuple<string, float>(itemKey, itemHeight));
            }
        }
        float startX = 0;
        float startY = 0;
        Vector3 vector3 = new Vector3(0, -120, 1);
        RectTransform rectTransform1 = GetComponent<RectTransform>();
        if (useVec)
        {
            float h = rectTransform1.rect.y;
            startY = 0 - h / 2 + heightItem / 2 - (heightItem / 2 + interval / 2);
            vector3.x = 0 - rectTransform.sizeDelta.x / 2 - offset1;
            float spacingLen =interval  * (size - 1);
            float height = spacingLen + coutPixel;
            if (height > h)
            {
                h = height;
            }
            rectTransform.sizeDelta = new Vector2(rectTransform.sizeDelta.x, h);
        }
        else
        {
            float w = rectTransform1.rect.width;
            vector3.y = 0 - rectTransform.sizeDelta.y / 2 - offset1;//0 - rectTransform.sizeDelta.y / 2 - offset1;
            startX = 0 - w / 2 + widthItem / 2 - (widthItem / 2 + interval / 2);
            float spacingLen = interval * (size - 1);
            float width = spacingLen + coutPixel;
            if (width > w)
            {
                w = width - w;
            }
            rectTransform.sizeDelta = new Vector2(w, rectTransform.sizeDelta.y);
        }
        utilsTools.setGDataByKey("listViewTempCellSize", new Vector2(widthItem,heightItem));
        utilsTools.setGDataByKey("listViewContextCellSize", rectTransform.sizeDelta);
        Vector3 vector31 = new Vector3();
        Quaternion quaternion = new Quaternion();
        for (int i = 0; i < size; i++)
        {
            string name = $"auto_title_{i}";
            var childTransform = gameObjectContext.transform.Find(name);
            string newItemType = firstKey;

            if (infos.Count > 0)
            {
                newItemType = infos[i].Item1;
            }
            GameObject itemObject = null;
            if (useVec)
            {
                vector3.y = vector3.y + heightItem / 2 + interval / 2;
            }
            else
            {
                vector3.x = vector3.x + widthItem / 2 + interval / 2;
            }
            if (childTransform != null)
            {
                itemObject = childTransform.gameObject;
                string oldItemType = "";
                if (true == utilsTools.getUserData<string>(itemObject, "scrollViewItemType", out oldItemType, "") && newItemType.Equals(oldItemType))
                {
                    itemObject.transform.GetLocalPositionAndRotation(out vector31, out quaternion);
                    itemObject.transform.SetLocalPositionAndRotation(vector3, quaternion);
                    back(itemObject, i, ListViewBackTypeEnum.update);
                    if(useVec)
                        vector3.y = vector3.y + heightItem / 2 + interval / 2;
                    else
                        vector3.x = vector3.x + widthItem / 2 + interval / 2; 
                    continue;
                }
                childTransform.SetParent(null);
                GameObject.Destroy(childTransform.gameObject);
            }
            itemObject = Instantiate(dicts[newItemType].Item2);
            itemObject.name = name;
            utilsTools.setUserData(itemObject, "scrollViewItemType", newItemType);
            itemObject.transform.SetParent(gameObjectContext.transform);
            itemObject.transform.GetLocalPositionAndRotation(out vector31, out quaternion);
            itemObject.transform.SetLocalPositionAndRotation(vector3, quaternion);
            back(itemObject, i, ListViewBackTypeEnum.create);
            if (useVec)
                vector3.y = vector3.y + heightItem / 2 + interval / 2;
            else
                vector3.x = vector3.x + widthItem / 2 + interval / 2;
        }
        for (int i = size; i < 100000000; i++)
        {
            string name = $"auto_title_{i}";
            var childTransform = gameObjectContext.transform.Find(name);
            if (childTransform == null)
            {
                break;
            }
            childTransform.SetParent(null);
            GameObject.Destroy(childTransform.gameObject);
        }
    }
}
