
// 兼容缩放自适应
(function (doc, win) {
  window.base = document.documentElement.clientWidth / 1920;
  var docEl = doc.documentElement,
    resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
    recalc = function () {
      window.clientWidth = docEl.clientWidth;
      window.clientHeight = docEl.clientHeight;
      var aspectRatio = window.clientWidth / window.clientHeight;
      if (aspectRatio > 1920 / 1080) {
        docEl.style.fontSize = 100 * (window.clientHeight / 1080) + 'px';
        window.base = 100 * (window.clientHeight / 1080);
      } else {
        docEl.style.fontSize = 100 * (window.clientWidth / 1920) + 'px';
        window.base = 100 * (window.clientWidth / 1920);
        // 判断是否为移动设备，提示旋转屏幕
      }
    };
  recalc();
  win.addEventListener(resizeEvt, recalc, false);
  doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);

var cw = window.courseware;

//对应模板的名称，这个可以不写，但是最好是能写上，同时开发多个模板的情况下如果不写这个，本地缓存可能会存在混乱
var key = "JM-07";

var USERINFO = null;

var ROLE = null;

var defaultData = '{"stuImage":"http://staging-teach.cdn.ireadabc.com/0623b0c0d8b1da234f64959a8826e113.jpg","video":"http://staging-teach.cdn.ireadabc.com/bcb8b751b98371ea71956a1d1a447956.mp4"}';

// 资源
var rawImages = new Map();
var rawAudios = new Map();

var images = new Map();

var audioObj = {};

// 维护切面数据
var teaUserAspect = {
  isSendQuestion: false, // 是否是答题环节
  bindData: null,
  totalTime: 0
};
var stuUserAspect = {
  speed: 1,//播放速度
  videoCurTime: 0,//播放进度
  recorderScoreObj: null, // 这块只记录一个最好的成绩
  recorderArr: [],//录音记录
  recorderTimeLenArr: [],//录音时长
  isPause: true,
  firstClickRecorder: true, //是否第一次点击录音
  firstClickCancel: true,//是否第一次点击撤销按钮
  isEnd: false,
  isDelTemp: false,//是否删除临时录音
};

//进度条刷新是否启动
var started = false;

var tempRecorder;

$(function () {

  window.courseware.getData(function (data, aspect) {


    USERINFO = window.air.airClassInfo.user;
    ROLE = USERINFO.classRole;

    // 初始化 音频资源
    initAudio(data);

    // 初始化 图片资源
    initImg(data);

    loadResources().then(() => {
      const playView = new PlayView(data);

      playView.init();

      if (aspect) {
        recoverPage(aspect);
      }

      //初始化监听事件
      initListener();

      //在页面加载、事件、动画等都初始化完成后，一定要记得调用此方法，否则模板将是不可用的
      window.air.hideAirClassLoading(key, this.data);
    });

  }, key);

})

function loadResources() {
  const pr = [];
  rawImages.forEach((value, key) => {// 预加载图片

    const p = preload(value)
      .then(img => {
        images.set(key, img);
      })
      .catch(err => console.log(err));

    pr.push(p);
  });

  rawAudios.forEach((value, key) => {// 预加载音频

    const a = preloadAudio(value)
      .then(() => {
        // this.images.set(key, img);
      })
      .catch(err => console.log(err));

    pr.push(a);
  });
  return Promise.all(pr);
}

function preload(url) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    // img.crossOrigin = "anonymous";
    img.onload = () => resolve(img);
    img.onerror = reject;
    img.src = url;
  });
}

function preloadAudio(url) {
  return new Promise((resolve, reject) => {
    const audio = new Audio();
    audio.oncanplay = (a) => {
      resolve(a);
    };
    audio.onerror = () => {
      reject();
    };
    audio.src = url;
    audio.load();
  });
}

