import {
	Game,
	TouchSprite,
	RandomInt,
	MyLabel,
	blinkItem,
	stopBlinkItem,
	asyncDelayTime,
	asyncTweenChange,
} from './Game';

import {
	Label,
	jelly,
	showPopParticle,
	tweenChange,
	rotateItem,
	scaleItem,
	delayCall,
	hideItem,
	showItem,
	moveItem,
	shake,
	ShapeRect,
} from './../Unit';

import TWEEN from '@tweenjs/tween.js';

import { defaultData } from './DefaultData';


export class MyGame extends Game {

	images = null;

	data = null;
	status = null;

	initData(data) {
		this.images = data.images;

		this.status = {};

		if (!data.data || Object.is(data.data, {}) || !data.data.tittle) {
			this.data = defaultData;
		} else {
			this.data = data.data;

			let imgUrlList = [];
			let audioUrlList = [];

			imgUrlList = imgUrlList.filter((data) => data != null && data != '');

			audioUrlList.push(this.data.audio);
			audioUrlList.push(this.data.tittle.audio);
			audioUrlList.push(...this.data.questions.map(question => question.audio));
			audioUrlList.push(...this.data.questions.map(question => question.blocks.map(block => block.audio)).flat(Infinity));

			audioUrlList = audioUrlList.filter((data) => data != null && data != '');

			this.preLoadData(imgUrlList, audioUrlList);
		}
	}

	preLoadData(imgUrlList, audioUrlList) {
		imgUrlList.forEach((data) => {
			this._parent.addUrlToImages(data);
		});
		audioUrlList.forEach((data) => {
			this._parent.addUrlToAudioObj(data);
		});
	}

	initView() {
		// 初始化背景
		this.initBg();

		// 初始化标题
		this.initTittle();

		// 初始化中间部分
		this.initMiddle();

		// 游戏开始
		this.gameStart();
	}

	bg = null;
	initBg() {
		this.removeChild(this.getChildByName('bg'));

		let screenSize = this.getScreenSize();
		let defaultSize = this.getDefaultScreenSize();

		let bgSized1 = new TouchSprite();
		bgSized1.init(this.images.get('Img_bg'));
		bgSized1.anchorX = 0.5;
		bgSized1.anchorY = 1;
		bgSized1.setPosition(screenSize.width / 2, screenSize.height);
		bgSized1.setScaleXY(this.getFullScaleXY());
		this.addChild(bgSized1);

		// 背景
		let bg = new TouchSprite();
		bg.init(this.images.get('Img_bg'));
		bg.setScaleXY(this._parent.mapScale);
		bg.alpha = 0;
		bg.anchorX = 0.5;
		bg.anchorY = 0;
		bg.setPosition(screenSize.width / 2, 0);
		bg.setName('bg');
		this.addChild(bg);

		this.bg = bg;

		let bgMask = new TouchSprite();
		bgMask.init(this.images.get('Img_bg'));
		bgMask.setScaleXY(this._parent.mapScale);
		bgMask.anchorX = 0.5;
		bgMask.anchorY = 0;
		bgMask.setPosition(screenSize.width / 2 + bg.width * this._parent.mapScale, 0);
		bgMask.setName('bgMask');
		this.addChild(bgMask);

		let bgMask2 = new TouchSprite();
		bgMask2.init(this.images.get('Img_bg'));
		bgMask2.setScaleXY(this._parent.mapScale);
		bgMask2.anchorX = 0.5;
		bgMask2.anchorY = 0;
		bgMask2.setPosition(screenSize.width / 2, (bg.height - 50) * this._parent.mapScale);
		bgMask2.setName('bgMask2');
		this.addChild(bgMask2);


		const bgRect = new ShapeRect();
		bgRect.setSize(57, 65);
		bgRect.fillColor = '#f8c224';
		const sx = screenSize.width / this._parent.canvasBaseW;
		bgRect.setScaleXY(sx);
		bgRect.x = 65 * sx;
		bgRect.alpha = 0;
		this._parent.renderArr.push(bgRect);
		this.bgRect = bgRect;
	}

	bgRect = null;
	getTittleBlockPositionX() {
		return this.bgRect.x + 28.5 * this.bgRect.scaleX;
	}

