import { _decorator, Component, Node } from 'cc';
import { LevelPanel } from '../../../UI/global/LevelPanel';
import { LevelData, UnlockData } from '../../data/DataModel';
import { UserDataBehaviour } from '../../data/UserDataBehaviour';
import { GridManager } from '../../in-game/board/GridManager';

const { ccclass, property } = _decorator;

@ccclass('LevelManager')
export class LevelManager extends Component 
{
    @property({type: LevelPanel})
    private m_LevelPanel: LevelPanel;
    
    private m_LevelDatas: LevelData[] = [];
    private m_CurrentLevelNum: number = 0;
    
    private m_CurrentLevelIndex: number = 0;
    
    private gridManager: GridManager;
    private userDataBehaviour: UserDataBehaviour;

    public get fn_UserDataBehaviour() : UserDataBehaviour
    {
        return this.userDataBehaviour;
    }
    
    public fn_GetLevelSelectedState() : boolean
    {
        return this.m_LevelPanel.fn_HasSelectedLevel();
    }

    public fn_GetCurrentLevelNum() : number
    {
        return this.m_CurrentLevelNum;
    }

    public fn_GetLastLevelNum() : number 
    {
        return this.m_LevelDatas.length;
    }

    public fn_IsLevelUnfinished() : UnlockData
    {
        if (this.m_LevelDatas != null)
        {
            let dataFound = this.m_LevelDatas.find(data => data.level == this.m_CurrentLevelNum);
            
            if (dataFound != null && dataFound.unlockData != null) // no data, level was finished
            {
                return dataFound.unlockData;
            }
        }

        return null;
    }

    public fn_InitGridManager(gridManager: GridManager) 
    {
        this.gridManager = gridManager;
    }

    public fn_InitData(userDataBehaviour: UserDataBehaviour)
    {
        this.userDataBehaviour = userDataBehaviour;

        this.m_LevelDatas = this.userDataBehaviour.fn_GetUserData().levelDatas;
        this.fn_SetUnlockedStateForAllLevels();            
        
        if (this.userDataBehaviour.fn_GetUserData().selectedLevel == null)
            this.userDataBehaviour.fn_GetUserData().selectedLevel = 1;

        this.fn_SetCurrentLevelNum(this.userDataBehaviour.fn_GetUserData().selectedLevel);

        console.log("this.userDataBehaviour.fn_GetUserData().lastUnlockedLevel: " + this.userDataBehaviour.fn_GetUserData().lastUnlockedLevel);

        this.m_LevelPanel.fn_InitLevelsData(
            this.m_LevelDatas, 
            this.userDataBehaviour.fn_GetUserData().selectedLevel,
            this.userDataBehaviour.fn_GetUserData().lastUnlockedLevel, 
            this);
    }

    private fn_SetUnlockedStateForAllLevels() 
    {
        let levelsLength = this.m_LevelDatas.length;
        
        this.m_LevelDatas[0].unlocked = true; 
        for (let i = 0; i < levelsLength; i++) 
        {
            if (this.m_LevelDatas[i].unlocked)
                continue;

            this.m_LevelDatas[i].unlocked = false;
        } 
    }

    public PassLevelData(levelNum: number, rows: number, cols: number)
    {
        this.fn_SetCurrentLevelNum(levelNum);
        this.gridManager.fn_InitLevelData(rows, cols);
    }

    public fn_UpdateLevelsDataOnLevelCompletion() : void 
    {
        this.fn_SlidePageToCurrentActivePage();

        if ((this.m_CurrentLevelNum % this.m_LevelPanel.maxLevelsAllowedInSinglePage) == 0) // last level in current page has been completed
        {
            this.m_LevelPanel.levelPageNavigator.fn_SetManualNavigation(true);
            this.m_LevelPanel.levelPageNavigator.fn_OnNextPageClicked();
        }
        
        // this.m_LevelPanel.fn_UpdateLastUnlockedLevel(this.m_CurrentLevelNum);
        this.m_LevelPanel.fn_UpdateCurrentAndNewLevelElementsOnLevelComplete();

        console.log("## this.m_CurrentLevelNum: " + this.m_CurrentLevelNum);
        console.log("## this.m_LevelPanel.lastUnlockedLevel: " + this.m_LevelPanel.lastUnlockedLevel);

        this.userDataBehaviour.fn_SetLevelUnlockedData(this.m_CurrentLevelNum, this.m_LevelPanel.lastUnlockedLevel);
    }

