class EosMgr {
	private static _instance: EosMgr;

	static get instance(): EosMgr {
		if (!this._instance) {
			this._instance = new EosMgr();
		}
		return this._instance;
	}
	private isTop: boolean = (window == top);
	public scatter: any = null;
	public identity: any = null;
	public eos: any = null;

	register(): void {
		if (this.isTop) {
			this.scatterLoad();
			top.addEventListener('scatterLoaded', this.scatterLoad);
		} else {
			EOS_VUE.$getEosInfo();
			window.addEventListener('message', this.onMessage.bind(this), false);
		}
	}

	public constructor() {
	}

	private onMessage(ev: MessageEvent): void {
		if (ev.data.login) {
			let accounts = ev.data.login;
			UserMgr.instance.setAccount(accounts);
			GameMgr.instance.createdGame && SocketMgr.instance.closeSocket();
		} else if (ev.data.logout) {
			UserMgr.instance.setAccount(null);
			UserMgr.instance.setCoin({ balance: 0, gt: 0 });
			SocketMgr.instance.closeSocket();
		} else if (ev.data.coin) {
			UserMgr.instance.setCoin(ev.data.coin);
		} else if (ev.data.doDeposit) {
			Bet.instance.betSucc(ev.data);
		} else if (ev.data.doDepositFail) {
			Bet.instance.betFail();
		}
	}

	async login() {
		if (this.isTop) {
			if (!this.scatter) {
				DEBUG && console.log('installScatter');
				return
			}
			let identity = await this.scatter.getIdentity({ accounts: [this.getNetwork()] })
			if (identity) {
				let accounts = identity.accounts.find(x => x.blockchain === 'eos');
				UserMgr.instance.setAccount(accounts);
				this.getEos(this.scatter)
			}
		} else {
			EOS_VUE.$scatterLogin();
		}
	}

	async scatterLoad() {
		if (!top['scatter']) {
			return;
		}
		let scatter = top['scatter']
		await this.getIdentity(scatter);

		if (this.identity) {
			let accounts = this.identity.accounts.find(x => x.blockchain === 'eos');
			UserMgr.instance.setAccount(accounts);
			this.getEos(scatter)
		}
		this.scatter = scatter;
		top['scatter'] = null;
		top.removeEventListener('scatterLoaded', this.scatterLoad);
	}

	async getIdentity(scatter) {
		try {
			this.identity = await scatter.getIdentity({ accounts: [this.getNetwork()] })
		} catch (err) {
			if (err.isError) {
				return;
			}
		}
	}

	async getEos(scatter) {
		this.eos = scatter.eos(this.getNetwork(), Eos, {})
	}

	async getBalance() {
		if (this.identity) {
			return await this.eos.getCurrencyBalance('eosio.token', this.identity.account.name, 'EOS')
		} else {
			return 0;
		}
	}

	async  getNewPermissions(accountName) {
		if (!this.eos) {
			DEBUG && console.log('not login');
			return;
		}
		const account = await this.eos.getAccount(accountName);
		const perms = JSON.parse(JSON.stringify(account.permissions));
		return perms;
	}

	// EOS配置
	private getNetwork(): networkConfig {
		if (/^test-|\.webdev2\./.test(location.host) || location.host == '0.0.0.0:8080' || location.host.indexOf('172.16.14') >= 0) {
			return {
				protocol: 'http',
				blockchain: 'eos',
				port: '7777',
				host: '61.160.36.19',
				chainId: 'cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f'
			}
		} else {
			return {
				protocol: 'https',
				blockchain: 'eos',
				port: '443',
				host: 'nodes.get-scatter.com',
				chainId: 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906'
			}
		}
	}

	// 下注
	transfer(name: string, toAccount: string, amount: number, memo: string, options: any) {
		return new Promise((resolve, reject) => {
			this.eos.transfer(name, toAccount, amount + ' EOS', memo, options).then(trx => {
				DEBUG && console.log('confirmBet succ');
				resolve(trx);
			}).catch(msg => {
				console.error('confirmBet error:', msg);
				reject(msg);
			})
		})
	}
}