import Cartoon from "./Cartoon"
import defaultData from "./defaultData"
import { jelly } from "./utils"

export default class GameLogic {
  g_cartoon = null;
  g_formData = null
  g_enableClick = true;
  g_canvas = null;
  g_systemOption = null;
  g_useDefaultData = false;
  g_curDragonDisplay = null;
  
  m_questionAudioPlayed = false;
  m_currentQuestion = -1;
  m_questionDone = false;
  m_currentQuestionArray = []
  m_gameEnd = false;
  m_firstEnter = true;

  constructor(formData, systemOption) {
    this.g_systemOption = systemOption;
    this.g_canvas = cc.find('Canvas');
    this.g_cartoon = new Cartoon(cc);

    if(!formData.contentObj.dataArray || formData.contentObj.dataArray.length == 0) {
      this.g_useDefaultData = true;
      this.g_formData = defaultData
      console.warn("User default data =>", this.g_formData)
    } else {
      this.g_formData = formData.contentObj;
      console.log("User saved data =>", this.g_formData)
    }
    
    this.disableClick("Sysyem_init")
    this.g_cartoon.initLocalAudios(["sm_btn", "sm_join"])
    this.initMaskLayer();
    
    this.initBg()
    this.initNodes();
    this.resetPosition();
    this.initTheme();
    this.addEventListener();
    this.initBottomButtons();
    this.initDragonContainers();
    this.initRightImageContainer();
    if(!this.loadQuestion(true)) {
      const btnRestart = this.g_cartoon.getCartoonElement("btn_restart");
      if(this.m_currentQuestion <= -1) {
        btnRestart.node.opacity = 128;
        btnRestart.disable = true;
        console.log("Disable restart")
      } else {
        btnRestart.node.opacity = 255;
        btnRestart.disable = false;
      }
    }
    
    this.enableClick("Sysyem_init_done")

  }

  initNodes() {
  	this.g_cartoon.initCartoonElement("bgMain", this.g_cartoon.getNodeByPath(`Canvas/bgMain`))
  	this.g_cartoon.initCartoonElement("textDragonContainer", this.g_cartoon.getNodeByPath(`Canvas/text_container/DB`))
    this.g_cartoon.initCartoonElement("rightDragonContainer", this.g_cartoon.getNodeByPath(`Canvas/right_container/dragonBones`))
    this.g_cartoon.initCartoonElement("rightImageContainer", this.g_cartoon.getNodeByPath(`Canvas/right_container/imageContainer`))
    
    this.g_cartoon.initCartoonElement(`video_container`, this.g_cartoon.getNodeByPath(`Canvas/video_container`));
    this.g_cartoon.initCartoonElement(`video_container_video`, this.g_cartoon.getNodeByPath(`Canvas/video_container/video`));
    
    this.g_cartoon.initCartoonElement(`bottomButtons`, this.g_cartoon.getNodeByPath(`Canvas/bottomButtons`));
    this.g_cartoon.initCartoonElement(`btn_left`, this.g_cartoon.getNodeByPath(`Canvas/bottomButtons/btn_left`));
    this.g_cartoon.initCartoonElement(`btn_restart`, this.g_cartoon.getNodeByPath(`Canvas/bottomButtons/btn_restart`));
    this.g_cartoon.initCartoonElement(`btn_right`, this.g_cartoon.getNodeByPath(`Canvas/bottomButtons/btn_right`));

    this.g_cartoon.initCartoonElement(`borderTheme_A`, this.g_cartoon.getNodeByPath(`Canvas/bgMain/bg_A`));
    // this.g_cartoon.initCartoonElement(`borderTheme_B`, this.g_cartoon.getNodeByPath(`Canvas/bgMain/bg_B`));
    // this.g_cartoon.initCartoonElement(`borderTheme_C`, this.g_cartoon.getNodeByPath(`Canvas/bgMain/bg_C`));
    this.g_cartoon.initCartoonElement(`borderTheme_D`, this.g_cartoon.getNodeByPath(`Canvas/bgMain/bg_D`));

    this.g_cartoon.initCartoonElement(`videoTheme_A`, this.g_cartoon.getNodeByPath(`Canvas/video_container/bg_A`));
    // this.g_cartoon.initCartoonElement(`videoTheme_B`, this.g_cartoon.getNodeByPath(`Canvas/video_container/bg_B`));
    // this.g_cartoon.initCartoonElement(`videoTheme_C`, this.g_cartoon.getNodeByPath(`Canvas/video_container/bg_C`));
    this.g_cartoon.initCartoonElement(`videoTheme_D`, this.g_cartoon.getNodeByPath(`Canvas/video_container/bg_D`));

    this.g_cartoon.initCartoonElement(`textTheme_A`, this.g_cartoon.getNodeByPath(`Canvas/text_container/bg_A`));
    // this.g_cartoon.initCartoonElement(`textTheme_B`, this.g_cartoon.getNodeByPath(`Canvas/text_container/bg_B`));
    // this.g_cartoon.initCartoonElement(`textTheme_C`, this.g_cartoon.getNodeByPath(`Canvas/text_container/bg_C`));
    this.g_cartoon.initCartoonElement(`textTheme_D`, this.g_cartoon.getNodeByPath(`Canvas/text_container/bg_D`));
  }