function addUrlToAudioObj(key, url = null, vlomue = 1, loop = false, callback = null) {

  const audioObj = this.audioObj;

  if (url == null) {
    url = key;
  }

  rawAudios.set(key, url);

  const audio = new Audio();
  audio.src = url;
  audio.load();
  audio.loop = loop;
  audio.volume = vlomue;

  audioObj[key] = audio;

  if (callback) {
    audio.onended = () => {
      callback();
    };
  }
}

function playAudio(key, now = false, callback = null) {

  const audio = audioObj[key]; console.log(audio);
  if (audio) {

    if (now) {
      audio.pause();
      audio.currentTime = 0;
    }

    if (callback) {
      audio.onended = () => {
        callback();
      };
    }
    audio.play();
  }

  return audio;
}

function initAudio(data) {

  this.addUrlToAudioObj('submit', "../lib/redio/submit.mp3");
  this.addUrlToAudioObj('click', "../lib/redio/click.mp3");
  this.addUrlToAudioObj('fade', "../lib/redio/fade.mp3");
}

function initImg(data) {

}

class PlayView {

  data;

  constructor(data) {
    this.data = data;
  }

  init() {

    // 若无数据 则为预览模式 需要填充一些默认数据用来显示
    this.initDefaultData();

    this.initData();

    this.initView();

  }

  initDefaultData() {

    if (!this.data) {
      this.data = JSON.parse(defaultData);
    }

    console.log(this.data);

  }


  initData() {
    teaUserAspect.bindData = this.data;
  }

  initView() {

    if (this.data.video) {
      $(".video").attr("src", this.data.video);

      const video = $("#video")[0];
      let i = setInterval(() => {

        if (video.readyState > 0) {
          let totalTime = getTimeStr(video.duration);

          $(".total-time").empty();
          $(".total-time").append(totalTime);

          if (ROLE == 'tea') {
            teaUserAspect.totalTime = video.duration;

            cw.storeAspect(teaUserAspect);
          }

          clearInterval(i);
        }
      }, 100);


    }

    if (this.data.stuImage) {
      $("#stuimage").attr("src", this.data.stuImage);
    }

    if (this.data.title) {
      $(".title").empty();
      $(".title").append(this.data.title);
    }

    $("#keyWord").val(this.data.keyWord);

    if (ROLE == "tea") {
      $("[role='tea']").show(); // 老师特定的页面

      //绑定sent事件
      bindSentBtn();
    }
    else {

      bindRecorderBtn();

      bindSpeedBtn();

      bindBackBtn();

      bindSubmitBtn();

      bindContinueBtnBtn();

      bindConfirmBtn();

     $(".hello-container").show();

      //$("#submitBtn").show();
      //$("#exercise").show();
      // 学生特定的页面
      $("[role='stu']").show();
    }


  }
}

/**
 * 
 * @param {*} aspect 断线恢复
 */
