import { baseBX24 } from "./base/BX24";
import { getAuth } from "./types/getAuth";

export class BX24 extends baseBX24{
    constructor(cb?:(params:any)=>void){
        super();
        const q = window.name.split('|');
        this.DOMAIN = q[0].replace(/:(80|443)$/, '');
        this.PROTOCOL = parseInt(q[1])||0;
        this.APP_SID = q[2];
        if (window&&window instanceof Window){
            window.addEventListener("message", (event:MessageEvent)=>{
                this.runCallback(event);
            });
            
            if(!this.DOMAIN||!this.LANG||!this.AUTH_ID){                    
                this.sendMessage('getInitData', this.defaultValueFromIframe);
            }
        }            

        this.utilReady();
        if (cb){
            this.init(cb);
        }
    }


    defaultValueFromIframe(data:any){
        if(!this.DOMAIN)
            this.DOMAIN = data.DOMAIN;
        if(!this.PATH)
            this.PATH = data.PATH;
        if(!this.LANG)
            this.LANG = data.LANG;
        if(!this.PLACEMENT)
            this.PLACEMENT = data.PLACEMENT;

        this.PROTOCOL = data.PROTOCOL;
        this.DOMAIN = this.DOMAIN.replace(/:(80|443)$/, '');

        if(data.AUTH_ID){
            this.AUTH_ID = data.AUTH_ID;
            this.REFRESH_ID = data.REFRESH_ID;
            this.AUTH_EXPIRES = (new Date()).valueOf()+data.AUTH_EXPIRES*1000;
            this.IS_ADMIN = !!data.IS_ADMIN;
            this.MEMBER_ID = data.MEMBER_ID||'';
        }

        if(!this.USER_OPTIONS)
            this.USER_OPTIONS = data.USER_OPTIONS;

        if(!this.APP_OPTIONS)
            this.APP_OPTIONS = data.APP_OPTIONS;

        if(!this.PLACEMENT_OPTIONS)
            this.PLACEMENT_OPTIONS = data.PLACEMENT_OPTIONS;

        this.isInit = true;

        if(data.FIRST_RUN && this.arrEvents.find(el=>{return el.event=='install'})){
            this.emitEvent('install');
        }
        else
        {
            this.doInit();
        }
    }

    runCallback(e:MessageEvent){
        if(e.origin != 'http'+(this.PROTOCOL?'s':'')+'://'+this.DOMAIN)
            return;
    
        if(e.data)
        {
            const r = e.data.split(":");
            const cmd = [r[0],r.slice(1).join(":")];
            let args = [];

            const findedCb=this.cbArray.find(el=>{return el.uid==cmd[0]});
    
            if(findedCb)
            {
                if(findedCb)
                    try {
                        args = JSON.parse(cmd[1]);    
                    } catch (error) {
                        console.log('Args callback not parsed:', cmd[1]);
                    }
                    findedCb.cb.call(this, args);
            }
        }
    }

    refreshAuthAsync(): Promise<getAuth> {
        return new Promise((resolve, reject)=>{
            let isExeted=false;
            this.refreshAuth(newAuth=>{
                isExeted=true;
                resolve(newAuth);
            })
            setTimeout(() => {
                if (!isExeted) reject('refresh auth timeout!')
            }, 5000);
        });
    }

    refreshAuth(cb?:(params: any) => void){
        this.sendMessage('refreshAuth', {}, (result:any)=>{
            this.AUTH_ID=result.AUTH_ID;
            this.REFRESH_ID=result.REFRESH_ID;
            this.AUTH_EXPIRES=(new Date()).valueOf()+result.AUTH_EXPIRES*1000;
            if (cb){
                cb(this.getAuth());
            }
        })
    }

    sendMessage(cmd: string, params: any, cb?: (args:any)=>void): void{
        if(this.isFunction(params))
        {
            cb = params; params = null;
        }
    
        cmd += ':' + (params ? JSON.stringify(params) : '')
                + ':' + this.setCallback(cb)
                + (this.APP_SID ? (':' + this.APP_SID) : '');
    
        parent.postMessage(cmd, 'http'+(this.PROTOCOL?'s':'')+'://' + this.DOMAIN);
    }

    openApplication(params?:Record<string, string|number>, cb?:(params:any)=>void, settings?:any):void{
        if (!params){
            params={};
        }

        if (settings&&typeof(settings)=='object'){
            for (const item in settings){
                params["bx24_" + item]=settings[item];
            }
        }
        this.sendMessage('openApplication', params, cb);
    }

    openPath(path:string, cb?:(params:any)=>void):void{
        this.sendMessage('openPath', {path:path}, cb);
    }
}