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

namespace DuckHunter
{
    public class GameManager : MonoBehaviour
    {
        public static GameManager Instance;
        [SerializeField] GameObject dogObject;
        [SerializeField] GameObject dogSideObject;
        [SerializeField] GameObject duckPrefab;
        [SerializeField] RectTransform duckBox;

        [System.NonSerialized] public bool isGameStarted;
        [System.NonSerialized] public bool isGameOver;
        public bool isGamePlaying { get => isGameStarted && !isGameOver; }
        public System.Action onGameStart;


        void Awake()
        {
            Instance = this;
            dogObject.SetActive(true);
            if (!AutoNextLevel)
            {
                DefaultLevel = 1;
                _CumulativeScore = 0;
            }
            level = DefaultLevel;
        }

        void OnDestroy()
        {
            if (Instance == this) Instance = null;
        }

        void Start()
        {
            TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.GAME_START);
            if (AutoNextLevel)
            {
                AutoNextLevel = false;
                StartGame(true);
            }
        }

        void onDeviceShoot(float speed) {

            OnModuleShooting((int)speed);
        }

        void Update()
        {
            UpdateCheckMouseHit();
            UpdateForAutoCreateDucks();
            SettleGame();
#if UNITY_EDITOR
            if (Input.GetKeyDown(KeyCode.A))
            {
                Time.timeScale = 10;
            }
            if (Input.GetKeyUp(KeyCode.A))
            {
                Time.timeScale = 1;
            }
#endif
        }

        void UpdateCheckMouseHit()
        {
            if (Input.GetMouseButtonDown(0) && BowCamera.isTouchMode)
            {
                if (EventSystem.current.currentSelectedGameObject == null)
                {
                    CrossHair.Instance.transform.position = Input.mousePosition;
                    OnModuleShooting(10);
                }
            }
        }

        /// <summary>
        /// 基础初速度
        /// </summary>
        public static float BaseFlySpeed = 50;
        /// <summary>
        /// 下次从多少分开始
        /// </summary>
        public static int DefaultLevel = 1;
        private static bool AutoNextLevel = false;
        [System.NonSerialized] public int hitScore; //得分
        [System.NonSerialized] public int level = 1;
        /// <summary>
        /// 通关需要击落的鸭子数量
        /// </summary>
        int passNeedHitCount;
        int needCreateDuckCount;
        bool canCreateDuck;
        [System.NonSerialized] public int theDuckCountWaitingForDogHandle;
        float _createDuckInterval;
        void UpdateForAutoCreateDucks()
        {
            if (isGameOver) return;
            if (!canCreateDuck) return;
            _createDuckInterval = 0;
            if (level <= 60)
            {
                if (theDuckCountWaitingForDogHandle > 0) return;
            }
            else if (level <= 80)
            {
                if (theDuckCountWaitingForDogHandle > 0) _createDuckInterval = 5;
                if (theDuckCountWaitingForDogHandle > 1) return;
            }
            else //<=100
            {
                if (theDuckCountWaitingForDogHandle > 0) _createDuckInterval = 5;
                if (theDuckCountWaitingForDogHandle > 2) return;
            }
            if (!Dog.Instance || Dog.Instance.isShowing) return;
            if (Time.time - _lastCreateDuckTime < _createDuckInterval) return;
            CreateDuck();
        }

        List<int> _ductTypeList = null;
        void InitDuckTypeList(int greenCount, int blueCount, int redCount)
        {
            if (_ductTypeList != null) return;
            _ductTypeList = new List<int>();
            for (int i = 0; i < greenCount; i++) _ductTypeList.Add(1);
            for (int i = 0; i < blueCount; i++) _ductTypeList.Add(2);
            for (int i = 0; i < redCount; i++) _ductTypeList.Add(3);
            _ductTypeList.Sort((a, b) => Random.value < 0.5 ? -1 : 1);
            needCreateDuckCount = _ductTypeList.Count;
        }

        static float[] _FlyAngles1 = { 75, 180 - 75 };
        static float[] _FlyAngles2 = { 75, 60, 180 - 75, 180 - 60 };
        static float[] _FlyAngles3 = { 45, 60, 180 - 45, 180 - 60 };
        static float[] _FlyAngles4 = { 30, 45, 60, 180 - 30, 180 - 45, 180 - 60 };
        static float RangeFlyAngle(float[] angles)
        {
            return angles[Random.Range(0, angles.Length)];
        }