	initTittle() {

		let tittleLongBlock = new TouchSprite();
		tittleLongBlock.init(this.images.get('Img_tittle_bg'));
		tittleLongBlock.setScaleXY(this._parent.mapScale);
		tittleLongBlock.setPositionX(this.getScreenSize().width / 2);
		tittleLongBlock.setPositionY(31 * this._parent.mapScale);
		tittleLongBlock.scaleX = this.getScreenSize().width / tittleLongBlock.width;
		this.addChild(tittleLongBlock);

		// 标题字母背景
		let tittleWordBg = new TouchSprite();
		tittleWordBg.init(this.images.get('Img_tittleBg'));
		tittleWordBg.setScaleXY(this._parent.mapScale);
		tittleWordBg.setPosition(this.getTittleBlockPositionX(), 31 * this._parent.mapScale);
		this.addChild(tittleWordBg);


		// 标题字母
		let tittleWord = new MyLabel();
		tittleWord.fontSize = 48;
		tittleWord.fontName = 'BerlinSansFBDemi-Bold';
		tittleWord.fontColor = '#ab5b22';
		tittleWord.text = this.data.tittle.word;
		tittleWord.anchorX = 0.5;
		tittleWord.anchorY = 0.5;
		tittleWord.setPosition(0, 0);

		tittleWordBg.addChild(tittleWord);
		tittleWord.refreshSize();

		// 标题文字
		let questionLabel = new MyLabel();
		questionLabel.fontSize = 36;
		questionLabel.fontName = 'FuturaBT-Bold';
		questionLabel.fontColor = '#000000';
		questionLabel.text = this.data.tittle.text;
		questionLabel.anchorX = 0;
		questionLabel.anchorY = 0.5;
		questionLabel.setPosition(50, 0);

		questionLabel.addTouchBeganListener(() => {
			this.onClickTittle();
		});

		tittleWordBg.addChild(questionLabel);
		questionLabel.refreshSize();
	}

	initMiddle() {
		this.createQuestions();
		this.createScrollBar();
		this.createTittle();
		this.createWholeAudioBtn();
	}

	createTittle() {
		// 标题文字
		let tittleLabel = new MyLabel();
		tittleLabel.fontSize = 48;
		tittleLabel.fontName = 'BerlinSansFBDemi-Bold';
		tittleLabel.fontColor = '#70401e';
		tittleLabel.text = this.data.questionsTittle;
		tittleLabel.anchorX = 0.5;
		tittleLabel.anchorY = 0.5;
		tittleLabel.setPosition(0, 120);

		tittleLabel.addTouchBeganListener(() => {
			this.playAudio(this.data.tittleAudio);
		});

		this.bg.addChild(tittleLabel);
		tittleLabel.refreshSize();
	}

