<template>
  <div>
    <el-form ref="form" :model="form" label-width="150px">
      <el-form-item
        prop="sysMusicScore.name"
        label="曲名"
        :rules="[{ required: true, message: '请输入曲名' }]"
      >
        <el-input placeholder="请输入曲名" v-model="form.sysMusicScore.name" />
      </el-form-item>
      <el-form-item
        prop="sysMusicScore.musicScoreCategoriesId"
        label="分类"
        :rules="[{ required: true, message: '请选择分类' }]"
      >
        <el-cascader
          v-model="form.sysMusicScore.musicScoreCategoriesId"
          style="width: 100%"
          :options="tree"
          placeholder="请选择分类"
          :props="treeProps"
        ></el-cascader>
        <!-- <el-select style="width: 100%!important;" v-model="form.sysMusicScore.musicScoreCategoriesId" placeholder="请选择声部">
          <el-option
            v-for="item in selects.subjects"
            :value="item.id"
            :label="item.name"
            :key="item.id"
          ></el-option>
        </el-select> -->
      </el-form-item>
      <!-- 是否收费  免费  收费 -->
      <el-form-item
        prop="rankIdType"
        label="是否收费"
        :rules="[{ required: true, message: '请选择是否收费' }]"
      >
        <el-select
          style="width: 100% !important"
          v-model="form.rankIdType"
          placeholder="请选择是否收费"
          @change="rankChange"
        >
          <!-- <el-option
            :value="item.id"
            :label="item.name"
            v-for="item in memberRankList"
            :key="item.id"
          ></el-option> -->
          <el-option :value="0" label="免费"></el-option>
          <el-option :value="1" label="收费"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item
        prop="sysMusicScore.isOpenMetronome"
        label="节拍器"
        :rules="[{required: true, message: '请选择节拍器'}]"
      >
        <template slot="label">
          <span>
            节拍器
            <el-tooltip placement="top" popper-class="mTooltip">
              <div slot="content">
                是否播放系统自带节拍器
              </div>
              <i
                class="el-icon-question"
                style="font-size: 18px; color: #f56c6c"
              ></i>
            </el-tooltip>
          </span>
        </template>
        <el-select
          style="width: 100% !important"
          v-model="form.sysMusicScore.isOpenMetronome"
          placeholder="请选择节拍器"
        >
          <!-- <el-option
            :value="item.id"
            :label="item.name"
            v-for="item in memberRankList"
            :key="item.id"
          ></el-option> -->
          <el-option
            :value="0"
            label="不播放"
          ></el-option>
          <el-option
            :value="1"
            label="播放"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item
        label="重复节拍时长"
      >
        <template slot="label">
          <span>
            重复节拍时长
            <el-tooltip placement="top" popper-class="mTooltip">
              <div slot="content">
                2/4拍类似的节拍器是否重复时长
              </div>
              <i
                class="el-icon-question"
                style="font-size: 18px; color: #f56c6c"
              ></i>
            </el-tooltip>
          </span>
        </template>
        <el-select
          style="width: 100% !important"
          v-model="form.repeatedBeats"
          placeholder="请选择是否重复节拍器时长"
        >
          <el-option
            :value="0"
            label="不重复"
          ></el-option>
          <el-option
            :value="1"
            label="重复"
          ></el-option>
        </el-select>
      </el-form-item>
      <!-- <el-form-item
        prop="sysMusicScore.clientType"
        label="客户端类型"
        :rules="[{ required: true, message: '请选择客户端类型' }]"
      >
        <el-select
          style="width: 100% !important"
          v-model="form.sysMusicScore.clientType"
          placeholder="请选择客户端类型"
        >
          <el-option value="NETWORK_ROOM" label="网络教室"></el-option>
          <el-option value="SMART_PRACTICE" label="云教练"></el-option>
        </el-select>
      </el-form-item> -->
      <!-- <el-form-item
        prop="sysMusicScore.renderFrom"
        label="渲染模式"
        :rules="[{ required: true, message: '请选择渲染模式' }]"
      >
        <el-select
          style="width: 100% !important"
          v-model="form.sysMusicScore.renderFrom"
          placeholder="请选择渲染模式"
        >
          <el-option value="H5" label="H5"></el-option>
          <el-option value="APP" label="原生"></el-option>
        </el-select>
      </el-form-item> -->
      <el-form-item
        prop="sysMusicScore.playMode"
        label="播放模式"
        :rules="[{ required: true, message: '请选择播放模式' }]"
      >
        <el-select
          style="width: 100% !important"
          v-model="form.sysMusicScore.playMode"
          placeholder="请选择播放模式"
        >
          <el-option value="MP3" label="MP3播放"></el-option>
          <el-option value="XML" label="XML播放"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item
        prop="sysMusicScore.enableEvaluation"
        label="支持评测"
        :rules="[{ required: true, message: '请选择支持评测' }]"
      >
        <el-radio-group v-model="form.sysMusicScore.enableEvaluation">
          <el-radio :label="1">是</el-radio>
          <el-radio :label="0">否</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item
        prop="sysMusicScore.order"
        label="排序"
        :rules="[{ required: true, message: '请输入排序' }, {
              pattern: /^([1-9]\d*|[0]{1,1})$/,
              message: '请输入正确的排序',
              trigger: 'blur',
            },]"
      >
        <el-input placeholder="请输入排序" v-model="form.sysMusicScore.order" />
      </el-form-item>
      <el-form-item
      v-if="form.sysMusicScore.isOpenMetronome ===1"
        label="伴奏(不含节拍器)"
        prop="sysMusicScore.url"
      >
        <singe-file-upload
          tips="仅支持上传 mp3/aac 格式音频文件"
          accept=".mp3, .aac"
          v-model="form.sysMusicScore.url"
          bucket_name="cloud-coach"
        />
      </el-form-item>
      <el-form-item
      v-else
        label="伴奏(含节拍器)"
        prop="sysMusicScore.metronomeUrl"
      >
        <singe-file-upload
          tips="仅支持上传 mp3/aac 格式音频文件"
          accept=".mp3, .aac"
          v-model="form.sysMusicScore.metronomeUrl"
            bucket_name="cloud-coach"
        />
      </el-form-item>
      <el-form-item
        label="MIDI"
        prop="sysMusicScore.midiUrl"
      >
        <singe-file-upload
          tips="仅支持上传 mid 格式音频文件"
          accept=".mid"
          v-model="form.sysMusicScore.midiUrl"
            bucket_name="cloud-coach"
        />
      </el-form-item>

      <div v-if="gradual && gradual.length">
        <el-alert :closable="false" style="margin-bottom: 20px;">识别到共{{gradual.length}}处渐变速度，请输入Dorico对应小节时间信息</el-alert>
        <div v-for="item in gradual">
          <el-form-item
            :label="item[0].measureIndex + 2 + ' 小节'"
            :rules="[{required: true, message: '请输入合奏曲目时间'}, {
              pattern: /^((\d{2}):?){2,3}$/,
              message: '请输入正确的曲目时间',
              trigger: 'blur',
            }]"
            :prop="`graduals.${item[0].measureIndex}`"
          >
            <el-input placeholder="00:00:00" v-model="form.graduals[item[0].measureIndex]"></el-input>
          </el-form-item>
          <el-form-item
            :label="item[1].measureIndex + 2 + ' 小节'"
            :rules="[{required: true, message: '请输入合奏曲目时间'}, {
              pattern: /^((\d{2}):?){2,3}$/,
              message: '请输入正确的曲目时间',
              trigger: 'blur',
            }]"
            :prop="`graduals.${item[1].measureIndex}`"
          >
            <el-input placeholder="00:00:00" v-model="form.graduals[item[1].measureIndex]"></el-input>
          </el-form-item>
        </div>
      </div>

      <div
        class="files"
        v-for="(song, index) in form.sysMusicScoreAccompaniments"
        :key="index"
      >
        <el-row>
          <el-col :span="12">
            <el-form-item
              :prop="`sysMusicScoreAccompaniments.${index}.subjectId`"
              label="声部"
            >
              <!-- :rules="[{required: true, message: '请选择声部'}]" -->
              <el-select
                style="width: 100% !important"
                v-model="song.subjectId"
                clearable
                placeholder="请选择声部"
              >
                <el-option
                  v-for="item in selects.subjects"
                  :value="item.id"
                  :label="item.name"
                  :key="item.id"
                  :disabled="hasSubjectId(item.id)"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item
              :prop="`sysMusicScoreAccompaniments.${index}.speed`"
              label="速度"
              :rules="[{ required: true, message: '请输入速度' }]"
            >
              <el-input
                type="number"
                placeholder="请输入速度"
                v-model="song.speed"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item
              :prop="`sysMusicScoreAccompaniments.${index}.isShowFingering`"
              label="指法展示"
              :rules="[{ required: true, message: '请选择是否展示指法' }]"
            >
              <el-select
                style="width: 100% !important"
                v-model="song.isShowFingering"
                placeholder="请选择是否展示指法"
              >
                <el-option :value="true" label="是"></el-option>
                <el-option :value="false" label="否"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item
              :prop="`sysMusicScoreAccompaniments.${index}.memo`"
              label="描述"
            >
              <el-input placeholder="请输入描述" v-model="song.memo" />
            </el-form-item>
          </el-col>
          <el-col :span="12"  v-if="form.sysMusicScore.isOpenMetronome ===1">
            <el-form-item

              label="原音(不含节拍器)"
              :prop="`sysMusicScoreAccompaniments.${index}.mp3Url`"
              :rules="[
                {
                  required: form.sysMusicScore.isOpenMetronome ? form.sysMusicScore.playMode === 'MP3' : false,
                  message: '请上传原音(不含节拍器)',
                },
              ]"
            >
              <singe-file-upload
                tips="仅支持上传 mp3/aac 格式音频文件"
                accept=".mp3, .aac"
                v-model="song.mp3Url"
                  bucket_name="cloud-coach"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-else>
            <el-form-item
              label="原音(含节拍器)"
              :prop="`sysMusicScoreAccompaniments.${index}.metronomeMp3Url`"
              :rules="[
                {
                  required: form.sysMusicScore.isOpenMetronome ? false : form.sysMusicScore.playMode === 'MP3',
                  message: '原音(含节拍器)',
                },
              ]"
            >
              <singe-file-upload
                tips="仅支持上传 mp3/aac 格式音频文件"
                accept=".mp3, .aac"
                v-model="song.metronomeMp3Url"
                  bucket_name="cloud-coach"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item
              label="MusicXML"
              :prop="`sysMusicScoreAccompaniments.${index}.xmlUrl`"
              :rules="[{ required: true, message: '请选择MusicXML文件' }]"
            >
              <singe-file-upload
                tips="仅支持上传 xml 格式文件"
                accept=".xml"
                v-model="song.xmlUrl"
                @inputFile="inputFile"
                  bucket_name="cloud-coach"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="partListNames.length > 1">
            <el-form-item
              label="所属轨道"
              :prop="`sysMusicScoreAccompaniments.${index}.track`"
              :rules="[{ required: true, message: '请选择所属轨道' }]"
            >
              <el-select
                style="width: 100% !important"
                v-model="song.track"
                clearable
                placeholder="请选择轨道"
              >
                <el-option
                  v-for="item in partListNames"
                  :value="item"
                  :label="item"
                  :key="item"
                  :disabled="hasPartName(item)"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-button
          class="file-remove"
          type="text"
          @click="removeSys(index)"
          :disabled="form.sysMusicScoreAccompaniments.length == 1"
          >删除</el-button
        >
      </div>
      <el-button
        @click="createSys"
        type="info"
        style="width: 100%; margin-bottom: 20px"
        plain
        >添加原音</el-button
      >
      <div class="btns">
        <el-button type="primary" @click="submit">提交</el-button>
        <el-button @click="$listeners.close">取消</el-button>
      </div>
    </el-form>
  </div>