function recoverPage(aspect) {

  if (ROLE == "tea") {
    // 解析切面数据
    if (!aspect.user_aspect) {
      return;
    }
    teaUserAspect = aspect.user_aspect && JSON.parse(aspect.user_aspect);
    if (teaUserAspect.isSendQuestion) {
      $(".sent-btn").hide();
    }
  }
  else {
    // 解析切面数据
    const tea = aspect.all_user.find(item => item.user.classRole == "tea");
    if (!tea || !tea.aspect) {
      return;
    }
    const teaAspect = JSON.parse(tea.aspect);
    //没有答题，则结束
    if (!teaAspect.isSendQuestion) {
      return;
    }

    //隐藏欢迎界面
    $(".hello-container").hide();

    const stuAspect = aspect.user_aspect && JSON.parse(aspect.user_aspect);
    console.log(aspect);
    if (stuAspect) {
      stuUserAspect = stuAspect;

      cw.storeAspect(stuUserAspect);

      //设置速度
      setSpeed(stuUserAspect.speed);

      //已经结束，就显示结束画面
      if (stuUserAspect.isEnd) {

        let score = stuUserAspect.recorderScoreObj;

        drawResult(score.result, score.text);
      }
      else {


        let recorderArr = stuUserAspect.recorderArr;

        let videoCurTime = stuUserAspect.videoCurTime;

        $("#curTime").empty();
        $("#curTime").append(getTimeStr(videoCurTime));

        //已经录制
        if (recorderArr.length > 0) {
          let length = recorderArr.length;

          let last = recorderArr[length - 1];

          $("#submitBtn").show();

          //如果没有删除最后一段，则显示删除按钮
          if (stuUserAspect.isDelTemp) {
            //重新绘画进度条
            drawProgress($("#progressbar"), last.endTime, teaAspect.totalTime);
          }
          else {

            //重新绘画进度条
            drawProgress($("#tempProgressbar"), last.endTime - last.startTime, teaAspect.totalTime);
            drawProgress($("#progressbar"), last.startTime - 0, teaAspect.totalTime);

            $("#backBtn").show();

            if (!stuUserAspect.firstClickCancel) {
              $(".back-tips").hide();
            }
            else {
              $(".back-tips").show();
            }
          }

          if (!stuUserAspect.firstClickRecorder) {
            $(".recorder-tips").hide();
          }
        }


        const video = $("#video")[0];
        if (video) {
          video.currentTime = videoCurTime;
        }

        $("#exercise").show();
      }
    }
  }
}

// 视频播放按钮
function bindVideoPlayBtn() {
  bindPressAnimation($(".video-play-icon"));
  $("#video")[0].addEventListener('ended', function () {
    // 监听视频播放结束
    $(".video-play-icon .control").removeClass("pause").addClass("play");
  });
  $("#video")[0].addEventListener('pause', function () {
    // 监听视频播放结束
    $(".video-play-icon .control").removeClass("pause").addClass("play");
  });
  $(".video-play-icon").on('click touchend', function () {
    const video = $("#video")[0];
    const control = $(".video-play-icon .control");
    const status_ = control.hasClass("play");
    if (status_) {
      video.play();
      control.removeClass("play").addClass("pause");
    } else {
      video.pause();
      control.removeClass("pause").addClass("play");
    }
  });
}

// 录音按钮
let tempTimeLen = 0;
function bindRecorderBtn() {
  bindPressAnimation($(".recorder-play-icon"));

  //结束录音处理
  const endRecord = () => {
    const control = $(".recorder-play-icon .control");
    $("#ani").hide();
    $(".recorder-play-icon .recorder-pause").hide();
    control.addClass("recorder-play");

    let curTime = $("#video")[0].currentTime;
    tempRecorder.endTime = curTime;
    if (started) {
      //直接绘制结束
      drawProgress($("#tempProgressbar"), curTime - tempRecorder.startTime, $("#video")[0].duration);
      clearInterval(started);
    }

    cw.stopRecord(0, function (data) {
      //录完后，显示撤销按钮
      if (stuUserAspect.firstClickCancel) {
        $(".back-tips").show();
      }

      tempRecorder.data = data;

      $("#backBtn").show();

      $("#submitBtn").show();

      //将当前时间保存到切片中
      stuUserAspect.videoCurTime = curTime;

      stuUserAspect.isPause = true;
      stuUserAspect.recorderArr.push(tempRecorder);
      stuUserAspect.recorderTimeLenArr.push(Date.now() - tempTimeLen);

      stuUserAspect.isDelTemp = false;

      //保存切片
      cw.storeAspect(stuUserAspect);
    })
  }

  $("#video")[0].addEventListener('ended', function () {
    // 监听视频播放结束
    $(".video-play-bg").hide();

    endRecord();
  });

  $(".recorder-play-icon").on('click touchend', function () {

    $(".video-cover").hide();

    playAudio('click', true);

    if (stuUserAspect.firstClickRecorder) {
      $(".recorder-tips").hide();
      stuUserAspect.firstClickRecorder = false;
    }

    const control = $(".recorder-play-icon .control");
    const status_ = control.hasClass("recorder-play");

    let keyWord = $("#keyWord").val();

    //开始录制
    if (status_) {

      //隐藏按钮
      $("#backBtn").hide();
      $(".back-tips").hide();
      $("#ani").show();
      $("#submitBtn").hide();
      
      //绘制滚动条
      drawProgress($("#progressbar"), $("#video")[0].currentTime , $("#video")[0].duration);

      drawProgress($("#tempProgressbar"), 0, $("#video")[0].duration);


      control.removeClass("recorder-play");
      $(".recorder-play-icon .recorder-pause").show();

      //当前时间
      let startTime = $("#video")[0].currentTime;

      tempRecorder = {
        startTime: startTime,
        endTime: startTime
      }

      $("#video")[0].play();
      stuUserAspect.isPause = false;

      //刷新进度条
      refreshProgress();

      //开始录制
      tempTimeLen = Date.now();
      cw.startRecord(keyWord);
    } else {

      $("#video")[0].pause();

      endRecord();

    }


  });


}