  addEventListener() {
    const btnRestart = this.g_cartoon.getCartoonElement("btn_restart");
  	this.g_cartoon.subscribeTouchEvent("bgMain", ()=>{
      if(btnRestart.disable) {
        return
      }
  		this.playCurrentQuestion()
  	})
  }

  initBg() {
    const bgBubble = cc.find('Canvas/bgMain/bubble');
    bgBubble.scale = this.g_systemOption.mapScaleMin;
    // bgBubble.width = cc.winSize.width
    // bgBubble.height = cc.winSize.height

    const bgNode_A = cc.find('Canvas/bgMain/bg_A');
    // bgNode_A.scale = this.g_systemOption.mapScaleMin;
    bgNode_A.width = cc.winSize.width
    bgNode_A.height = cc.winSize.height
    if(this.g_formData.theme == "A") {
      bgNode_A.active = true;
    } else {
      bgNode_A.active = false;
    }

    const bgNode_D = cc.find('Canvas/bgMain/bg_D');
    // bgNode_D.scale = this.g_systemOption.mapScaleMin;
    bgNode_D.width = cc.winSize.width
    bgNode_D.height = cc.winSize.height
    if(this.g_formData.theme == "D") {
      bgNode_D.active = true;
    } else {
      bgNode_D.active = false;
    }

  }

  resetPosition() {
    const bottomButtons = this.g_cartoon.getCartoonElement("bottomButtons");
    bottomButtons.node.y = -cc.winSize.height / 2 + 50
  }

