using SC.XR.Unity;
using SC.XR.Unity.Module_InputSystem;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class SlideList : BaseList, IDragHandler, IPointerEnterHandler, IPointerExitHandler, IPointerUpHandler, IPointerDownHandler
{
    [HideInInspector]
    private List<Vector3> posList;
    public float rowSpacing;
    public float columnSpacing; 
    [HideInInspector]
    private int maxRow;
    [HideInInspector]
    private int maxColumn;
    [HideInInspector]
    private float maxRowSpacing;
    [HideInInspector]
    private float maxColumnSpacing;
    [HideInInspector]
    private int startItem = 0;
    [HideInInspector]
    private int endItem = 0;
    public SCSlider3D slider3D;
    public bool isSlideX=false;
    public override void initList(List<BaseConfig> configs)
    {
        startItem = 0;
        endItem = Row * Column;
        posList = new List<Vector3>();
        base.initList(configs);
        

            for (int i = 0; i < Views.Count; i++)
            {
                Views[i].transform.localPosition = new Vector3(((i) % Row) * rowSpacing, -((i) / Row) * columnSpacing, 0);
                posList.Add(Views[i].transform.localPosition);
        }
        maxRow = (Views.Count - 1) / Row + 1;
        maxColumn = (Views.Count - 1) / Column + 1;
        maxRowSpacing = ((maxColumn - 1) * rowSpacing + (rowSpacing / 2));
        maxColumnSpacing = ((maxRow - 1) * columnSpacing + (columnSpacing / 2));
        // StartCoroutine(moveCoroutine());

        slider3D.onValueChanged.AddListener(valueChanged);
    }

    private void valueChanged(float arg0)
    {
        setProgress(arg0);
    }

    bool checkColumnMax(int i, int r)
    {
        if ((((i) / this.Row) + 1) == r)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    List<Vector3> v3;
    void MoveItem(float f, bool ischange = true)
    {
        if (isSlideX)
        {
            if (Mathf.Abs(f) > rowSpacing)
            {
                if (f > 0)
                {
                    f = rowSpacing * 0.9f;
                }
                else
                {
                    f = -rowSpacing * 0.9f;
                }
            }
        }
        else
        {

            if (Mathf.Abs(f) > columnSpacing)
            {
                if (f > 0)
                {
                    f = columnSpacing * 0.9f;
                }
                else
                {
                    f = -columnSpacing * 0.9f;
                }
            }
        }
        v3 = new List<Vector3>();
        for (int j = 0; j < Views.Count; j++)
        {
            v3.Add(Views[j].transform.localPosition);
        }
        bool isDown = false;
        bool isUp = false;
        List<int> listIndex = new List<int>(); ;

        float downf = 0;
        float upf = 0;
        //  bool isshow =
        for (int i = 0; i < Views.Count; i++)
        {
            if (isSlideX)
            {
                Views[i].transform.localPosition = new Vector3(Views[i].transform.localPosition.x - f, Views[i].transform.localPosition.y , Views[i].transform.localPosition.z);
            }else
            {
                Views[i].transform.localPosition = new Vector3(Views[i].transform.localPosition.x, Views[i].transform.localPosition.y - f, Views[i].transform.localPosition.z);
            }
            int type = checkBorder(i);
            switch (type)
            {
                //下边界
                case 1:
                    if (isSlideX)
                    {
                        isDown = true;
                        Views[i].gameObject.SetActive(false);
                        Views[i].isShow = false;
                   //     upf = Views[i].transform.localPosition.x + rowSpacing / 2f;
                        showPretRow(i);
                    }
                    else
                    {
                        isDown = true;
                        Views[i].gameObject.SetActive(false);
                        Views[i].isShow = false;
                  //      upf = Views[i].transform.localPosition.y - columnSpacing / 2f;
                        showPretRow(i);
                    }
                    break;
                //上边界
                case 2:
                    if (isSlideX)
                    {
                        isUp = true;
                        Views[i].gameObject.SetActive(false);
                        Views[i].isShow = false;
                     //   downf = -Views[i].transform.localPosition.x + maxRowSpacing;
                        showNextRow(i);
                    }
                    else
                    {
                        isUp = true;
                        Views[i].gameObject.SetActive(false);
                        Views[i].isShow = false;
                      //  downf = -Views[i].transform.localPosition.y - maxColumnSpacing;
                        showNextRow(i);
                    }
                    break;
                case 0:
                    //  showItem(i);
                    Views[i].isShow = true;
                    Views[i].gameObject.SetActive(true);
                    break;

            }
        }
     //   Debug.Log("移动"+f);
        if (isDown)
        {
            if (isSlideX)
            {
                changeList(false, Column); 
                changeRCount(rCount - 1);
                MoveItem(downf);
            }else
            {

                changeList(false, Row);
                changeRCount(rCount - 1);
                MoveItem(downf);
            }
        }
        else if (isUp)
        {
            if (isSlideX)
            {
                changeList(true, Column);
                changeRCount(rCount + 1);
                MoveItem(upf);
            }
            else
            {
                changeList(true, Row);
                changeRCount(rCount + 1);
                MoveItem(upf);
            }
        }
        if (isSlideX)
        {
            showItems(startItem + Column * rCount, endItem + Column * rCount);
        }else
        {
            showItems(startItem + Row * rCount, endItem + Row * rCount);

        }

    }

    void changeList(bool isADD, int chaRow)
    {
        if(isSlideX)
        {
            if (isADD)
            {
                List<int> addIndexA = new List<int>();
                List<int> addIndexB = new List<int>();
                List<BaseView> bv = new List<BaseView>();
                for (int i = 0; i < Views.Count; i++)
                {
                    if (i % Row == 0)
                    {
                        addIndexB.Add(i);
                    }
                    else
                    {
                        bv.Add(Views[i]);

                    }
                }
              //  Debug.Log("更换前的位置");
                for (int i = 0; i < Views.Count; i++)
                {
              //      Debug.Log("View==》" + i + "==>" + Views[i].Index);
                }
                List<BaseView> bv3 = new List<BaseView>();
                for (int i = 0; i < chaRow; i++)
                {
                    bv3.Add(Views[addIndexB[i]]);
                }
                int b3Ct = 0;
                for (int i = 0; i < Views.Count; i++)
                {
                    if (i % Row == (Row-1))
                    {
                        bv.Insert(i , bv3[b3Ct]);
                        b3Ct++;
                    }
                }
                Views = bv;
                //   Debug.Log("更换后的位置");
                for (int i = 0; i < Views.Count; i++)
                {
               //     Debug.Log("View==》" + i + "==>" + Views[i].Index);
                }
            }
            else
            {

                List<int> addIndexA = new List<int>();
                List<BaseView> bv = new List<BaseView>();
                for (int i = 0; i < Views.Count; i++)
                {
                    if (i % Row == (Row-1))
                    {
                        addIndexA.Add(i);
                    }else
                    {
                        bv.Add(Views[i]);

                    }
                }

            //    Debug.Log("更换前的位置");
                for (int i = 0; i < Views.Count; i++)
                {
             //       Debug.Log("View==》" + i + "==>" + Views[i].Index);
                }
                List<BaseView> bv2 = new List<BaseView>();
                List<BaseView> bv3 = new List<BaseView>();
                for (int i = 0; i < chaRow; i++)
                {
                    bv2.Add(Views[addIndexA[i]]);
                }
                int b3Ct = 0;
                for (int i = 0; i < Views.Count; i++)
                {
                    if (i % Row == 0)
                    {
                        bv.Insert(i , bv2[b3Ct]);
                        b3Ct++;
                    }
                }
                Views = bv;
                //    Debug.Log("更换后的位置");
                for (int i = 0; i < Views.Count; i++)
                {
                  //  Debug.Log("View==》"+i+"==>"+Views[i].Index);
                }
            }
        }else
        {
            if (isADD)
            {
                for (int i = 0; i < chaRow; i++)
                {
                    Views.Add(Views[i]);
                }
                for (int i = 0; i < chaRow; i++)
                {
                    Views.RemoveAt(0);
                }
            }
            else
            {
                for (int i = 0; i < chaRow; i++)
                {
                    Views.Insert(i, Views[Views.Count - chaRow + i]);
                }
                for (int i = 0; i < chaRow; i++)
                {
                    Views.RemoveAt(Views.Count - 1);
                }
            }
        }
    }

    int RowCount = 0;

    //显示下一行
    void showNextRow(int i)
    {
        if (isSlideX)
        {
            int zuxiao = 0;
            float max = -999999;
            for (int j = 0; j < Views.Count; j++)
            {
                if (max < v3[j].x)
                {
                    max = v3[j].x;
                     zuxiao = j;
                }
            }
         //   Debug.Log(i + "移动到最大的" + zuxiao + "坐标==》" + (max + rowSpacing));
            Views[i].transform.localPosition = new Vector3(max + rowSpacing, Views[i].transform.localPosition.y, Views[i].transform.localPosition.z);

        }
        else
        {
            float max = 999999;
            for (int j = 0; j < Views.Count; j++)
            {
                if (max > v3[j].y)
                {
                    max = v3[j].y;
                }
            }
            Views[i].transform.localPosition = new Vector3(Views[i].transform.localPosition.x, max - columnSpacing, Views[i].transform.localPosition.z);

        }
    }

    //显示上一行
    void showPretRow(int i)
    {
        if (isSlideX)
        {
            int zuxiao=0;
            float min = 999999;
            for (int j = 0; j < Views.Count; j++)
            {
                if (min > v3[j].x)
                {
                    min = v3[j].x;
                    zuxiao = j;
                }
            }
         //   Debug.Log(i+"移动到最小的"+ zuxiao+"坐标==》"+ (min + rowSpacing));
            //  min=  0 + (0 - v3[0].y)+ columnSpacing;
            Views[i].transform.localPosition = new Vector3(min - rowSpacing, Views[i].transform.localPosition.y, Views[i].transform.localPosition.z);


        }
        else
        {
            float min = -999999;
            for (int j = 0; j < Views.Count; j++)
            {
                if (min < v3[j].y)
                {
                    min = v3[j].y;
                }
            }
            //  min=  0 + (0 - v3[0].y)+ columnSpacing;
            Views[i].transform.localPosition = new Vector3(Views[i].transform.localPosition.x, min + columnSpacing, Views[i].transform.localPosition.z);

        }
    }

            //判断是否超出边界
            int checkBorder(int i)
            {
                if (isSlideX)
                {
                    if (Views[i].transform.localPosition.x > maxRowSpacing)
            {
          //      Debug.Log(i + "x坐标=1=》" + Views[i].transform.localPosition.x);
                return 1;
                    }
                    else if (Views[i].transform.localPosition.x < -(rowSpacing / 2f))
                    {
          //      Debug.Log(i+"x坐标=2=》"+ Views[i].transform.localPosition.x);
                        return 2;
                    }
                    else
                    {
                        return 0;
                    }
                }
                else
                {
                    if (-Views[i].transform.localPosition.y > maxColumnSpacing)
                    {
                        return 1;
                    }
                    else if (Views[i].transform.localPosition.y > (columnSpacing / 2f))
                    {
                        return 2;
                    }
                    else
                    {
                        return 0;
                    }

                }
            }

    private Vector3 startPos;
    private Vector3 startItemPos;
    private float TimeDrag = 0;
    private Vector3 DragPos;
    private float dragFloat;
    private float jiasudu;
    private float speedTime = 0;
    private bool isJiasudu = false;
    private float oldNum = 0;
    public virtual void OnDrag(PointerEventData eventData)
    {
        SCPointEventData sCPointEventData = eventData as SCPointEventData;
        float num = 0;
        Vector3 pos3D = this.transform.TransformPoint(sCPointEventData.Position3D) / this.transform.localScale.x;

        if (isSlideX)
        {
            Vector3 a= GSXRManager.Instance.leftCamera.WorldToScreenPoint(startScreenV3);
            Vector3 b = GSXRManager.Instance.leftCamera.WorldToScreenPoint(sCPointEventData.Position3D);
            // pos3D = sCPointEventData.Position3D / this.transform.localScale.x;
            num = (startPos.x - pos3D.x);
            num = Vector3.Cross(this.transform.forward, pos3D).y - oldNum;
            num = (a - b).x;
            oldNum = Vector3.Cross(this.transform.forward, pos3D).y;
    
        }
        else
        {
            num = (startPos.y - pos3D.y) * 5;
        }
        //Debug.Log("num====>"+num);
        startPos = pos3D;
        startScreenV3 = sCPointEventData.Position3D;
        TimeDrag = TimeDrag + Time.deltaTime;
        if (TimeDrag > 1f)
        {
            DragPos = pos3D;
            TimeDrag = 0;
        }

        int hz = ((maxRowItemCount - Column));
        float cdz = columnSpacing * hz;
        float Prog = 0;
        if (isSlideX)
        {
            Prog = getValue() + (num / hz)/100;
        } else
        {
            Prog = getValue() + (num / hz) * 2;

        }
        if (Prog > 0)
        {

            if (isSlideX)
            {
                changeValue(Prog);
            }
            else
            {
                changeValue(Prog);

            }
        }

        speedTime = speedTime + Time.deltaTime;
        if (speedTime > 0.3f)
        {
            speedTime = 0;
            jiasudu = 0;
        }
        else
        {
            if (isSlideX)
            {
                jiasudu = jiasudu + (num / hz) /100;
            }else
            {

                jiasudu = jiasudu + (num / hz) * 2;
            }
        }

        
        //float a = float.Parse(num.ToString("F2"));
        //    Debug.Log("");
        // if((num / 2))


    }
    private Vector3 startScreenV3;
    public virtual void OnPointerDown(PointerEventData eventData)
    {
        SCPointEventData sCPointEventData = eventData as SCPointEventData;
        startPos = this.transform.TransformPoint(sCPointEventData.Position3D)/this.transform.localScale.x;
        startScreenV3 = sCPointEventData.Position3D;
        startItemPos = this.transform.localPosition;
        DragPos = sCPointEventData.Position3D;
        //  MoveItem(1f);
    }

    public virtual void OnPointerEnter(PointerEventData eventData)
    {
    }

    public virtual void OnPointerExit(PointerEventData eventData)
    {
    }

    public virtual void OnPointerUp(PointerEventData eventData)
    {
        SCPointEventData sCPointEventData = eventData as SCPointEventData;
        if(isSlideX)
        {
            dragFloat = (DragPos.x - this.transform.TransformPoint(sCPointEventData.Position3D).x);

        }
        else
        {
            dragFloat = (DragPos.y - this.transform.TransformPoint(sCPointEventData.Position3D).y);

        }

        if (jiasudu != 0)
            isJiasudu = true;
        //    MoveUpEnd();
    }

    void changeRCount(int count)
    {
        rCount = count;
    }

    public virtual void Update()
    {
        if (isJiasudu)
        {
            speedTime = speedTime + Time.deltaTime;
            if (speedTime > 2)
            {
                speedTime = 0;
                isJiasudu = false;
              //  fixedItems();
            }
            jiasudu = jiasudu / 1.05f;
          //  if (Mathf.Abs(-jiasudu / 2) <= 0.1f)
          //  {
          //      speedTime = 0;
          //      isJiasudu = false;
             //   fixedItems();
         //   }
            changeValue((jiasudu+getValue()));
           // MoveItem(-jiasudu / 3);
        }
    }

    private void changeMaxRowItemCount()
    {
        maxRowItemCount = ((this.configs.Count - 1) / Row + 1);
    }
    private void changeMaxColumnItemCount()
    {
        maxColumItemCount = ((this.configs.Count-1) / Column + 1);
    }
    public override void updateConfig(List<BaseConfig> c)
    {
        if(isSlideX)
        {
            if (this.configs.Count < c.Count)
            {
                configs = new List<BaseConfig>();
                c.ForEach(i => configs.Add(i));
                changeMaxColumnItemCount();
                if (((Row * Column) > (Row * maxColumItemCount)))
                {
                    changeValue(0);
                    setProgress(0);
                }
                else
                {
                    changeValue(1);
                    setProgress(1);
                }

            }
            else if (Row * rCount > (Row * maxColumItemCount - Row * Column + 1) && (Row * Column < Row * maxColumItemCount))
            {
                configs = new List<BaseConfig>();
                c.ForEach(i => configs.Add(i));
                changeMaxColumnItemCount();

                changeValue(1);
                setProgress(1);
            }
            else
            {
                configs = new List<BaseConfig>();
                c.ForEach(i => configs.Add(i));
                changeMaxColumnItemCount();
                showItems(startItem + Column * rCount, endItem + Column * rCount, true);
            }
        }
        else
        {
            if (this.configs.Count < c.Count)
            {
                configs = new List<BaseConfig>();
                c.ForEach(i => configs.Add(i));
                changeMaxRowItemCount();
                if (((Row * Column) > (Row * maxRowItemCount)))
                {
                    changeValue(0);
                    setProgress(0);
                }
                else
                {
                    changeValue(1);
                    setProgress(1);
                }

            }
            else if (Row * rCount > (Row * maxRowItemCount - Row * Column + 1) && (Row * Column < Row * maxRowItemCount))
            {
                configs = new List<BaseConfig>();
                c.ForEach(i => configs.Add(i));
                changeMaxRowItemCount();

                changeValue(1);
                setProgress(1);
            }
            else
            {
                configs = new List<BaseConfig>();
                c.ForEach(i => configs.Add(i));
                changeMaxRowItemCount();
                showItems(startItem + Row * rCount, endItem + Row * rCount, true);
            }
        }
    }
    private bool checkRCount(int r)
    {
        return r == rCount;
    }

    public virtual float getProgress()
    {

        if (isSlideX)
        {
            int hm = ((rCount));
            int hz = ((maxColumItemCount - Row));
            float cdm = (rowSpacing) * hm + (0 - Views[0].transform.localPosition.x);
            float cdz = rowSpacing * hz;
            if (cdz == 0)
            {
                return -1;
            }
            float proNum = cdm / cdz;
            return proNum;
        }else
        {
            int hm = ((rCount));
            int hz = ((maxRowItemCount - Column));
            float cdm = (columnSpacing) * hm - (0 - Views[0].transform.localPosition.y);
            float cdz = columnSpacing * hz;
            if (cdz == 0)
            {
                return -1;
            }
            float proNum = cdm / cdz;
            return proNum;

        }
    }
    //  private float 
    public virtual void setProgress(float proNum)
    {
        if (isSlideX)
        {
            float p = getProgress();
            int hz = ((maxColumItemCount - Row));
            float cdz = rowSpacing * hz;
            int hm = ((rCount));
            float cdm = (rowSpacing) * hm + (0 - Views[0].transform.localPosition.x);
            float xNum = cdm;
            float fNum = cdz * proNum;

            if ((Math.Abs(fNum - xNum)) < rowSpacing)
            {
                MoveItem((fNum - xNum), false);
                cdm = (rowSpacing) * hm + (0 - Views[0].transform.localPosition.x);

            }
            else
            {


                //fNum = hz * proNum;
                int iNum = (int)(fNum / rowSpacing);
                float a = (fNum / rowSpacing);
                float b = (a-iNum) * rowSpacing; 
                int Rc = rCount;
                if (!checkRCount(iNum))
                {
                    showItems(startItem + iNum, endItem + iNum, true);
                    changeRCount(iNum);
                }

                hm = (Column * (rCount));
                fNum = cdz * proNum;
                cdm = (rowSpacing) * hm + (0 - Views[0].transform.localPosition.x);
                xNum = cdm;
                MoveItem((b), false);

            }
        }
        else
        {

            float p = getProgress();
            int hz = ((maxRowItemCount - Column));
            float cdz = columnSpacing * hz;
            int hm = ((rCount));
            float cdm = (columnSpacing) * hm - (0 - Views[0].transform.localPosition.y);
            float xNum = cdm;
            float fNum = cdz * proNum;
            /*
            Debug.Log("预期比值==》" + ((fNum - xNum) + xNum) / cdz);
            Debug.Log("总长度==》" + cdz);
            Debug.Log("现有比值==》" + p);
            Debug.Log("将要变的比值==》" + proNum);
            Debug.Log("将要变的长度==》" + fNum);
            Debug.Log("现有的长度==》" + xNum);
            Debug.Log("需要移动==》" + (fNum - xNum));*/
            if ((Math.Abs(fNum - xNum)) < columnSpacing)
            {
                MoveItem(-(fNum - xNum), false);
                cdm = (columnSpacing) * hm - (0 - Views[0].transform.localPosition.y);/*
            Debug.Log("更改后的需要移动==》" + (fNum - cdm));
            Debug.Log("更改后的现有长度==》" + cdm);
            Debug.Log("更改后的比值==》" + getProgress());*/

            }
            else
            {


                //fNum = hz * proNum;
                int iNum = (int)(fNum / columnSpacing);
                float a = (fNum / columnSpacing);
                float b = (a - iNum) * columnSpacing;
                /* Debug.Log("移动的时候需要在==》" + iNum);
                 Debug.Log("滚动后的差值==》" + b);*/
                int Rc = rCount;
                if (!checkRCount(iNum))
                {
                    showItems(startItem + iNum, endItem + iNum, true);
                    changeRCount(iNum);
                }

                hm = (Row * (rCount));
                fNum = cdz * proNum;
                cdm = (columnSpacing) * hm - (0 - Views[0].transform.localPosition.y);
                xNum = cdm;
                MoveItem(-(b), false);
                /*  Debug.Log("更改后的需要移动==》" + (fNum - cdm));
                 Debug.Log("更改后的现有长度==》" + cdm);
                 Debug.Log("更改后的比值==》" + getProgress());*/

            }
        }
    }

    void changeValue(float f)
    {
        slider3D.value = f;
    }

    float getValue()
    {
      return slider3D.value ;
    }
}