import { reactive } from 'vue';
import tockAndTick from './tockAndTick.json';
import { Howl } from 'howler';
import { initSelectScorePart, setting } from './setting';
import { beatDesc } from './beat-desc';

const tickData = reactive({
  list: [] as number[],
  len: 0, // 有几拍
  afterBeat: 0, // 一小节里面有几拍
  tickEnd: false,
  /** 节拍器时间 */
  beatLengthInMilliseconds: 0,
  state: '',
  source1: '' as any,
  source2: '' as any,
  index: 0,
  show: false
});

let diffTime = 0; // 每一次节拍时间差
const handlePlay = (i: number, source: any) => {
  let payBeatTime = new Date().getTime();
  return new Promise(resolve => {
    if (tickData.tickEnd) {
      resolve(i);
      return;
    }
    let timeSppedEnum = 16.7;
    const proofTime = () => {
      if (setting.playState !== 'play') {
        return;
      }
      setTimeout(() => {
        const currentTime = new Date().getTime();
        // 两次定时任务时间间隔
        const diffTime = currentTime - payBeatTime;
        if (diffTime >= tickData.beatLengthInMilliseconds) {
          tickData.index++;
          if (source) source.play();
          resolve(i);
          payBeatTime = currentTime;
        } else {
          if (
            Math.abs(diffTime - tickData.beatLengthInMilliseconds) <=
            timeSppedEnum
          ) {
            // 为了处理最后循环时间，用循环耗时
            for (let index = 0; index < 500000; index++) {
              let forTime = new Date().getTime();
              if (
                Math.abs(forTime - payBeatTime) >=
                tickData.beatLengthInMilliseconds
              ) {
                tickData.index++;
                if (source) source.play();
                resolve(i);
                payBeatTime = forTime;
                break;
              }
            }
          } else {
            proofTime();
          }
        }
      }, timeSppedEnum);
    };
    proofTime();
  });
};

/** 设置节拍器
 * @param beatLengthInMilliseconds 节拍间隔时间
 * @param beat 节拍数
 */
export const handleInitTick = (
  beatLengthInMilliseconds: number,
  beat: number,
  afterBeat: number
) => {
  tickData.state = '';
  tickData.beatLengthInMilliseconds = beatLengthInMilliseconds;
  tickData.len = beat;
  tickData.afterBeat = afterBeat;
};

/** 开始节拍器 */
export const handleStartTick = async () => {
  tickData.show = true;
  tickData.tickEnd = false;
  if (tickData.state !== 'ok') {
    tickData.source1 = new Howl({
      src: tockAndTick.tick
    });
    tickData.source2 = new Howl({
      src: tockAndTick.tock
    });
    tickData.state = 'ok';
  }
  tickData.index = 0;
  tickData.beatLengthInMilliseconds = (60 / setting.speed) * 1000;

  if (tickData.afterBeat === 8) {
    tickData.beatLengthInMilliseconds = tickData.beatLengthInMilliseconds * 0.5;
  }

  for (let i = 0; i < setting.scorePart.length; i++) {
    if (tickData.tickEnd) return false;
    const temp = setting.scorePart[i];
    let len = temp.length;
    if (tickData.afterBeat === 8) {
      len = tickData.len;
    }

    for (let j = 0; j < len; j++) {
      // 提前结束, 直接放回false
      if (tickData.tickEnd) return false;
      const source =
        j === 0 ? tickData.source1 : j === len ? null : tickData.source2;

      await handlePlay(j, source);
      if (tickData.afterBeat === 8) {
        initSelectScorePart(i, Math.floor((j <= 0 ? 1 : j) / 3));
      } else {
        initSelectScorePart(i, j);
      }
    }
  }

  // console.log(+new Date() - startTime);
  tickData.show = false;
  handleStartTick();
  return true;
};

/** 节拍器暂停 */
export const hendleEndTick = () => {
  tickData.tickEnd = true;
  initSelectScorePart();
};