  initTheme() {
    let themeType = this.g_formData.theme;

    let videoTheme_A = this.g_cartoon.getCartoonElement("videoTheme_A")
    // let videoTheme_B = this.g_cartoon.getCartoonElement("videoTheme_B")
    // let videoTheme_C = this.g_cartoon.getCartoonElement("videoTheme_C")
    let videoTheme_D = this.g_cartoon.getCartoonElement("videoTheme_D")

    let textTheme_A = this.g_cartoon.getCartoonElement("textTheme_A")
    // let textTheme_B = this.g_cartoon.getCartoonElement("textTheme_B")
    // let textTheme_C = this.g_cartoon.getCartoonElement("textTheme_C")
    let textTheme_D = this.g_cartoon.getCartoonElement("textTheme_D")

    let borderTheme_A = this.g_cartoon.getCartoonElement("borderTheme_A")
    // let borderTheme_B = this.g_cartoon.getCartoonElement("borderTheme_B")
    // let borderTheme_C = this.g_cartoon.getCartoonElement("borderTheme_C")
    let borderTheme_D = this.g_cartoon.getCartoonElement("borderTheme_D")


    switch(themeType) {
      case "A": 
        videoTheme_A.node.active = true;
        // videoTheme_B.node.active = false;
        // videoTheme_C.node.active = false;
        videoTheme_D.node.active = false;

        textTheme_A.node.active = true;
        // textTheme_B.node.active = false;
        // textTheme_C.node.active = false;
        textTheme_D.node.active = false;

        borderTheme_A.node.active = true;
        // borderTheme_B.node.active = false;
        // borderTheme_C.node.active = false;
        borderTheme_D.node.active = false;
        break;
      case "B":
        videoTheme_A.node.active = false;
        // videoTheme_B.node.active = true;
        // videoTheme_C.node.active = false;
        videoTheme_D.node.active = false;

        textTheme_A.node.active = false;
        // textTheme_B.node.active = true;
        // textTheme_C.node.active = false;
        textTheme_D.node.active = false;

        borderTheme_A.node.active = false;
        // borderTheme_B.node.active = true;
        // borderTheme_C.node.active = false;
        borderTheme_D.node.active = false;

        break;
      case "C":
        videoTheme_A.node.active = false;
        // videoTheme_B.node.active = false;
        // videoTheme_C.node.active = true;
        videoTheme_D.node.active = false;

        textTheme_A.node.active = false;
        // textTheme_B.node.active = false;
        // textTheme_C.node.active = true;
        textTheme_D.node.active = false;

        borderTheme_A.node.active = false;
        // borderTheme_B.node.active = false;
        // borderTheme_C.node.active = true;
        borderTheme_D.node.active = false;

        break;
      case "D":
        videoTheme_A.node.active = false;
        // videoTheme_B.node.active = false;
        // videoTheme_C.node.active = false;
        videoTheme_D.node.active = false;

        textTheme_A.node.active = false;
        // textTheme_B.node.active = false;
        // textTheme_C.node.active = false;
        textTheme_D.node.active = false;

        borderTheme_A.node.active = false;
        // borderTheme_B.node.active = false;
        // borderTheme_C.node.active = false;
        borderTheme_D.node.active = false;

        this.getSpriteFrimeByUrl(this.g_formData.border_image_url).then(sf=>{
          sf.width = cc.winSize.width;
          sf.height = cc.winSize.height;
          borderTheme_D.node.getComponent(cc.Sprite).spriteFrame = sf;
          borderTheme_D.node.active = true;
        }).catch(err=>{
          borderTheme_A.node.active = true;
        })

        this.getSpriteFrimeByUrl(this.g_formData.video_image_url).then(sf=>{
          sf.width = 688;
          sf.height = 353;
          videoTheme_D.node.getComponent(cc.Sprite).spriteFrame = sf;
          videoTheme_D.node.active = true;
        }).catch(err=>{
          videoTheme_A.node.active = true;
        })

        this.getSpriteFrimeByUrl(this.g_formData.text_image_url).then(sf=>{
          sf.width = 602;
          sf.height = 164;
          textTheme_D.node.getComponent(cc.Sprite).spriteFrame = sf;
          textTheme_D.node.active = true;
        }).catch(err=>{
          textTheme_A.node.active = true;
        })
      default:;
    }
  }

  stopCurrentPlaying() {
      let rightDragon = this.g_cartoon.getCartoonElement("rightDragonContainer")
      let videoContainer = this.g_cartoon.getCartoonElement("video_container_video")
      let textContainer = this.g_cartoon.getCartoonElement("textDragonContainer")
      var rightType = this.g_formData.dataArray[this.m_currentQuestion].rightType

      textContainer.dragonBones.stopDragonBones()
      if(rightType != "image") {
        rightDragon.dragonBones.stopDragonBones()
      }

      this.g_cartoon.stopVideo(videoContainer.node.getComponent(cc.VideoPlayer))
      this.g_cartoon.stopAllAudio()
  }

	playCurrentQuestion() {
    const play = ()=>{
      let rightDragon = this.g_cartoon.getCartoonElement("rightDragonContainer")
      let rightImageContainer = this.g_cartoon.getCartoonElement("rightImageContainer")
      var container = this.g_cartoon.getCartoonElement("video_container_video")
      var rightType = this.g_formData.dataArray[this.m_currentQuestion].rightType
      this.g_cartoon.getCartoonElement("textDragonContainer").play()

      if(this.g_formData.dataArray[this.m_currentQuestion].text_audio_url) {
        this.g_cartoon.playAudio(this.g_formData.dataArray[this.m_currentQuestion].text_audio_url)
      }

      this.g_cartoon.playVideo(container.node.getComponent(cc.VideoPlayer), ()=>{
        if(rightType == "image") {
          rightImageContainer.play()
        } else {
          rightDragon.play()
        }
        if(this.g_formData.dataArray[this.m_currentQuestion].right_audio_url) {
          this.g_cartoon.playAudio(this.g_formData.dataArray[this.m_currentQuestion].right_audio_url)
        }
      })
    }

    if(!this.g_formData.dataArray[this.m_currentQuestion].played) {
      this.g_formData.dataArray[this.m_currentQuestion].played = true;
      this.g_cartoon.playAudio("sm_join", () => {
        this.stopCurrentPlaying();
        play()
      })
    } else {
      this.stopCurrentPlaying();
      play()
    }
    
	}

