using Config.config;
using Sirenix.OdinInspector;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Rendering;
/// 
/// 路段_生成NPC车辆
/// 
public partial class SectionRoad
{
    /// 
    /// 占用车道列表
    /// 
    public List occupationIndex = new List();
    /// 
    /// 排除已换的车辆
    /// 
    private List exclude;
    /// 
    /// 记录变道车辆
    /// 
    private List record;
    /// 
    /// 生成NPC车
    /// 
    public void GenerateNPCCar(List ints, LevelConfig levelConfig)
    {
        PutCar();
        for (int i = 0; i < ints.Count; i++)
        {
            GenerateRoundNPCCar(levelConfig, generatePoints[ints[i]]);
        }
    }
    /// 
    /// 指定位置生成车
    /// 
    /// 
    public NPCCar GenerateNPCCar(Vector3 pos,string skinCarID)
    {
        NPCCar npcCar =CachePoolManager.Instance.Take(YooAssetManager.Instance.LoadAssetSync(PackagesName.GameData, "NPCCar")).GetComponent();
        npcCar.SetSkinCar(skinCarID);
        npcCar.transform.localEulerAngles = new Vector3(0,90,0);
        npcCar.transform.position = pos;
        return npcCar;
    }
    /// 
    /// 生成火车
    /// 
    public void GenerateTrain(LevelConfig levelConfig)
    {
        PutCar();
        int rLan = Random.Range(0, 2);
        Train train = CachePoolManager.Instance.Take(YooAssetManager.Instance.LoadAssetSync(PackagesName.GameData, "Train")).GetComponent();
        train.transform.position = generatePoints[rLan].transform.position;
        train.SetDirection(ProbabilityManager.Instance.GetPercent(50) ? E_DirectionType.Left : E_DirectionType.Right);
        trains.Add(train);
        GenerateRoundNPCCar(levelConfig, generatePoints[rLan == 0 ? 1 : 0]);
    }
    /// 
    /// 生成一轮NPC车
    /// 
    private void GenerateRoundNPCCar(LevelConfig levelConfig, Transform generatePoint)
    {
        List recordGeneratingDistance = new List();
        for (int i = 0; i < generatingDistance.Count; i++)
        {
            recordGeneratingDistance.Add(generatingDistance[i]);
        }
        int number;
        if (Scenes.Instance.gameScene.GetSchedule() < levelConfig.End / 3)
        {
            number = 2;
        }
        else
        {
            number = GetCurrentLaneNumber() - Random.Range(levelConfig.MinEmptyLane, (levelConfig.MaxEmptyLane + 1));
        }
        for (int i = 0; i < number; i++)
        {
            (Vector3, int) pos = GetEmptyLane();
            NPCCar npcCar = CachePoolManager.Instance.Take(YooAssetManager.Instance.LoadAssetSync(PackagesName.GameData, "NPCCar")).GetComponent();
            npcCar.transform.SetParent(npcCarNode);
            npcCar.transform.localEulerAngles = Vector3.zero;
            int rPos = recordGeneratingDistance[Random.Range(0, recordGeneratingDistance.Count)];
            npcCar.transform.localPosition = new Vector3(pos.Item1.x, 0, generatePoint.transform.localPosition.z + rPos);
            recordGeneratingDistance.Remove(rPos);
            npcCar.SetData(pos.Item2, this);
            LaneData laneData = new LaneData();
            laneData.index = pos.Item2;
            laneData.car = npcCar;
            occupationIndex.Add(laneData);
            npcCars.Add(npcCar);
        }
        RandomChangeLanes(levelConfig);
        occupationIndex.Clear();
    }
    /// 
    /// 同行变道
    /// 
    public void SideBySideChangeLanes(LevelConfig levelConfig)
    {
        int number = Random.Range(levelConfig.MinLaneChangingCar,levelConfig.MaxLaneChangingCar+1);
        if(number>= occupationIndex.Count)
        {
            number = occupationIndex.Count-1;
        }
        if(number==3)
        {
            if(occupationIndex.Find(s => s.index == minIndex) != null && occupationIndex.Find(s => s.index == maxIndex) != null&& occupationIndex.Find(s => s.index == minIndex+1) != null && occupationIndex.Find(s => s.index == maxIndex-1)!=null)
            {
                number--;
            }
        }
        if(number==2)
        {
            if(occupationIndex.Find(s=>s.index==minIndex)!=null&& occupationIndex.Find(s => s.index == maxIndex) != null)
            {
                number--;
            }
        }
        bool isLeft = false;
        bool isRight = false;
        bool leftCondition = false;//条件是否成立
        bool rightCondition = false;//条件是否成立
        int startIndex = 0;
        LaneData laneData = null;
        exclude = new List();
        for (int i = 0; i < number; i++)
        {
            record = new List();
            for (int j = 0; j < occupationIndex.Count; j++)
            {
                if (exclude.Find(s => s.index == occupationIndex[j].index) == null)
                {
                    record.Add(occupationIndex[j].index);
                }
            }
            while (true)
            {
                int randomIndex = record[Random.Range(0, record.Count)];
                laneData = occupationIndex.Find(s => s.index == randomIndex);
                startIndex = laneData.index;
                isLeft = startIndex - 1 >= minIndex && occupationIndex.Find(s => s.index == startIndex - 1) == null;
                isRight = startIndex + 1 <= maxIndex && occupationIndex.Find(s => s.index == startIndex + 1) == null;
                if (isLeft)
                {
                    leftCondition = number - i != 1 && JustFindLeft(startIndex,startIndex - 1)&&!AgainstFindRight(startIndex, startIndex-1);
                }
                 if (isRight)
                {
                    rightCondition =number - i != 1 && JustFindRight(startIndex,startIndex + 1)&&!AgainstFindLeft(startIndex,startIndex + 1);
                }
                if (isLeft && !leftCondition || isRight && !rightCondition)
                {
                    break;
                }
                else
                {
                    record.Remove(startIndex);
                }
            }
            if (ProbabilityManager.Instance.GetPercent(50))
            {
                if (isLeft && leftCondition)
                {
                    laneData.index++;
                    laneData.car.SetRightLeft(E_DirectionType.Right);
                }
                else if (isLeft && !rightCondition)
                {
                    laneData.index--;
                    laneData.car.SetRightLeft(E_DirectionType.Left);
                }
                else if (isLeft)
                {
                    laneData.index--;
                    laneData.car.SetRightLeft(E_DirectionType.Left);
                }
                if (isRight && rightCondition)
                {
                    laneData.index--;
                    laneData.car.SetRightLeft(E_DirectionType.Left);
                }
                else if (isRight && !leftCondition)
                {
                    laneData.index++;
                    laneData.car.SetRightLeft(E_DirectionType.Right);
                }
                else if (isRight)
                {
                    laneData.index++;
                    laneData.car.SetRightLeft(E_DirectionType.Right);
                }
            }
            else
            {
                if (isRight && rightCondition)
                {
                    laneData.index--;
                    laneData.car.SetRightLeft(E_DirectionType.Left);
                }
                else if (isRight && !leftCondition)
                {
                    laneData.index++;
                    laneData.car.SetRightLeft(E_DirectionType.Right);
                }
                else if (isRight)
                {
                    laneData.index++;
                    laneData.car.SetRightLeft(E_DirectionType.Right);
                }
                if (isLeft && leftCondition)
                {
                    laneData.index++;
                    laneData.car.SetRightLeft(E_DirectionType.Right);
                }
                else if (isLeft && !rightCondition)
                {
                    laneData.index--;
                    laneData.car.SetRightLeft(E_DirectionType.Left);
                }
                else if (isLeft)
                {
                    laneData.index--;
                    laneData.car.SetRightLeft(E_DirectionType.Left);
                }
            }
            exclude.Add(laneData);
        }
        exclude.Clear();
    }
    /// 
    /// 随机变道
    /// 
    public void RandomChangeLanes(LevelConfig levelConfig)
    {
        LaneData laneData = null;
        int number = Random.Range(levelConfig.MinLaneChangingCar, levelConfig.MaxLaneChangingCar + 1);
        if(number>occupationIndex.Count)
        {
            number = occupationIndex.Count;
        }
        record = new List();
        for (int i = 0; i < occupationIndex.Count; i++)
        {
            record.Add(occupationIndex[i].index);
        }
        for (int i = 0; i < number; i++)
        {
            int randomIndex = record[Random.Range(0, record.Count)];
            laneData = occupationIndex.Find(s => s.index == randomIndex);
            laneData.car.ISChangeLanes();
            record.Remove(randomIndex);
        }
    }
    /// 
    /// 正向查找左边车道是否占满
    /// 
    public bool JustFindLeft(int startIndex,int index)
    {
        int numbr = 0;
        bool isTrue = false;
        for (int i = 0; i < occupationIndex.Count; i++)
        {
            if (occupationIndex[i].index < index && occupationIndex[i].index!= startIndex)
            {
                numbr++;
            }
        }
        for (int i = 1; i <= numbr; i++)
        {
            if (occupationIndex.Find(s => s.index == (index-i)) != null&& index - i != startIndex)
            {
                isTrue = true;
            }
            else
            {
                isTrue = false;
                break;
            }
        }
        return isTrue;
    }
    /// 
    /// 正向查找右边车道是否占满
    /// 
    public bool JustFindRight(int startIndex,int index)
    {
        int numbr = 0;
        bool isTrue = false;
        for (int i = 0; i < occupationIndex.Count; i++)
        {
            if (occupationIndex[i].index > index && occupationIndex[i].index!= startIndex)
            {
                numbr++;
            }
        }
        for (int i = 1; i <= numbr; i++)
        {
            if (occupationIndex.Find(s => s.index == (index + i)) != null&& index+i!=startIndex)
            {
                isTrue = true;
            }
            else
            {
                isTrue = false;
                break;
            }
        }
        return isTrue;
    }
    /// 
    /// 反向查找左边车道是否占满
    /// 
    public bool AgainstFindLeft(int startIndex, int index)
    {
        int numbr = 0;
        bool isTrue = false;
        for (int i = 0; i < occupationIndex.Count; i++)
        {
            if (occupationIndex[i].index < index)
            {
                numbr++;
            }
        }
        for (int i = 1; i <= numbr; i++)
        {
            if (occupationIndex.Find(s => s.index == (index - i)) != null && index - i != startIndex)
            {
                isTrue = true;
                break;
            }
            else
            {
                isTrue = false;
            }
        }
        return isTrue;
    }
    /// 
    /// 反向查找右边车道是否占满
    /// 
    public bool AgainstFindRight(int startIndex, int index)
    {
        int numbr = 0;
        bool isTrue = false;
        for (int i = 0; i < occupationIndex.Count; i++)
        {
            if (occupationIndex[i].index > index)
            {
                numbr++;
            }
        }
        for (int i = 1; i <= numbr; i++)
        {
            if (occupationIndex.Find(s => s.index == (index + i)) != null && index + i != startIndex)
            {
                isTrue = true;
                break;
            }
            else
            {
                isTrue = false;
            }
        }
        return isTrue;
    }
}
/// 
/// 每条车道数据
/// 
public class LaneData
{
    /// 
    /// 车道索引
    /// 
    public int index;
    /// 
    /// 车道上生成的车 是null则是空车道
    /// 
    public NPCCar car;
}