	scrollBaseNode;
	createQuestions() {

		let scrollViewBg = new TouchSprite();
		scrollViewBg.init(this.images.get('Img_white'));
		scrollViewBg.scaleX = 1200 / scrollViewBg.width;
		scrollViewBg.scaleY = 580 / scrollViewBg.height;
		scrollViewBg.setPosition(0, this.bg.height / 2 + 100);
		scrollViewBg.addTouchBeganListener(this.onScrollViewBgTouchBegan.bind(this));
		scrollViewBg.addTouchMoveListener(this.onScrollViewBgTouchMoved.bind(this));
		scrollViewBg.alpha = 0.1;
		scrollViewBg.setName('scrollViewBg');
		this.bg.addChild(scrollViewBg);

		let scrollBaseNode = new TouchSprite();
		scrollBaseNode.init(this.images.get('Img_white'));
		scrollBaseNode.anchorX = 0.5;
		scrollBaseNode.anchorY = 0;
		this.bg.addChild(scrollBaseNode);
		this.scrollBaseNode = scrollBaseNode;

		console.log('this.data.questions.length = ' + this.data.questions.length);

		this.data.questions.forEach((question, idx) => {

			let baseNode = new TouchSprite();
			baseNode.setPositionX(120 - this.bg.width / 2);
			baseNode.setPositionY(idx * 85 + 200);
			baseNode.setName('question_' + idx);
			scrollBaseNode.addChild(baseNode);

			let labelList = [];
			if (question.words != '') {
				question.words.match(/(([a-z]|[A-Z]|[0-9]|'|-|&|_)+|.)/g).forEach((word, wordIdx) => {

					let block = question.blocks.find(block => block.idx == wordIdx);

					let posX = labelList.reduce((offsetX, label, labelIdx) => {
						if (labelIdx < wordIdx) {
							return offsetX + label.width;
						} else {
							return offsetX;
						}
					}, 0);

					let questionLabel = new MyLabel();
					questionLabel.fontSize = 42;
					questionLabel.fontName = 'MMTextBook';
					questionLabel.fontColor = '#070408';
					questionLabel.text = word;

					let match = word.match(/(([a-z]|[A-Z]|[0-9])+)/);

					if (match && block && block.type == 'bold') {
						questionLabel.fontName = 'MMTextBook-Bold';
					}
					if (match && block && block.type == 'red') {
						questionLabel.fontColor = '#c8161e';
						questionLabel.set('audio', block.audio);
						questionLabel.addTouchBeganListener(() => this.onClickWord(questionLabel));

						let labelImg = new TouchSprite();
						labelImg.init(this.images.get(block.img));
					}

					questionLabel.refreshSize();
					questionLabel.setPositionX(posX + questionLabel.width / 2);
					baseNode.addChild(questionLabel, 2);
					labelList.push(questionLabel);
				});
			}

			if (question.questionTittle != '') {
				let questionTittle = new MyLabel();
				questionTittle.fontSize = 42;
				questionTittle.fontName = 'MMTextBook';
				questionTittle.fontColor = '#070408';
				questionTittle.text = question.questionTittle + '. ';
				questionTittle.anchorX = 1;
				questionTittle.anchorY = 0.5;
				questionTittle.refreshSize();

				baseNode.addChild(questionTittle);
			}

			if (question.audio != '') {
				let offsetX = labelList.reduce((offsetX, label) => { return offsetX + label.width }, 0);
				this._createSpeacker(
					this.images.get('Btn_s_play'),
					this.images.get('Btn_s_pause'),
					baseNode,
					{
						x: offsetX + 50,
						y: 0
					},
					this.getAudioObj(question.audio)
				);
			}
		});
	}

	onClickWord(block) {
		if (block.get('moved')) {
			return;
		}
		block.set('moved', true);

		block.setScaleXY(3);
		tweenChange(block, { scaleX: 1, scaleY: 1 }, 0.5, () => {
			this.playAudio(block.get('audio'));
		}, TWEEN.Easing.Cubic.In);
		tweenChange(block, { alpha: 1 }, 0.5, null, TWEEN.Easing.Quintic.In);
	}

	createScrollBar() {
		if (this.data.questions.length <= 6) {
			return;
		}

		let scrollBg = new TouchSprite();
		scrollBg.init(this.images.get('Img_scroll_bg'));
		scrollBg.setPositionX(this.bg.width / 2 - 150);
		scrollBg.setPositionY(this.bg.height / 2 + 60);
		scrollBg.setName('scrollBg');
		scrollBg.scaleY = (this.bg.height - 240) / scrollBg.height;

		this.bg.addChild(scrollBg);

		let scrollBar = new TouchSprite();
		scrollBar.init(this.images.get('Img_scroll_bar'));
		scrollBar.anchorY = 0;
		scrollBar.scaleY = (6 / this.data.questions.length) * scrollBg.height * scrollBg.scaleY / scrollBar.height;
		scrollBar.setPositionX(this.bg.width / 2 - 150);
		scrollBar.setPositionY(183);
		scrollBar.setName('scrollBar');
		scrollBar.addTouchBeganListener(this.onScrollBarTouchBegan.bind(this));
		scrollBar.addTouchMoveListener(this.onScrollBarTouchMoved.bind(this));
		this.bg.addChild(scrollBar);

		let bgMaskRight = new TouchSprite();
		bgMaskRight.init(this.images.get('Img_bg'));
		bgMaskRight.setPositionX(this.bg.width - 143);
		bgMaskRight.setPositionY(this.bg.height / 2 + 60);
		this.bg.addChild(bgMaskRight);

		let bgMaskUp = new TouchSprite();
		bgMaskUp.init(this.images.get('Img_bg'));
		bgMaskUp.setPositionX(0);
		bgMaskUp.setPositionY(0 - 190);
		this.bg.addChild(bgMaskUp);

		let bgMaskDown = new TouchSprite();
		bgMaskDown.init(this.images.get('Img_bg'));
		bgMaskDown.setPositionX(0);
		bgMaskDown.setPositionY(this.bg.height * 2 - 190);
		bgMaskDown.alpha = 1;
		this.bg.addChild(bgMaskDown);
	}

	updateScrollBar(rate) {
		let scrollBg = this.bg.getChildByName('scrollBg');
		let scrollBar = this.bg.getChildByName('scrollBar');
		scrollBar.setPositionY(183 + (scrollBg.height * scrollBg.scaleY - scrollBar.height * scrollBar.scaleY - 8) * rate);
	}

	updateScrollView(rate) {
		this.scrollBaseNode.setPositionY(((this.data.questions.length - 6) * -85) * rate);
	}

	onScrollViewBgTouchBegan(touchPos) {
		this.scrollBaseNode.set('beginPos', { x: this.scrollBaseNode.x, y: this.scrollBaseNode.y });
		this.scrollBaseNode.set('beginTouchPos', touchPos);
	}

	onScrollViewBgTouchMoved(touchPos) {
		let beginPos = this.scrollBaseNode.get('beginPos');
		let beginTouchPos = this.scrollBaseNode.get('beginTouchPos');

		let rate = (beginPos.y + (touchPos.y - beginTouchPos.y)) / (-85 * (this.data.questions.length - 6));
		rate = Math.min(Math.max(rate, 0), 1);
		this.updateScrollView(rate);
		this.updateScrollBar(rate);
	}

	onScrollBarTouchBegan(pos) {
		let scrollBar = this.bg.getChildByName('scrollBar');
		scrollBar.set('beginPos', { x: scrollBar.x, y: scrollBar.y });
		scrollBar.set('beginTouchPos', pos);
	}

	onScrollBarTouchMoved(touchPos) {
		let scrollBg = this.bg.getChildByName('scrollBg');
		let scrollBar = this.bg.getChildByName('scrollBar');
		let beginPos = scrollBar.get('beginPos');
		let beginTouchPos = scrollBar.get('beginTouchPos');

		let rate = (beginPos.y + (touchPos.y - beginTouchPos.y) - 183) / (scrollBg.height * scrollBg.scaleY - scrollBar.height * scrollBar.scaleY - 8);
		rate = Math.min(Math.max(rate, 0), 1);
		this.updateScrollView(rate);
		this.updateScrollBar(rate);
	}

	createWholeAudioBtn() {
		let pos = {
			x: this.bg.width / 2 - 70,
			y: this.bg.height - 100
		};

		this._createSpeacker(
			this.images.get('Btn_play'),
			this.images.get('Btn_pause'),
			this.bg,
			pos,
			this.getAudioObj(this.data.audio)
		);
	}

	_createSpeacker(playImg, pauseImg, parentNode, pos, audio) {
		const speaker = new TouchSprite();
		speaker.init(playImg);
		speaker.setPosition(pos);
		speaker.addTouchBeganListener(() => this._onClickSpeaker(speaker));
		parentNode.addChild(speaker);

		const speakerPause = new TouchSprite();
		speakerPause.init(pauseImg);
		speakerPause.setPosition(pos);
		speakerPause.addTouchBeganListener(() => this._onClickSpeakerPause(speakerPause));
		speakerPause.alpha = 0;
		parentNode.addChild(speakerPause);

		speaker.set('_audio', audio);
		speaker.set('_speakerPause', speakerPause);

		speakerPause.set('_audio', audio);
		speakerPause.set('_speaker', speaker);
	}

	_currentSpeaker;
	_onClickSpeaker(speaker) {
		const audio = speaker.get('_audio');
		if (!audio) {
			return;
		}

		if (this._currentSpeaker) {
			this._onClickSpeakerPause(this._currentSpeaker.get('_speakerPause'), true);
		}

		const speakerPause = speaker.get('_speakerPause');
		audio.onended = () => {
			this._showSpeaker(speaker, speakerPause);
			this._currentSpeaker = null;
		};
		audio.play();
		this._currentSpeaker = speaker;

		this._showPauser(speaker, speakerPause);
		jelly(speaker);
		jelly(speakerPause);
	}

	_onClickSpeakerPause(speakerPause, unJellyFlg = false) {
		const audio = speakerPause.get('_audio');
		if (!audio) {
			return;
		}
		audio.pause();

		const speaker = speakerPause.get('_speaker');
		this._showSpeaker(speaker, speakerPause);
		if (!unJellyFlg) {
			jelly(speaker);
			jelly(speakerPause);
		}
	}

	_showSpeaker(speaker, speakerPause) {
		tweenChange(speaker, { alpha: 1 }, 0.3);
		tweenChange(speakerPause, { alpha: 0 }, 0.3);
	}
	_showPauser(speaker, speakerPause) {
		tweenChange(speaker, { alpha: 0 }, 0.3);
		tweenChange(speakerPause, { alpha: 1 }, 0.3);
	}

	printCurrentStatus() {
		console.log(JSON.stringify(this.status));
	}

	onClickTittle() {
		this.playAudio(this.data.tittle.audio);
	}

	gameStart() {
		this.playIncomeAudio();
		this.income();
	}

	playIncomeAudio() {
		this.playAudio('audio_new_page');
	}

	income() {
		this.data.questions.forEach(async (question, idx) => {
			let baseNode = this.bg.seekChildByName('question_' + idx);
			baseNode.setPositionX(120 + this.bg.width / 2);
			baseNode.setPositionY(idx * 85 + 200);
			await asyncDelayTime(0.1 * idx);
			await asyncTweenChange(baseNode, {
				x: 120 - this.bg.width / 2,
				y: idx * 85 + 200
			}, 0.5, TWEEN.Easing.Quadratic.Out);
		});
	}
}