  initVideo() {
    var container = this.g_cartoon.getCartoonElement("video_container_video")
    var video = container.node.getComponent(cc.VideoPlayer)
  }

  initDragonContainers() {
		let textDragon = this.g_cartoon.getCartoonElement("textDragonContainer")
		textDragon.node.opacity = 255;
		textDragon.show = (callBack) => {
  		if(textDragon.node.opacity == 255) {
				if(callBack) {
        	callback()
        }
  		} else {
  			this.g_cartoon.tweenChange(textDragon.node, {opacity: 255}, 0.3, ()=>{
	        if(callBack) {
	        	callback()
	        }
	      });
  		}
  	}

  	textDragon.dragonBonesLoaded = null;
  	textDragon.play = (callback)=>{
  		if(textDragon.dragonBonesLoaded) {
  			textDragon.dragonBonesLoaded.showDragonBones(1, null, ()=>{

  			})
  		}
  	}

  	textDragon.setDragonBones = (dragon, callback) => {
  		if(dragon && dragon.texPngData.url && dragon.skeJsonData.url && dragon.texJsonData.url) {
	      textDragon.dragonBones.setDragonBones(dragon, null, (handle)=>{
	      	textDragon.dragonBonesLoaded = handle;
          if(callback) {
            callback()
          }
	      })
	    } else{
        textDragon.dragonBones.deleteDragonBones()
	    	textDragon.dragonBonesLoaded = null;
        if(callback) {
          callback()
        }
	    }
  	}

  	let rightDragon = this.g_cartoon.getCartoonElement("rightDragonContainer")
  	rightDragon.node.opacity = 255;
  	rightDragon.show = (callBack) => {
  		if(rightDragon.node.opacity == 255) {
				if(callback) {
        	callback()
        }
  		} else {
  			this.g_cartoon.tweenChange(rightDragon.node, {opacity: 255}, 0.3, ()=>{
	        if(callback) {
	        	callback()
	        }
	      });
  		}
  	}

  	rightDragon.dragonBonesLoaded = null;
  	rightDragon.play = (callback)=>{
  		if(rightDragon.dragonBonesLoaded) {
  			rightDragon.dragonBonesLoaded.showDragonBones(1, null, ()=>{

  			})
  		}
  	}

  	rightDragon.setDragonBones = (dragon, callback) => {
  		if(dragon && dragon.texPngData.url && dragon.skeJsonData.url && dragon.texJsonData.url) {
	      rightDragon.dragonBones.setDragonBones(dragon, null, (handle)=>{
	      	// let sx = 498 / handle._animationLoaded.node.width;
	      	// let sy = 98 / handle._animationLoaded.node.height;
	      	// let s = Math.min(sx, sy)
	      	// handle._animationLoaded.node.setScale(s, s)
	      	// handle._animationLoaded.node.width *= s;
	      	// handle._animationLoaded.node.height *= s;

	      	rightDragon.dragonBonesLoaded = handle;
	        // rightDragon.show(()=>{
	        //   handle.showDragonBones(0);
	        // }, ()=>{
	        //   // handle.showDragonBones();
	        // })
          if(callback) {
            callback()
          } 
	      })
	    } else{
        rightDragon.dragonBones.deleteDragonBones()
	    	rightDragon.dragonBonesLoaded = null;
        if(callback) {
          callback()
        }
	    }
  	}
  }

