using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;

public class PanelMain : BasePanel
{
    [SerializeField] CanvasGroup mCvsOpenPart;
    [SerializeField] Button mBtnOpen;

    [SerializeField] GameObject mGobLogo;
    [SerializeField] AudioClip[] mLogoSounds;

    [SerializeField] float[] mIconPosX;
    [SerializeField] Image[] mImgLevelIcons;
    [SerializeField] RectTransform mRctBottom;
    [SerializeField] RectTransform mRctFilmCells;

    [SerializeField] RectTransform mRctScream;

    [SerializeField] Transform mCtnBubble;
    [SerializeField] GameObject mTplBubble;

    [SerializeField] Button mBtnLast;
    [SerializeField] Button mBtnNext;

    [SerializeField] Button mBtnStartSingle;

    [SerializeField] Button mBtnStart;
    [SerializeField] Button mBtnLevel;

    [SerializeField] Button mBtnPrivacy;
    [SerializeField] Button mBtnUserPolicy;

    [SerializeField] GameObject mGobOpMask;

    private List<Image> mLevelIconList = new List<Image>();
    private List<int> mLevelList = new List<int>();

    private int mTotalLevel;
    private const int FOCUS_IDX = 2;

    private int mWaftDir = 1;
    private bool mIsWafting = false;

    private int mSoundIndex = -1;

    private bool mIsRolling = false;
    private TimerUnit mLogoSoundTimer;
    private TimerUnit mRollTimer;

    private SoundBubble mCurrentBubble;

    private const float FIX_DURATION = 0.2f;
    private const float FIX_WAIT = 10;

    private const float ROLL_DURATION = 0.3f;
    private const float WAFT_DURATION = 4f;

    private static bool sFirstIn = true;

    private void Awake()
    {
        UIUtils.BindBtn(mBtnOpen, OnClickOpen);
        UIUtils.BindBtn(mBtnLast, OnClickLast, AudioClipType.Click_Last);
        UIUtils.BindBtn(mBtnNext, OnClickNext, AudioClipType.Click_Next);
        UIUtils.BindBtn(mBtnStartSingle, OnClickStartSingle, AudioClipType.StartGame);
        UIUtils.BindBtn(mBtnStart, OnClickStart, AudioClipType.StartGame);
        UIUtils.BindBtn(mBtnLevel, OnClickLevel, AudioClipType.Click_Normal);
        UIUtils.BindBtn(mBtnPrivacy, OnClickPrivacy);
        UIUtils.BindBtn(mBtnUserPolicy, OnClickUserPolicy);
    }

    public override void OnOpen()
    {
        base.OnOpen();

        mLogoSoundTimer = TimerManager.Instance.CreateTimerUnit();
        mRollTimer = TimerManager.Instance.CreateTimerUnit();

        mGobOpMask.SetActive(false);

        if (sFirstIn)
        {
            sFirstIn = false;

            mCvsOpenPart.alpha = 1;
            mCvsOpenPart.gameObject.SetActive(true);
            mBtnOpen.enabled = true;

            mRollTimer.StartTimer(FadeOutOpenPart, 3);
        }
        else
        {
            ShowMainPart();
        }

        ToukaSDKManager.Instance.LogEventByUmeng(Const.AdsEvent.PanelMainShowed);
    }

    public override void OnClose()
    {
        base.OnClose();

        if (mLogoSoundTimer != null)
        {
            mLogoSoundTimer.Destroy();
            mLogoSoundTimer = null;
        }

        if (mRollTimer != null)
        {
            mRollTimer.Destroy();
            mRollTimer = null;
        }
    }

    private void OnDestroy()
    {
        if (mLogoSoundTimer != null)
        {
            mLogoSoundTimer.Destroy();
            mLogoSoundTimer = null;
        }

        if (mRollTimer != null)
        {
            mRollTimer.Destroy();
            mRollTimer = null;
        }
    }

    private void FadeOutOpenPart()
    {
        mRollTimer.CancelTimer();
        mCvsOpenPart.DOFade(0, 0.5f).SetEase(Ease.Linear).onComplete = ShowMainPart;
    }

    private void PlayLogoSound()
    {
        mSoundIndex++;

        if (mSoundIndex < mLogoSounds.Length)
        {
            AudioManager.Instance.PlaySound(mLogoSounds[mSoundIndex]);
            mLogoSoundTimer.StartTimer(PlayLogoSound, 0.8f);
        }
        else
        {
            mLogoSoundTimer.CancelTimer();
            mLogoSoundTimer.Destroy();
            mLogoSoundTimer = null;
        }
    }