</template>
<script>
import axios from 'axios'
import { Add, Update, queryPageSysExam, queryTree } from "../api";
import { getAllmemberRank } from "@/views/resetTeaming/api";
const initailExtConfigJson = {
  repeatedBeats: 0
}
export default {
  props: ["detail", "type"],
  data() {
    return {
      gradual: null,
      xmlFirstSpeed: '',
      partListNames: [],
      tree: [],
      extConfigJson: {},
      memberRankList: [], // 会员列表
      form: {
        graduals: {},
        rankIdType: 0, // 收费会员类型 默认免费
        repeatedBeats: 0, // 重复节拍
        sysMusicScore: {
          isOpenMetronome: 0, // 是否开启节拍器 默认关闭
          name: "",
          rankIds: "", // 收费会员编号
          url: "",
          metronomeUrl: "",
          midiUrl: "",
          order: "",
          musicScoreCategoriesId: [],
          // 兼容之前数据，默认选择云教练
          clientType: "SMART_PRACTICE",
          renderFrom: "",
          playMode: "MP3",
          enableEvaluation: 1,
          extConfigJson: "{}"
        },
        sysMusicScoreAccompaniments: [
          {
            subjectId: "",
            speed: "",
            mp3Url: "",
            xmlUrl: "",
            isShowFingering: true,
            mome: "",
            track: ""
          },
        ],
        delExamSongAccompanimentIds: [],
      },
      treeProps: {
        value: "id",
        label: "name",
        children: "sysMusicScoreCategoriesList",
      },
    };
  },
  async mounted() {
    this.$store.dispatch("setSubjects");
    await this.FetchTree();
    await this.memberRank();
    if (this.detail) {
      try {
        this.extConfigJson = JSON.parse(this.detail.extConfigJson);
      } catch (error) {
        this.extConfigJson = {...initailExtConfigJson}
      }
      this.form.repeatedBeats = this.extConfigJson.repeatedBeats;
      this.form.graduals = this.extConfigJson.gradualTimes || {};
      this.$set(this.form, "sysMusicScore", {
        isOpenMetronome:Number(this.detail.isOpenMetronome),
        name: this.detail.name,
        url: this.detail.url,
        midiUrl: this.detail.midiUrl,
        rankIds: this.detail.rankIds,
        order: this.detail.order,
        clientType: this.detail.clientType,
        enableEvaluation: +this.detail.enableEvaluation,
        metronomeUrl: this.detail.metronomeUrl,
        renderFrom: this.detail.renderFrom,
        playMode: this.detail.playMode,
        musicScoreCategoriesId: this.detail.categoriesId
          ? this.formatParentId(this.detail.categoriesId, this.tree)
          : [],
      });
      if (this.detail.rankIds) {
        this.form.rankIdType = 1;
      } else {
        this.form.rankIdType = 0;
      }
      const xmlres = await axios(this.detail.xmlUrl)
      this.gradual = getGradualLengthByXml(xmlres.data).filter(item => item.length === 2)
      this.partListNames = this.getPartListNames(xmlres.data)
      this.FeatchDetailList();
    } else {
      // 新增条件下默认设置为收费
      this.rankChange(1);
      this.form.rankIdType = 1;
    }
  },
  methods: {
    getPartListNames(xml) {
      if (!xml) return []
      const xmlParse = new DOMParser().parseFromString(xml, 'text/xml')
      const partList = xmlParse.getElementsByTagName('part-list')?.[0]?.getElementsByTagName('score-part') || []
      const partListNames = Array.from(partList).map(item => item.getElementsByTagName('part-name')?.[0].textContent || '')
      this.xmlFirstSpeed = xmlParse.getElementsByTagName('per-minute')?.[0]?.textContent || ''
      return partListNames.filter(text => text.toLocaleUpperCase() !== 'COMMON')
    },
    inputFile(file) {
      const xmlRead = new FileReader()
      xmlRead.onload = res => {
        this.partListNames = this.getPartListNames(res.target.result)
        this.gradual = getGradualLengthByXml(res.target.result).filter(item => item.length === 2)
        for (let j = 0; j < this.form.sysMusicScoreAccompaniments.length; j++) {
          this.form.sysMusicScoreAccompaniments[j].track =  this.partListNames[j]
          if (!this.form.sysMusicScoreAccompaniments[j].speed) {
            this.form.sysMusicScoreAccompaniments[j].speed = this.xmlFirstSpeed
          }
          this.$set(this.form, 'sysMusicScoreAccompaniments', this.form.sysMusicScoreAccompaniments)
        }
        for (let index = this.form.sysMusicScoreAccompaniments.length; index < this.partListNames.length; index++) {
          const part = this.partListNames[index]
          const sysData = {
            ...this.form.sysMusicScoreAccompaniments[0],
            metronomeMp3Url: "",
            mp3Url: "",
            track: part,
          }
          if (!sysData.speed) {
            sysData.speed = this.xmlFirstSpeed
          }
          this.createSys(sysData)
        }
      }
      xmlRead.readAsText(file.raw)
    },
    rankChange(value) {
      if (value) {
        let tempIds = [];
        this.memberRankList.forEach((item) => {
          tempIds.push(item.id);
        });
        this.form.sysMusicScore.rankIds = tempIds.join(",");
      } else {
        // 会员购买重置
        this.form.sysMusicScore.rankIds = "";
      }
    },
    async memberRank() {
      try {
        const res = await getAllmemberRank({ isDefault: 0 });
        this.memberRankList = res.data || [];
      } catch (e) {
        console.log(e);
      }
    },
    formatParentId(id, list, ids = []) {
      for (const item of list) {
        if (item.sysMusicScoreCategoriesList) {
          const cIds = this.formatParentId(
            id,
            item.sysMusicScoreCategoriesList,
            [...ids, item.id]
          );
          if (cIds.includes(id)) {
            return cIds;
          }
        }
        if (item.id === id) {
          return [...ids, id];
        }
      }
      return ids;
    },
    async FetchTree() {
      try {
        const res = await queryTree();
        this.tree = res.data;
        this.formatTree(this.tree)
      } catch (error) {}
    },
    formatTree(data){
      for(let i of data) {
        if(i.sysMusicScoreCategoriesList && i.sysMusicScoreCategoriesList.length > 0) {
          this.formatTree(i.sysMusicScoreCategoriesList, i)
        } else {
          i.sysMusicScoreCategoriesList = null
        }
      }
    },
    async FeatchDetailList() {
      try {
        const res = await queryPageSysExam({
          sysMusicScoreId: this.detail.id,
        });
        const result = res.data || [];
        result.forEach((item) => {
          if (!item.subjectId) {
            item.subjectId = null;
          }
        });
        this.$set(this.form, "sysMusicScoreAccompaniments", result);
      } catch (error) {}
    },
    createSys(initData) {
      this.form.sysMusicScoreAccompaniments.push(Object.assign({
        subjectId: "",
        speed: "",
        mp3Url: "",
        xmlUrl: "",
        track: "",
      }, (initData || {})));
    },
    async removeSys(index) {
      try {
        await this.$confirm("是否确认删除此原音?", "提示", {
          type: "warning",
        });
        if (this.form.sysMusicScoreAccompaniments[index]) {
          this.form.delExamSongAccompanimentIds.push(
            this.form.sysMusicScoreAccompaniments[index].id
          );
        }

        this.form.sysMusicScoreAccompaniments.splice(index, 1);
      } catch (error) {}
    },
    hasPartName(name) {
      const names = [];
      for (const item of this.form.sysMusicScoreAccompaniments) {
        names.push(item.track);
      }
      return names.includes(name);
    },
    hasSubjectId(id) {
      const ids = [];
      for (const item of this.form.sysMusicScoreAccompaniments) {
        ids.push(item.subjectId);
      }
      return ids.includes(id);
    },
    async submit() {
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          if (!this.detail) {
            await Add({
              ...this.form,
              sysMusicScore: {
                ...this.form.sysMusicScore,
                extConfigJson: JSON.stringify({
                  repeatedBeats: this.form.repeatedBeats,
                  gradualTimes: this.form.graduals,
                }),
                type: "COMMON",
                showFlag: 0,
                musicScoreCategoriesId: (
                  this.form.sysMusicScore.musicScoreCategoriesId || []
                ).pop(),
              },
            });
            this.$message.success("提交成功");
          } else {
            await Update({
              ...this.form,
              sysMusicScore: {
                ...this.form.sysMusicScore,
                extConfigJson: JSON.stringify({
                  repeatedBeats: this.form.repeatedBeats,
                  gradualTimes: this.form.graduals,
                }),
                type: "COMMON",
                id: this.detail.id,
                showFlag: this.detail.showFlag,
                musicScoreCategoriesId: (
                  this.form.sysMusicScore.musicScoreCategoriesId || []
                ).pop(),
              },
            });
            this.$message.success("修改成功");
          }
          this.$listeners.close();
          this.$listeners.submited();
        }
      });
    },
  },
};