  initRightImageContainer() {
    let imageContainer = this.g_cartoon.getCartoonElement("rightImageContainer");

    imageContainer.node.active = false;
    imageContainer.setImage = (image_url, callback) => {
      this.getSpriteFrimeByUrl(image_url).then(sf=>{
        let rect = sf.getRect()
        let sx = 400 / rect.width;
        let sy = 400 / rect.height;
        let s = Math.min(sx, sy);
        imageContainer.node.setScale(s, s)
        imageContainer.node.getComponent(cc.Sprite).spriteFrame = sf;
        imageContainer.node.active = true;
        if(callback) {
          callback(sf)
        }
      })
    }

    imageContainer.play = (callback) => {
      let sx = imageContainer.node.scaleX
      let sy = imageContainer.node.scaleY

      this.g_cartoon.tweenChange(imageContainer.node, {scaleX: sx * 1.08, scaleY: sy * 1.08}, 0.3, ()=>{
        this.g_cartoon.tweenChange(imageContainer.node, {scaleX: sx, scaleY: sy}, 0.4, ()=>{
        
        })
      })
    }

  }

  loadQuestion(isNext) {
  	if(isNext) {
			this.m_currentQuestion++;
  	} else {
  		this.m_currentQuestion--;
  	}

    this.checkButtonDisable();
  	if(this.m_currentQuestion >= this.g_formData.dataArray.length) {
  		this.m_currentQuestion = this.g_formData.dataArray.length-1
  		return false;
  	} else if(this.m_currentQuestion <= -1) {
			this.m_currentQuestion = 0;
			return false;
  	}

  	let textDragon = this.g_formData.dataArray[this.m_currentQuestion].textDragonBones
  	let rightDragon = this.g_formData.dataArray[this.m_currentQuestion].rightDragonBones

    let p1 = new Promise((resolve, reject) => {
      this.g_cartoon.getCartoonElement("textDragonContainer").setDragonBones(textDragon, ()=>{
        resolve()
      })
    })
  	
    let p2 = null
    if(this.g_formData.dataArray[this.m_currentQuestion].rightType == "image") {
      p2 = new Promise((resolve, reject) => {
        this.g_cartoon.getCartoonElement("rightImageContainer").setImage(this.g_formData.dataArray[this.m_currentQuestion].image_url, ()=>{
          resolve()
        })
      })
    } else {
      p2 = new Promise((resolve, reject) => {
        this.g_cartoon.getCartoonElement("rightDragonContainer").setDragonBones(rightDragon, ()=>{
          resolve()
        })
      })
    }
    

    this.g_formData.dataArray[this.m_currentQuestion]
    let video = this.g_cartoon.getCartoonElement("video_container_video")
    let p3 = new Promise((resolve, reject) => {
      if(this.g_formData.dataArray[this.m_currentQuestion].video_url) {
        video.node.active = true;
        this.g_cartoon.getVideo(this.g_formData.dataArray[this.m_currentQuestion].video_url).then((clip=>{
          video.node.getComponent(cc.VideoPlayer).clip = clip
          resolve()
        }))
      } else {
        video.node.active = false;
        resolve()
      }
    })

    return Promise.all([p1, p2, p3])
  }

	initBottomButtons() {
		const btnLeft = this.g_cartoon.getCartoonElement("btn_left");
		const btnRight = this.g_cartoon.getCartoonElement("btn_right");
		const btnRestart = this.g_cartoon.getCartoonElement("btn_restart");

		this.g_cartoon.subscribeTouchEvent(btnLeft.key, ()=>{
			if(btnLeft.disable) {
				return
			}
      this.g_cartoon.playAudio("sm_btn");
			this.disableClick("btn_left")
      this.stopCurrentPlaying();
			jelly(btnLeft.node)
			this.showMaskLayer(()=>{
				this.loadQuestion(false).then(()=>{
          this.hideMaskLayer(()=>{
            this.playCurrentQuestion()
            this.enableClick("btn_left")
          })
        })
			})
		})

		this.g_cartoon.subscribeTouchEvent(btnRight.key, ()=>{
			if(btnRight.disable) {
				return
			}
      this.g_cartoon.playAudio("sm_btn");
			this.disableClick("btn_right")
      this.stopCurrentPlaying();
			jelly(btnRight.node)
			this.showMaskLayer(()=>{
				this.loadQuestion(true).then(()=>{
          this.hideMaskLayer(()=>{
            this.playCurrentQuestion()
            this.enableClick("btn_right")
          })
        })
			})
		})

		this.g_cartoon.subscribeTouchEvent(btnRestart.key, ()=>{
      if(btnRestart.disable) {
        return
      }
			jelly(btnRestart.node)
      this.g_cartoon.playAudio("sm_btn");
			this.playCurrentQuestion()
		})
	}