    private void ShowMainPart()
    {
        mCvsOpenPart.gameObject.SetActive(false);
        mRctScream.gameObject.SetActive(false);

        mGobLogo.SetActive(true);
        mSoundIndex = -1;
        mLogoSoundTimer.StartTimer(PlayLogoSound, 0.5f);

        mBtnStartSingle.gameObject.SetActive(false);
        mRctBottom.anchoredPosition = Vector2.zero;
        mRctFilmCells.anchoredPosition = new Vector2(-1550, 0);

        if (PlayerData.Instance.UnlockedLevel < 3)
        {
            mRollTimer.StartTimer(ShowStartSingle, 3);
        }
        else
        {
            mRollTimer.StartTimer(ShowFilm, 3);
        }
    }

    private void ShowStartSingle()
    {
        mBtnStartSingle.gameObject.SetActive(true);

        AudioManager.Instance.PlayBGMusic(AudioClipType.BGM, 0.8f);
    }

    private void ShowFilm()
    {
        InitLevelIcons();

        mRctFilmCells.DOAnchorPosX(0, 0.5f).SetEase(Ease.Linear);
        mRctBottom.DOAnchorPosY(580, 0.5f).SetDelay(0.2f).SetEase(Ease.Linear).onComplete = () =>
        {
            Waft();
            ShowBubble();
        };

        AudioManager.Instance.PlayBGMusic(AudioClipType.BGM, 0.8f);
    }

    private void InitLevelIcons()
    {
        mTotalLevel = PlayerData.Instance.UnlockedLevel;

        int tLevel = 0;
        for (int i = 0; i < mImgLevelIcons.Length; i++)
        {
            tLevel = GetLevelInCircle(-2 + i + PlayerData.Instance.CurrentLevel, mTotalLevel);
            mLevelList.Add(tLevel);

            mImgLevelIcons[i].sprite = ResourceManager.Instance.LoadRes<Sprite>(Const.Path.GetLevelIconBig(GameConfig.Instance.LevelSort[(tLevel - 1) % mTotalLevel]));
            mLevelIconList.Add(mImgLevelIcons[i]);
        }
    }

    private int GetLevelInCircle(int pLevelNum, int pTotalLevel)
    {
        int tFinalLevel = pLevelNum;
        if (tFinalLevel <= 0)
        {
            while (tFinalLevel <= 0)
            {
                tFinalLevel += pTotalLevel;
            }
        }
        else if (tFinalLevel > pTotalLevel)
        {
            tFinalLevel = (tFinalLevel - 1) % pTotalLevel + 1;
        }

        return tFinalLevel;
    }

    private void FixRolling()
    {
        mIsWafting = false;
        mIsRolling = false;

        for (int i = 1; i < mLevelIconList.Count - 1; i++)
        {
            mLevelIconList[i].rectTransform.DOKill();
            mLevelIconList[i].rectTransform.DOAnchorPosX(mIconPosX[i], FIX_DURATION).SetEase(Ease.OutSine);
        }

        mRollTimer.StartTimer(Waft, FIX_WAIT);

        ShowBubble();
    }

    private void Waft()
    {
        mIsWafting = true;
        mIsRolling = false;

        for (int i = 1; i < mLevelIconList.Count - 1; i++)
        {
            mLevelIconList[i].rectTransform.DOKill();
            mLevelIconList[i].rectTransform.DOAnchorPosX(mIconPosX[i] + mWaftDir * 80, WAFT_DURATION).SetEase(Ease.Linear);
        }

        if (mWaftDir == 1)
        {
            mRollTimer.StartTimer(RollRight, WAFT_DURATION);
        }
        else
        {
            mRollTimer.StartTimer(RollLeft, WAFT_DURATION);
        }
    }

    private void RollLeft()
    {
        mIsRolling = true;

        for (int i = 0; i < mLevelList.Count; i++)
        {
            mLevelList[i] = GetLevelInCircle(mLevelList[i] + 1, mTotalLevel);
        }

        Image tStartImg = mLevelIconList[0];
        for (int i = 1; i < mLevelIconList.Count; i++)
        {
            int tLastIndex = (i - 1) % mLevelIconList.Count;

            mLevelIconList[tLastIndex] = mLevelIconList[i];
            mLevelIconList[tLastIndex].rectTransform.DOKill();
            mLevelIconList[tLastIndex].rectTransform.DOAnchorPosX(mIconPosX[tLastIndex], ROLL_DURATION).SetEase(Ease.OutSine);
        }
        mLevelIconList[mLevelIconList.Count - 1] = tStartImg;
        mLevelIconList[mLevelIconList.Count - 1].sprite = ResourceManager.Instance.LoadRes<Sprite>(Const.Path.GetLevelIconBig(GameConfig.Instance.LevelSort[mLevelList[mLevelIconList.Count - 1] - 1]));
        mLevelIconList[mLevelIconList.Count - 1].rectTransform.anchoredPosition = new Vector2(mIconPosX[mLevelIconList.Count - 1], 0);

        HideBubble();
        mRollTimer.StartTimer(RollOver, ROLL_DURATION);
    }

