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

const beatData = reactive({
  list: [] as number[],
  len: 0,
  tickEnd: false,
  /** 节拍器时间 */
  beatLengthInMilliseconds: 0,
  loopTime: 0, // 循环时长
  state: '',
  source1: '' as any,
  source2: new Howl({
    src: tockAndTick.tock
  }) as any,
  index: 0,
  show: false
});

let defaultSetting = {} as any

const handlePlay = (i: number, source: any, timer: any) => {
  let payBeatTime = new Date().getTime();
  return new Promise(resolve => {
    if (beatData.tickEnd) {
      resolve(i);
      return;
    }

    let timeSppedEnum = 16.7;
    const proofTime = () => {
      if (defaultSetting.playState !== 'play') {
        return;
      }
      setTimeout(() => {
        if (beatData.tickEnd) {
          resolve(i);
          return;
        }
        const currentTime = new Date().getTime();
        // 两次定时任务时间间隔
        const diffTime = currentTime - payBeatTime;
        if (diffTime >= beatData.loopTime) {
          beatData.index++;
          if (timer.type === 'sound') {
            if (source) source.play();
          }

          resolve(i);
          payBeatTime = currentTime;
        } else {
          if (Math.abs(diffTime - beatData.loopTime) <= timeSppedEnum) {
            // 为了处理最后循环时间，用循环耗时
            for (let index = 0; index < 500000; index++) {
              let forTime = new Date().getTime();
              if (Math.abs(forTime - payBeatTime) >= beatData.loopTime) {
                beatData.index++;
                if (timer.type === 'sound') {
                  if (source) source.play();
                }
                resolve(i);
                payBeatTime = forTime;
                break;
              }
            }
          } else {
            proofTime();
          }
        }
      }, timeSppedEnum);
    };
    proofTime();
  });
};

/** 开始节拍器
 * @param {boolean} 是否开启了设置
 */
export const handleStartBeat = async (settingStatus = false) => {
  const tempSetting = settingStatus ? setting_modal : setting
  defaultSetting = {
    playState: tempSetting.playState,
    speed: tempSetting.speed,
    scorePart: tempSetting.scorePart
  }

  beatData.show = true;
  beatData.tickEnd = false;
  beatData.index = 0;
  beatData.beatLengthInMilliseconds = (60 / defaultSetting.speed) * 1000;
  // let startTime = +new Date();
  for (let i = 0; i < defaultSetting.scorePart.length; i++) {
    if (beatData.tickEnd) return false;
    for (let j = 0; j < defaultSetting.scorePart[i].length; j++) {
      if (beatData.tickEnd) return false;
      // 提前结束, 直接放回false
      const part = defaultSetting.scorePart[i][j];
      const params = {
        ...part,
        ...beatDesc[part.index]
      };
      // console.log(params);
      const single16th = beatData.beatLengthInMilliseconds;
      const source = beatData.source2;
      for (let g = 0; g < params.attribute.length; g++) {
        let time = 0;
        const attr = params.attribute[g];
        // 计算每一拍需要的时长
        // 四分音符 有延音
        switch (attr.number) {
          case 4:
            if (attr.point) {
              time = single16th * 0.5 * 3;
            } else {
              time = single16th;
            }
            break;
          case 8:
            // 连音
            if (params.liaison) {
              time = single16th * (1 / params.beatNum);
            } else if (attr.point) {
              time = single16th * 0.25 * 3;
            } else {
              time = single16th * 0.5;
            }
            break;
          case 16:
            if (params.liaison) {
              time = single16th * (1 / params.beatNum);
            } else {
              time = single16th * 0.25;
            }
            break;
        }

        await handlePlay(i, source, {
          time,
          type: attr.type
        });
        beatData.loopTime = time;
        if (settingStatus) {
          initSelectScorePartModal(i, j)
        } else {
          initSelectScorePart(i, j);
        }

        defaultSetting.playState = settingStatus ? setting_modal.playState : setting.playState
        if (defaultSetting.playState !== 'play') {
          hendleEndBeat(settingStatus)
        }
      }
    }
  }

  // console.log(+new Date() - startTime);
  beatData.show = false;
  handleStartBeat(settingStatus);
  return true;
};

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

/** 节拍器暂停
 * @param {boolean} 是否开启了设置
 */
export const hendleEndBeat = (settingStatus = false) => {
  beatData.tickEnd = true;
  if (settingStatus) {
    initSelectScorePartModal()
  } else {
    initSelectScorePart();
  }
};