	checkButtonDisable() {
		const btnLeft = this.g_cartoon.getCartoonElement("btn_left");
		const btnRight = this.g_cartoon.getCartoonElement("btn_right");
    const btnRestart = this.g_cartoon.getCartoonElement("btn_restart");

		console.log("Check button disabe " + this.m_currentQuestion)

    if(this.m_currentQuestion <= -1) {
      btnRestart.node.opacity = 128;
      btnRestart.disable = true;
      console.log("Disable restart")
    } else {
      btnRestart.node.opacity = 255;
      btnRestart.disable = false;
    }

		if(this.m_currentQuestion <= 0) {
			btnLeft.node.opacity = 128;
			btnLeft.disable = true;
      console.log("Disable left")
		} else {
			btnLeft.node.opacity = 255;
			btnLeft.disable = false;
		}

		if(this.m_currentQuestion >= this.g_formData.dataArray.length-1) {
			btnRight.node.opacity = 128;
			btnRight.disable = true;
      console.log("Disable right")
		} else {
			btnRight.node.opacity = 255;
			btnRight.disable = false;
		}		
	}
  










  // Common function
  maskLayer = null;
  initMaskLayer() {
    const parentNode = this.g_cartoon.getNodeByPath("MaskLayer")
    parentNode.x = cc.winSize.width / 2
    parentNode.y = cc.winSize.height / 2
    const bNode = this.getSprNodeByResName('black');
    bNode.scaleX = cc.winSize.width / bNode.width;
    bNode.scaleY = cc.winSize.height / bNode.height;
    bNode.x = 0
    bNode.y = 0
    parentNode.setSiblingIndex(255)
    bNode.parent = cc.find('MaskLayer');
    bNode.active = false;
    this.maskLayer = bNode;
  }

  showMaskLayer(cb) {
    this.maskLayer.opacity = 0;
    this.maskLayer.active = true;
    cc.tween(this.maskLayer)
      .to(0.5, {opacity: 255}, {easing: 'sineOut'})
      .call(() => {
        cb()
      })
      .start()
  }

  hideMaskLayer(cb = null) {
    this.maskLayer.opacity = 255;
    cc.tween(this.maskLayer)
    .to(0.5, {opacity: 0}, {easing: 'sineIn'})
    .call(() => {
      this.maskLayer.active = false;
      if (cb) {
        cb()
      }
    })
    .start()
  }



  // Common API
  getSpriteFrimeByUrl(url) {
    return new Promise((resolve, reject) => {
      if(!url) {
        reject()
      } else {
        cc.assetManager.loadRemote(url, (err, img) => {
          if(err) {
            reject(err)
          } else {
            const spriteFrame = new cc.SpriteFrame(img)
            resolve(spriteFrame)
          }
        })
      }
    })
  }

  getSpriteFrimeByResName(name) {
    const sf = cc.find('Canvas/res/img/' + name).getComponent(cc.Sprite).spriteFrame;
    // const node = new cc.Node();
    // node.addComponent(cc.Sprite).spriteFrame = sf;
    return sf;
  }

  getSprNodeByUrl(resName) {
    return new Promise((resolve, reject) => {
      cc.assetManager.loadRemote(url, (err, img) => {
        const node = new cc.Node();
        const spriteFrame = new cc.SpriteFrame(img)
        node.addComponent(cc.Sprite).spriteFrame = sf;
        resolve(node)
      })
    })
  }

  getSprNodeByResName(resName) {
    const sf = cc.find('Canvas/res/img/' + resName).getComponent(cc.Sprite).spriteFrame;
    const node = new cc.Node();
    node.addComponent(cc.Sprite).spriteFrame = sf;
    return node;
  }



  // Sysyem function
  checkClickEnable(eventName) {
    if(this.g_enableClick) {
      return true;
    } else {
      console.log(`Click disabled by event [${this.g_disableClickEventName}]!`)
      return false;
    }
  }

  disableClick(eventName) {
    this.g_enableClick = false;
    this.g_disableClickEventName = eventName
    // console.log(`Click disabled! [${eventName}]`)
  }

  enableClick(eventName) {
    this.g_enableClick = true;
    this.g_disableClickEventName = ""
    // console.log(`Click enabled! [${eventName}]`)
  }

}