/**
 * 获取指定元素下一个Note元素
 * @param ele 指定元素
 * @param selectors 选择器
 */
 const getNextNote = (ele, selectors) => {
  let index = 0
  const parentEle = ele.closest(selectors)
  let pointer = parentEle
  const measure = parentEle?.closest('measure')
  let siblingNote = null
  // 查找到相邻的第一个note元素
  while (!siblingNote && index < (measure?.childNodes.length || 50)) {
    index++
    if (pointer?.nextElementSibling?.tagName === 'note') {
      siblingNote = pointer?.nextElementSibling
    }
    pointer = pointer?.nextElementSibling
  }
  return siblingNote
}

export const onlyVisible = (xml, partIndex) => {
  if (!xml) return ''
  const xmlParse = new DOMParser().parseFromString(xml, 'text/xml')
  const partList = xmlParse.getElementsByTagName('part-list')?.[0]?.getElementsByTagName('score-part') || []
  // const partListNames = Array.from(partList).map(item => item.getElementsByTagName('part-name')?.[0].textContent || '')
  const parts = xmlParse.getElementsByTagName('part')
  // const firstTimeInfo = parts[0]?.getElementsByTagName('metronome')[0]?.parentElement?.parentElement?.cloneNode(true)
  // const firstMeasures = [...Array.from(parts[0]?.getElementsByTagName('measure') || [])]
  // const metronomes = [...Array.from(parts[0]?.getElementsByTagName('metronome') || [])]
  // const words = [...Array.from(parts[0]?.getElementsByTagName('words') || [])]
  // const codas = [...Array.from(parts[0]?.getElementsByTagName('coda') || [])]
  // const rehearsals = [...Array.from(parts[0]?.getElementsByTagName('rehearsal') || [])]
  const visiblePartInfo = partList[partIndex]
  // console.log(visiblePartInfo, partIndex)
  // state.partListNames = partListNames
  if (visiblePartInfo) {
    const id = visiblePartInfo.getAttribute('id')
    Array.from(parts).forEach(part => {
      if (part && part.getAttribute('id') !== id) {
        part.parentNode?.removeChild(part)
        // 不等于第一行才添加避免重复添加
      } else {
        // words.forEach(word => {
        //   const text = word.textContent || ''
        //   if(isSpeedKeyword(text) && text) {
        //     const wordContainer = word.parentElement?.parentElement?.parentElement
        //     if (wordContainer && wordContainer.firstElementChild && wordContainer.firstElementChild !== word) {
        //       const wordParent = word.parentElement?.parentElement
        //       const fisrt = wordContainer.firstElementChild
        //       wordContainer.insertBefore(wordParent, fisrt)
        //     }
        //   }
        // })
      }

      // 最后一个小节的结束线元素不在最后 调整
      if (part && part.getAttribute('id') === id) {
        const barlines = part.getElementsByTagName('barline')
        const lastParent = barlines[barlines.length - 1]?.parentElement
        if (lastParent?.lastElementChild?.tagName !== 'barline') {
          const children = lastParent?.children || []
          for (let el of children) {
            if (el.tagName === 'barline') {
              // 将结束线元素放到最后
              lastParent?.appendChild(el)
              break
            }
          }
        }
      }
    })
    Array.from(partList).forEach(part => {
      if (part && part.getAttribute('id') !== id) {
        part.parentNode?.removeChild(part)
      }
    })
    // 处理装饰音问题
    const notes = xmlParse.getElementsByTagName('note')
    const getNextvNoteDuration = (i) => {
      let nextNote = notes[i + 1]
      // 可能存在多个装饰音问题，取下一个非装饰音时值
      for (let index = i; index < notes.length; index++) {
        const note = notes[index];
        if (!note.getElementsByTagName('grace')?.length) {
          nextNote = note
          break
        }
      }
      const nextNoteDuration = nextNote?.getElementsByTagName('duration')[0]
      return nextNoteDuration
    }
    Array.from(notes).forEach((note, i) => {
      const graces = note.getElementsByTagName('grace')
      if (graces && graces.length) {
        // if (i !== 0) {
          note.appendChild(getNextvNoteDuration(i)?.cloneNode(true))
        // }
      }
    })
  }
  // console.log(new XMLSerializer().serializeToString(xmlParse))
  return new XMLSerializer().serializeToString(xmlParse)
}