// 绑定点击效果
function bindPressAnimation(_dom, cssName = null) {

  let css = 'press';

  if (cssName) {
    css = cssName;
  }

  _dom.mousedown(function () {
    $(this).addClass(css);
  }).mouseup(function () {
    $(this).removeClass(css);
  }).mouseout(function () {
    $(this).removeClass(css);
  })
  _dom.on("touchstart", function (e) {
    e.preventDefault();
    $(this).addClass(css);
  }).on("touchend", function (e) {
    e.preventDefault();
    $(this).removeClass(css);
  })
}

function getTimeStr(time) {
  if (!time) {
    return "00:00";
  }

  let sec = Math.ceil(time % 60);

  let minute = Math.floor(time / 60);

  let timeStr = (minute < 10 ? "0" + minute : minute) + ":" + (sec < 10 ? "0" + sec : sec);

  return timeStr;
}

function bindSpeedBtn() {

  setSpeed(stuUserAspect.speed);

  $(".speed-choice").on('click touchend', function () {

    $(".speed-choice").removeClass('speed-active');

    $(this).addClass('speed-active');

    const video = $("#video")[0];

    let speed = $(this).attr('data-speed');
    stuUserAspect.speed = speed;

    if (video) {
      video.playbackRate = speed;
    }

    //保存切片
    cw.storeAspect(stuUserAspect);

  });
}

function setSpeed(speed) {

  $("#exercise").find(".speed-choice").removeClass('speed-active');

  $.each($("#exercise").find(".speed-choice"), function (i, item) {
    let value = $(item).attr("data-speed");

    if (value == speed) {
      $(item).addClass('speed-active');
      const video = $("#video")[0];
      if (video) {
        video.playbackRate = speed;
      }
      return;
    }
  });
}

function bindSentBtn() {

  bindPressAnimation($(".sent-btn"));

  $(".sent-btn").on('click touchend', function () {

    playAudio('click', true);

    //设置已经发题
    teaUserAspect.isSendQuestion = true;

    $(this).hide();

    cw.sendEvent('sendQuestion', teaUserAspect);
  });
}

function initListener() {
  cw.onEvent('sendQuestion', (data, next) => {
    if (ROLE == "tea") {

    } else {
      stuUserAspect.currentWordIndex = data.currentWordIndex;

      $(".hello-container").hide();

      $("#exercise").show();

      cw.storeAspect(stuUserAspect);
    }
    next();
  });
}