    public fn_SlidePageToCurrentActivePage(useTween: boolean = false)
    {
        let currentShownPage = null;
        let levelComps = null;
        let levelPageFound = false;
        let lastLevelNumberValue = 0;

        let totalLevelsInPage = this.m_LevelPanel.maxLevelsAllowedInSinglePage;

        currentShownPage = this.m_LevelPanel.levelPageNavigator.currentMiddlePage;
        levelComps = currentShownPage.GetLevelComps;

        if (currentShownPage.GetTotalLevels == null)
            console.log("Undefined value obtained");

        console.log("levelComps[0].fn_GetLevelNum(): " + levelComps[0].fn_GetLevelNum());
        console.log("this.m_LevelPanel.maxLevelsAllowedInSinglePage - 1: " + (this.m_LevelPanel.maxLevelsAllowedInSinglePage - 1));
        console.log("this.m_LevelDatas.length: " + this.m_LevelDatas.length);        

        console.log("CurrentShownPage: " + currentShownPage.node.name);
        console.log("m_CurrentLevelNum: " + this.m_CurrentLevelNum);

        while (true)
        {
            currentShownPage = this.m_LevelPanel.levelPageNavigator.currentMiddlePage;
            levelComps = currentShownPage.GetLevelComps;
            
            lastLevelNumberValue = levelComps[0].fn_GetLevelNum() + (this.m_LevelPanel.maxLevelsAllowedInSinglePage - 1);
            if (lastLevelNumberValue > this.m_LevelDatas.length)
            {
                console.log("## NEW_LOG: this.m_LevelDatas.length: " + this.m_LevelDatas.length);
                console.log("## NEW_LOG: (levelComps[0].fn_GetLevelNum() + 1: " + (levelComps[0].fn_GetLevelNum() + 1));
                totalLevelsInPage = this.m_LevelDatas.length - (levelComps[0].fn_GetLevelNum() - 1);
                // totalLevelsInPage = lastLevelNumberValue - this.m_LevelDatas.length;
            }
            console.log("currentShownPage.GetTotalLevels: " + totalLevelsInPage);
            console.log("levelComps[levelComps.length - 1].fn_GetLevelNum(): " + levelComps[totalLevelsInPage - 1].fn_GetLevelNum());

            console.log("lastLevelNumberValue: " + lastLevelNumberValue);

            levelPageFound = this.m_CurrentLevelNum >= levelComps[0].fn_GetLevelNum() && 
                                this.m_CurrentLevelNum <= levelComps[totalLevelsInPage - 1].fn_GetLevelNum();
            
            if (levelPageFound)
            {
                console.log("page found");
                break;
            }
            else 
            {
                if (this.m_CurrentLevelNum < levelComps[0].fn_GetLevelNum())
                {
                    console.log("Sliding: Right slide");
                    this.m_LevelPanel.levelPageNavigator.fn_GoForRightSlide(false);
                }   
                else if (this.m_CurrentLevelNum > levelComps[totalLevelsInPage - 1].fn_GetLevelNum())
                {
                    console.log("Sliding: Left slide");
                    this.m_LevelPanel.levelPageNavigator.fn_GoForLeftSlide(false);
                }   
            }
        }
    }

    public fn_SetUnlockLevelData(unlockData: UnlockData)
    {
        this.m_LevelDatas[this.m_CurrentLevelIndex].unlockData = unlockData;
        this.m_LevelDatas[this.m_CurrentLevelIndex].unlocked = true;

        console.log("### this.m_CurrentLevelNum: " + this.m_CurrentLevelNum);
        console.log("### this.m_LevelPanel.lastUnlockedLevel: " + this.m_LevelPanel.lastUnlockedLevel);
        console.log("### lastSelectedLevel: " + this.m_LevelPanel.lastSelectedLevel);

        this.userDataBehaviour.fn_SetLevelDatas(this.m_CurrentLevelNum, this.m_LevelPanel.lastUnlockedLevel, unlockData);
    }

    private fn_SetCurrentLevelNum(levelNum: number)
    {
        this.m_CurrentLevelNum = levelNum;
        this.m_CurrentLevelIndex = this.m_CurrentLevelNum - 1;
    }
}