const speedInfo = {
  'rall.': 1.333333333,
  'poco rit.': 1.333333333,
  'rit.': 1.333333333,
  'molto rit.': 1.333333333,
  'molto rall': 1.333333333,
  lentando: 1.333333333,
  allargando: 1.333333333,
  morendo: 1.333333333,
  'accel.': 0.8,
  calando: 2,
  'poco accel.': 0.8,
}

/**
 * 按照xml进行减慢速度的计算
 * @param xml 始终按照第一分谱进行减慢速度的计算
 */
 export function getGradualLengthByXml (xml) {
  const firstPartXml = onlyVisible(xml, 0)
  const xmlParse = new DOMParser().parseFromString(firstPartXml, 'text/xml')
  const measures = Array.from(xmlParse.querySelectorAll('measure'))
  const notes = Array.from(xmlParse.querySelectorAll('note'))
  const words = Array.from(xmlParse.querySelectorAll('words'))
  const metronomes = Array.from(xmlParse.querySelectorAll('metronome'))

  const eles = []

  for (const ele of [...words, ...metronomes]) {
    const note = getNextNote(ele, 'direction')
    // console.log(ele, note)
    if (note) {
      const measure = note?.closest('measure')
      const measureNotes = Array.from(measure.querySelectorAll('note'))

      const noteInMeasureIndex = Array.from(measure.childNodes)
        .filter((item) => item.nodeName === 'note')
        .findIndex((item) => item === note)

      let allDuration = 0
      let leftDuration = 0
      for (let i = 0; i < measureNotes.length; i++) {
        const n = measureNotes[i]
        const duration = +(n.querySelector('duration')?.textContent || '0')
        allDuration += duration
        if (i < noteInMeasureIndex) {
          leftDuration = allDuration
        }
      }
      eles.push({
        ele,
        index: notes.indexOf(note),
        noteInMeasureIndex,
        textContent: ele.textContent,
        measureIndex: measures.indexOf(measure),
        type: ele.tagName,
        allDuration,
        leftDuration,
      })
    }
  }

  const gradualNotes = []
  eles.sort((a, b) => a.index - b.index)
  const keys = Object.keys(speedInfo).map(w => w.toLocaleLowerCase())
  for (const ele of eles) {
    const textContent = ele.textContent?.toLocaleLowerCase().trim()
    if (ele.type === 'words' && keys.includes(textContent)) {
      gradualNotes.push([
        {
          start: ele.index,
          measureIndex: ele.measureIndex,
          noteInMeasureIndex: ele.noteInMeasureIndex,
          allDuration: ele.allDuration,
          leftDuration: ele.leftDuration,
          type: textContent,
        },
      ])
    }
    if (
      ele.type === 'metronome' ||
      (ele.type === 'words' && textContent === 'a tempo')
    ) {
      const indexOf = gradualNotes.findIndex((item) => item.length === 1)
      if (indexOf > -1 && ele.index > gradualNotes[indexOf]?.[0].start) {
        gradualNotes[indexOf][1] = {
          start: ele.index,
          measureIndex: ele.measureIndex,
          noteInMeasureIndex: ele.noteInMeasureIndex,
          allDuration: ele.allDuration,
          leftDuration: ele.leftDuration,
          type: textContent,
        }
      }
    }
  }
  return gradualNotes
}
</script>
<style lang="less" scoped>
.btns {
  text-align: right;
}
.files {
  background-color: #f8f8f8;
  padding: 20px 0;
  padding-right: 20px;
  margin-bottom: 20px;
  border-radius: 5px;
  position: relative;
  .file-remove {
    position: absolute;
    right: 20px;
    bottom: 10px;
  }
}
</style>