function bindBackBtn() {

  const backBtn = $("#backBtn");

  bindPressAnimation(backBtn);

  backBtn.on('click touchend', function () {

    $(".video-play-bg").show();

    playAudio('click', true);
    if (stuUserAspect.firstClickCancel) {
      $(".back-tips").hide();
      stuUserAspect.firstClickCancel = false;
    }

    stuUserAspect.recorderTimeLenArr.pop(); //移除录音时长
    var recorder = stuUserAspect.recorderArr.pop();

    if (recorder) {
      const video = $("#video")[0];
      //视频时间回滚
      video.currentTime = recorder.startTime;
      $("#curTime").empty();
      $("#curTime").append(getTimeStr(video.currentTime));
      //重新绘画进度条
      drawProgress($("#tempProgressbar"), 0, video.duration);

      stuUserAspect.isDelTemp = true;

      stuUserAspect.videoCurTime = video.currentTime;
    }

    if (stuUserAspect.recorderArr.length == 0) {
      $("#submitBtn").hide();
    }

    //保存切片
    cw.storeAspect(stuUserAspect);

    $(this).hide();
  })
}

function bindSubmitBtn() {

  const submitBtn = $("#submitBtn");

  bindPressAnimation(submitBtn);

  submitBtn.on('click touchend', function () {
    playAudio('submit', true);
    $("#submitDialog").modal('show');
  });
}

/**
 * 刷新进度条
 */

function refreshProgress() {

  started = setInterval(() => {
    if (stuUserAspect.isPause) {
      return;
    }

    const video = $("#video")[0];

    let curTime = video.currentTime;
    let duration = curTime - tempRecorder.startTime;

    $("#curTime").empty();
    $("#curTime").append(getTimeStr(curTime))

    drawProgress($("#tempProgressbar"), duration, video.duration);
  }, 100);
}

function drawProgress(progressbar, duration, totalTime) {

  let progress = 0;

  if (totalTime && totalTime != 0) {
    progress = Math.floor(duration / totalTime * 100 * 100) / 100;
  }

  progressbar.attr('data-value', progress);

  progressbar.css("width", progress + "%");
}

/**
 * 继续录制操作
 */
function bindContinueBtnBtn() {

  $('#submitDialog').on('shown.bs.modal', function (e) {
    playAudio('fade', true);
  })

  const continueBtn = $("#continueBtn");
  bindPressAnimation(continueBtn, 'submit-press');
  continueBtn.on('click touchend', function () {
    playAudio('click', true);
    $("#submitDialog").modal('hide');
  })

}

/**
 * 确认提交事件
 */
function bindConfirmBtn() {
  const confirmBtn = $("#confirmBtn");
  bindPressAnimation(confirmBtn, 'submit-press');
  confirmBtn.on('click touchend', function () {

    playAudio('click', true);

    $("#submitDialog").modal('hide');

    let recorderArr = stuUserAspect.recorderArr;
    let text = "";

    for (let i = 0; i < recorderArr.length; ++i) {

      let data = JSON.parse(recorderArr[i].data);
      text += " " + data.text;
    }

    cw.greadPapersForText(text, function (data) {

      stuUserAspect.recorderScoreObj = {
        result: data,
        text: text
      };
      stuUserAspect.isEnd = true;

      //保存切片
      cw.storeAspect(stuUserAspect);

      //画结束界面
      drawResult(data, text);

    });


  })
}

function drawResult(data, text) {

  $("#exercise").hide();
  $("#result").show();

  let temp = JSON.parse(data);
  const timeLen = stuUserAspect.recorderTimeLenArr.reduce((a, b) => a + b, 0);
  let { integrity, fluency } = scoreByText(text, $("#keyWord").val(), timeLen);

  $("#complete").text(Math.floor(integrity * 100));
  $("#fluent").text(Math.floor(fluency * 100));
  $("#grammar").text(temp.overall);

  let score = Math.floor(integrity * 60 + fluency * 20 + (temp.overall - 0) * 0.20);

  let imgSrc = "";
  let tips = "";
  let fontColor = '';

  if (score >= 90) {
    imgSrc = "../lib/images/excellent.png";
    tips = 'Excellent!'
    fontColor = 'excellent';
  }
  else if (score >= 76) {
    imgSrc = "../lib/images/great.png";
    tips = 'Great!'
    fontColor = 'great';
  }
  else {
    imgSrc = "../lib/images/nicetry.png";
    tips = 'Nice try!'
    fontColor = 'nicetry';
  }

  const {annotationHtml, evaluateHtml} = annotation(text, temp.detail);
  $(".tips").empty().append(tips).addClass(fontColor);
  $("#medal").attr('src', imgSrc);
  $("#score").empty().append(score);
  $("#recorder-text").html(annotationHtml);
  $("#evaluation").html(evaluateHtml);

  // 上报成绩
  cw.sendAnswer({
    "duration": timeLen,
    "recorderArr": stuUserAspect.recorderArr,
    "score": score,
    "complete": Math.floor(integrity * 100),
    "fluent": Math.floor(fluency * 100),
    "grammar": temp.overall,
    "detail": temp.detail
  }); 
}