    private void RollRight()
    {
        mIsRolling = true;

        for (int i = 0; i < mLevelList.Count; i++)
        {
            mLevelList[i] = GetLevelInCircle(mLevelList[i] - 1, mTotalLevel);
        }

        Image tEndImg = mLevelIconList[mLevelIconList.Count - 1];
        for (int i = mLevelIconList.Count - 2; i >= 0; i--)
        {
            int tNextIndex = (i + 1) % mLevelIconList.Count;

            mLevelIconList[tNextIndex] = mLevelIconList[i];
            mLevelIconList[tNextIndex].rectTransform.DOKill();
            mLevelIconList[tNextIndex].rectTransform.DOAnchorPosX(mIconPosX[tNextIndex], ROLL_DURATION).SetEase(Ease.OutSine);
        }
        mLevelIconList[0] = tEndImg;
        mLevelIconList[0].sprite = ResourceManager.Instance.LoadRes<Sprite>(Const.Path.GetLevelIconBig(GameConfig.Instance.LevelSort[mLevelList[0] - 1]));
        mLevelIconList[0].rectTransform.anchoredPosition = new Vector2(mIconPosX[0], 0);

        HideBubble();
        mRollTimer.StartTimer(RollOver, ROLL_DURATION);
    }

    private void RollOver()
    {
        mIsRolling = false;
        mRollTimer.StartTimer(Waft, mIsWafting ? -1 : FIX_WAIT);

        ShowBubble();
    }

    private void ShowBubble()
    {
        HideBubble();

        mCurrentBubble = Instantiate(mTplBubble, mCtnBubble).GetComponent<SoundBubble>();
        mCurrentBubble.gameObject.SetActive(true);
        mCurrentBubble.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
        mCurrentBubble.transform.localScale = Vector3.one;

        mCurrentBubble.Show(GameConfig.Instance.LevelSort[mLevelList[FOCUS_IDX] - 1]);
    }

    private void HideBubble()
    {
        if (mCurrentBubble != null)
        {
            mCurrentBubble.Hide();
            mCurrentBubble = null;
        }
    }

    private void OnClickOpen()
    {
        mBtnOpen.enabled = false;
        FadeOutOpenPart();
    }

    private void OnClickLast()
    {
        if (mIsRolling)
            return;

        if (mIsWafting && mWaftDir == -1)//turn around
        {
            FixRolling();
        }
        else
        {
            mIsWafting = false;
            RollRight();
        }

        mWaftDir = 1;
    }

    private void OnClickNext()
    {
        if (mIsRolling)
            return;

        if (mIsWafting && mWaftDir == 1)//turn around
        {
            FixRolling();
        }
        else
        {
            mIsWafting = false;
            RollLeft();
        }

        mWaftDir = -1;
    }

    private void OnClickStartSingle()
    {
        mGobOpMask.SetActive(true);
        mRctScream.gameObject.SetActive(true);
        mRctScream.position = mBtnStartSingle.transform.position;

        TimerManager.Instance.Schedule(DelayStartSingle, 1f);
    }

    private void DelayStartSingle()
    {
        GameManager.Instance.LoadGame();
    }

    private void OnClickStart()
    {
        mGobOpMask.SetActive(true);
        mRctScream.gameObject.SetActive(true);
        mRctScream.position = mLevelIconList[FOCUS_IDX].transform.position;

        for (int i = 0; i < mLevelIconList.Count; i++)
        {
            mLevelIconList[i].rectTransform.DOKill();
        }
        mRollTimer.CancelTimer();

        TimerManager.Instance.Schedule(DelayStart, 1f);
    }

    private void DelayStart()
    {
        PlayerData.Instance.CurrentLevel = mLevelList[FOCUS_IDX];
        GameManager.Instance.LoadGame();
    }

    private void OnClickLevel()
    {
        PanelLevel tUILevel = UIManager.Instance.OpenUI<PanelLevel>();
        tUILevel.Init(false);
    }

    private void OnClickPrivacy()
    {
        ToukaUtils.OpenPrivacyURL();
    }

    private void OnClickUserPolicy()
    {
        ToukaUtils.OpenUserPolicy();
    }
}