        DuckConfig GetDuckConfig()
        {
            DuckConfig duckConfig = new DuckConfig();
            if (level <= 20) duckConfig.positionX = Random.Range(duckBox.rect.width / 2 - 200, duckBox.rect.width / 2 + 50);
            else duckConfig.positionX = Random.Range(250, duckBox.rect.width - 350);


            if (level <= 10)
            {
                InitDuckTypeList(10, 0, 0);
                passNeedHitCount = 6;
                duckConfig.touchBoundCount = 4;
                duckConfig.flyAngle = RangeFlyAngle(_FlyAngles1);
            }
            else if (level <= 15)
            {
                InitDuckTypeList(5, 5, 0);
                passNeedHitCount = 7;
                duckConfig.touchBoundCount = 4;
                duckConfig.flyAngle = RangeFlyAngle(_FlyAngles1);
            }
            else if (level <= 18)
            {
                InitDuckTypeList(5, 3, 2);
                passNeedHitCount = 8;
                duckConfig.touchBoundCount = 4;
                duckConfig.flyAngle = RangeFlyAngle(_FlyAngles1);
            }
            else if (level <= 20)
            {
                InitDuckTypeList(4, 4, 2);
                passNeedHitCount = 9;
                duckConfig.touchBoundCount = 4;
                duckConfig.flyAngle = RangeFlyAngle(_FlyAngles1);
            }
            else if (level <= 40)
            {
                InitDuckTypeList(3, 4, 3);
                passNeedHitCount = 10;
                duckConfig.touchBoundCount = 5;
                duckConfig.flyAngle = RangeFlyAngle(_FlyAngles2);
            }
            else if (level <= 60)
            {
                InitDuckTypeList(3, 3, 4);
                passNeedHitCount = 10;
                duckConfig.touchBoundCount = 6;
                duckConfig.flyAngle = RangeFlyAngle(_FlyAngles3);
            }
            else if (level <= 80)
            {
                InitDuckTypeList(2, 4, 4);
                passNeedHitCount = 10;
                duckConfig.touchBoundCount = 7;
                duckConfig.flyAngle = RangeFlyAngle(_FlyAngles4);
            }
            else if (level <= 100)
            {
                InitDuckTypeList(2, 3, 5);
                passNeedHitCount = 10;
                duckConfig.touchBoundCount = 8;
                duckConfig.flyAngle = RangeFlyAngle(_FlyAngles4);
            }

            duckConfig.type = _ductTypeList[0]; _ductTypeList.RemoveAt(0);


            //duckConfig.flySpeed = BaseFlySpeed * (1 + (level - 1) * 0.05f);
            //2023-7-25修改：速度还是以80关的做为初始速度，后面的关卡再按原来的公式增加
            duckConfig.flySpeed = BaseFlySpeed * (1 + (level + 79 - 1) * 0.05f);

            if (duckConfig.type == 1) duckConfig.flySpeed *= 1f;
            else if (duckConfig.type == 2) duckConfig.flySpeed *= 1.2f;
            else if (duckConfig.type == 3) duckConfig.flySpeed *= 1.5f;

            return duckConfig;
        }