function insertString(string, insert, index){
  return string.substring(0, index)+insert+string.substr(index);
}

function annotation(text, detail){
  let annotationHtml = "";
  const allFeatureAdvice = detail.AllFeatureAdvice;
  let evaluateHtml = `${allFeatureAdvice.WordDiversity};${allFeatureAdvice.Structure};${allFeatureAdvice.Spelling};${allFeatureAdvice.Grammar}<br>`;
  const sentsFeedbacks = detail.essayFeedback.sentsFeedback;

  let num = 0;
  for (let i = 0; i < sentsFeedbacks.length; i++) {
    const feedBack = sentsFeedbacks[i];
    let rawSent = feedBack.rawSent;

    const errorPosInfos = feedBack.errorPosInfos;
    for(let j=errorPosInfos.length-1; j>=0; j--){
      const errPos = errorPosInfos[j];
      const startPos = errPos.startPos;
      rawSent = insertString(rawSent, `<span class="err-grammar-number">${num+j+1}</span>`, startPos);
    }
    annotationHtml += rawSent;
    for(let j=0; j<errorPosInfos.length; j++){
      const errPos = errorPosInfos[j];
      const reason = errPos.reason;
      evaluateHtml += `<br><span class="err-grammar-index">${num+j+1}</span>&nbsp;${reason}`;
    }
    num += errorPosInfos.length;
  }
  return {annotationHtml, evaluateHtml};

}

function scoreByText(text, keyWords, timeLen) {
  const smallText = text.toLowerCase();
  let detailArr = [];
  if(keyWords){
    detailArr = keyWords.toLowerCase().split(",");
  }
  const mainArr = [];

  const speakedDetailWordArr = [];
  let detailLastIndex = -1;
  for (let i = 0; i < detailArr.length; i++) {
    const index = smallText.indexOf(detailArr[i]);
    if (index != -1) {

      speakedDetailWordArr.push({ index, text: detailArr[i] });
      if (detailLastIndex == -1 || index > detailLastIndex) {
        detailLastIndex = index;
      }
    }
  }

  const speakedMainWordArr = [];
  let mainFirstIndex = -1;
  for (let i = 0; i < mainArr.length; i++) {
    const index = smallText.indexOf(mainArr[i]);
    if (index != -1) {

      speakedMainWordArr.push({ index, text: mainArr[i] });
      if (mainFirstIndex == -1 || index < speakedMainWordArr) {
        mainFirstIndex = index;
      }
    }
  }

  const speakedCount = speakedDetailWordArr.length + speakedMainWordArr.length;
  const targetSpeakCount = detailArr.length + mainArr.length;
  const rate1 = speakedCount / targetSpeakCount;

  const integrity = Math.round(rate1 * 100) / 100; // 完整度


  const time = timeLen / 1000;
  const textArr = text.split(' ');
  const baseNum = textArr.length / (time / 60);
  const targetNum = 90; // 语速
  let rate2 = baseNum / targetNum;
  if (rate2 > 1) {
    rate2 = 1;
  }

  const fluency = Math.round(rate2 * 100) / 100; // 流利度

  return {
    integrity: integrity || 0, 
    fluency: fluency || 0
  };
}