        float _lastCreateDuckTime = -1000;
        void CreateDuck()
        {
            if (_ductTypeList != null && _ductTypeList.Count == 0) return;
            theDuckCountWaitingForDogHandle++;
            _lastCreateDuckTime = Time.time;
            DuckConfig duckConfig = GetDuckConfig();
            Duck duck = Instantiate(duckPrefab, duckBox).GetComponent<Duck>();
            duck.config = duckConfig;
            duck.onExit += HandleOnDuckExit;
            duck.onFallDonwEnd += HandleOnDuckFallDown;
            duck.onHitDead += HandleOnHitDead;
            duck.onStartFlyAway += () => TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.FLY_AWAY);
            //恢复箭
            ResumeArrows(duck);
        }
        int exitDuckCount = 0;
        void HandleOnDuckExit(Duck duck)
        {
            if (duck.dead) Dog.Instance?.OnEvent(Dog.SensitiveEventType.DuckHit, duck);
            else
            {
                RemoveArrows(duck);
                GameUI.Instance.RenderHitDuckCount(0);
                Dog.Instance?.OnEvent(Dog.SensitiveEventType.DuckGetAway);
            }
            exitDuckCount++;
        }
        float _lastFallDownTime = 0;
        void HandleOnDuckFallDown(Duck duck)
        {
            _lastFallDownTime = Time.time;
        }
        [System.NonSerialized] public int hitCount = 0;
        void HandleOnHitDead(Duck duck)
        {
            hitCount++;
            int scoreToPlus = duck.config.type * 500;
            hitScore += scoreToPlus;
            GameUI.Instance.RenderHitDuckCount(duck.config.type);
            // GameUI.Instance.RenderHitScore(hitScore, GetBestScore());
            _CumulativeScore += scoreToPlus;
            GameUI.Instance.RenderHitScore(_CumulativeScore, GetBestScore());
            GameUI.Instance.ShowTextHitScore(scoreToPlus, duck.transform.position);
            RemoveArrows(duck);
        }

        public void OnModuleRotationUpdate(Quaternion rotation)
        {
            CrossHair.Instance?.UpdatePositionByModuleRotation(rotation);
        }

        public void OnModuleShooting(float speed, bool bAddCount = false)
        {
            if (CrossHair.Instance)
            {

                if (isGamePlaying)
                {
                    if (UseOneArrow(bAddCount))
                    {
                        CrossHair.Instance.Shoot();
                        CheckShootPointHitDuck();
                        CheckNotifyFlyAway();
                    }
                }
                else if (!isGameStarted)
                {
                    //CrossHair.Instance.Shoot();
                    if (GameUI.Instance.CheckHitDuckForGameStart(CrossHair.Instance.transform.position))
                    {
                        OnClick_GameStart();
                    }
                }
            }
        }

        void CheckShootPointHitDuck()
        {
            bool hitDuck = false;
            Vector2 aimPos = CrossHair.Instance.transform.position;
            for (int i = Duck.DuckList.Count - 1; i >= 0; i--)
            {
                Duck duck = Duck.DuckList[i];
                RectTransform duckRTF = duck.transform as RectTransform;
                bool intersect = RectTransformUtility.RectangleContainsScreenPoint(duckRTF, aimPos);
                bool hitFrontBG = false;
                Collider2D[] hitColliders = Physics2D.OverlapPointAll(aimPos);
                foreach (var item in hitColliders)
                {
                    if (item.name.StartsWith("BGFront"))
                    {
                        hitFrontBG = true;
                        break;
                    }
                }
                if (intersect && !hitFrontBG && duck.Hit())
                {
                    hitDuck = true;
                    break;
                }
            }
            if (!hitDuck)
            {
                GameUI.Instance.AddArrowOnScreen(aimPos);
            }
        }

        void OnClick_GameStart()
        {
            AudioManager.Instance.PlayGameStart();
            StartGame(false);

        }

        void StartGame(bool startImmediate)
        {
            if (isGameStarted) return;
            isGameStarted = true;
            onGameStart?.Invoke();
            GameUI.Instance.HandleGameStart(() =>
            {
                dogSideObject.SetActive(true);
                dogSideObject.GetComponent<DogSide>().onExit = () => canCreateDuck = true;
                TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.ROUND_X, new object[] { level });
            }, startImmediate);
            NoArrows();
            GameUI.Instance.RenderLevel(level);
            // GameUI.Instance.RenderHitScore(hitScore, GetBestScore());
            GameUI.Instance.RenderHitScore(_CumulativeScore, GetBestScore());
        }
        //重新加载游戏
        public void onReLoadGame()
        {
            string sceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
            UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName);
        }

        public void onBackHome()
        {
            UnityEngine.SceneManagement.SceneManager.LoadScene("EnterTheInfraredScene",UnityEngine.SceneManagement.LoadSceneMode.Single);
        }

        void SettleGame()
        {
            if (isGameOver) return;
            if (_ductTypeList == null) return;
            if (Dog.Instance != null && Dog.Instance.isShowing) return;
            if (needCreateDuckCount != exitDuckCount) return;
            isGameOver = true;
            Debug.Log("Game Over");
            GameUI.Instance.RenderHitDuckCount(-1);

            if (hitCount < passNeedHitCount)
            {
                //通关失败
                TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.GAME_OVER, null, () =>
                {
                    string sceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
                    UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName);
                    //UnityEngine.SceneManagement.SceneManager.LoadScene("DuckHunter");
                });
                AudioManager.Instance.PlayGameOver();
                Debug.Log("通关失败");
            }
            else
            {
                //完美通关
                if (needCreateDuckCount == hitCount)
                {
                    //奖励额外积分
                    int plusScore = 10000;
                    hitScore += plusScore;
                    // GameUI.Instance.RenderHitScore(hitScore, GetBestScore());
                    _CumulativeScore += plusScore;
                    GameUI.Instance.RenderHitScore(_CumulativeScore, GetBestScore());
                    TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.SUPER_ARCHER, new object[] { plusScore }, ShowGamePass);
                    AudioManager.Instance.PlayFullScore();
                }
                else
                {
                    ShowGamePass();
                }
            }

            SaveBestScore();

            GameOverInterface.OnGameOver(GameMgr.gameType);
        }

        void ShowGamePass()
        {
            //通关成功
            TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.GAME_COMPLETED, null, () =>
            {
                //自动进入下一关
                if (level < 100)
                {
                    DefaultLevel = level + 1;
                    AutoNextLevel = true;
                }

                string sceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
                UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName);
                //UnityEngine.SceneManagement.SceneManager.LoadScene("DuckHunter");
            });
            AudioManager.Instance.PlayGamePass();
            Debug.Log("通关成功");
        }
        int _arrowCount;
        int arrowCount
        {
            get
            {
                // int count = 0;
                // _duckCanShootCountList.ForEach(e => count += e.shootCount);
                // return count;
                return _arrowCount;
            }
        }
        List<DuckCanShootCount> _duckCanShootCountList = new List<DuckCanShootCount>();
        class DuckCanShootCount
        {
            public Duck duck;
            public int shootCount;
            public DuckCanShootCount(Duck duck, int shootCount)
            {
                this.duck = duck;
                this.shootCount = shootCount;
            }
        }
        void ResumeArrows(Duck duck)
        {
            // _duckCanShootCountList.Add(new DuckCanShootCount(duck, 3));
            _arrowCount = 3;
            GameUI.Instance.RenderArrowCount(arrowCount);
        }
        void RemoveArrows(Duck duck)
        {
            // _duckCanShootCountList.RemoveAll(e => e.duck == duck);
            // GameUI.Instance.RenderArrowCount(arrowCount);
        }

        bool UseOneArrow(bool bAddCount = false)
        {
            if (arrowCount > 0)
            {
                // foreach (var e in _duckCanShootCountList)
                // {
                //     if (e.shootCount > 0)
                //     {
                //         e.shootCount--;
                //         break;
                //     }
                // }
                _arrowCount--;
                GameUI.Instance.RenderArrowCount(arrowCount);
                return true;
            }
            return false;
        }

        void NoArrows()
        {
            // _duckCanShootCountList = new List<DuckCanShootCount>();
            _arrowCount = 0;
            GameUI.Instance.RenderArrowCount(arrowCount);
        }

        void CheckNotifyFlyAway()
        {
            // foreach (var e in _duckCanShootCountList)
            //     if (e.shootCount == 0)
            //         e.duck.NotifyFlyAway();
            if (arrowCount <= 0)
                foreach (var duck in Duck.DuckList)
                    duck.NotifyFlyAway();
        }

        //累计得分
        private static int _CumulativeScore = 0;
        private static int _BestScoreVersion = 1;
        string GetBestScoreKey()
        {
            // return "BestScore_Level" + level + "_V" + _BestScoreVersion;
            return "DuckHunter_" + LoginMgr.myUserInfo.id + "_" + _BestScoreVersion;
        }
        void SaveBestScore()
        {
            string k = GetBestScoreKey();
            int s = PlayerPrefs.GetInt(k, 0);
            // if (hitScore > s) PlayerPrefs.SetInt(k, hitScore);
            if (_CumulativeScore > s) PlayerPrefs.SetInt(k, _CumulativeScore);
        }
        int GetBestScore()
        {
            string k = GetBestScoreKey();
            int s = PlayerPrefs.GetInt(k, 0);
            return s;
        }
    }
}
