import { defineComponent } from 'vue'
import requestOrigin from 'umi-request'
import { Skeleton, Empty, Button } from 'vant'
import Note from './note'
import Header from './header'
import state from '/src/pages/detail/state'
import SectionBox from '../detail/section-box'
import MusicScore from '/src/components/music-score'
import request from '/src/helpers/request'
import {
  getAllNodes,
  getBoundingBoxByverticalNote,
  getNoteBySlursStart,
  getParentNote,
} from '/src/pages/detail/helpers'
import { postMessage } from '/src/helpers/native-message'
import styles from './index.module.less'
import { browser, getVoiceChinesName } from '/src/helpers/utils'
import PlayerPopup from './player'
import { getLeveByScoreMeasure } from '../detail/evaluating/helper'
import { formatXML, onlyVisible } from '/src/pages/detail/helpers'

const browserInfo = browser()

export const colors = {
  RIGHT: '#01C1B5',
  WRONG: '#FF4444',
  NOT_PLAY: '#AEAEAE',
}

export const colorsClass = {
  RIGHT: styles.right,
  WRONG: styles.wrong,
  NOT_PLAY: styles.notPlay,
  CADENCE_WRONG: styles.cadence_wrong,
  INTONATION_WRONG: styles.intonation_wrong,
  INTEGRITY_WRONG: styles.integrity_wrong,
  CADENCE_FAST: styles.cadence_fast,
  CADENCE_SLOW: styles.cadence_slow,
  INTONATION_HIGH: styles.intonation_high,
  INTONATION_LOW: styles.intonation_low,
}

export type IResNote = {
  musicalErrorType: 'RIGHT' | 'WRONG' | 'NOT_PLAY' | 'CADENCE_WRONG' | 'INTONATION_WRONG' | 'CADENCE_FAST' | 'CADENCE_SLOW' | 'INTONATION_HIGH' | 'INTONATION_LOW'
  musicalNotesIndex: number
}

export default defineComponent({
  name: 'report',
  data() {
    return {
      data: null as any,
      score: null as any,
      allNote: [] as any[],
      allResNote: [] as IResNote[],
      loading: false,
      hasError: false,
      empty: false,
      paddingLeft: 20,
      svgHeight: 0,
      userMeasureScore: null as any,
      paddingTop: 0,
    }
  },
  created() {
    if (browserInfo.android) {
      postMessage({ api: 'setBarStatus', content: { status: 0 } })
    }
  },
  async mounted() {
    console.log(state)
    this.FetchList()
    if (browserInfo.android) {
      postMessage({ api: 'getNavHeight' }, (res) => {
        const { content }: any = res
        const dpi = content.dpi || 2
        if (content.navHeight) {
          this.paddingTop = content.navHeight / dpi
          this.paddingLeft = content.navHeight / dpi
        }
      })
    } else if (browserInfo.ios) {
      postMessage(
        {
          api: 'isSpecialShapedScreen',
        },
        (evt) => {
          const height = evt?.content.notchHeight
          this.paddingLeft = height || (evt?.content.isSpecialShapedScreen && browserInfo.ios ? 50 : 0)
          // state.isSpecialShapedScreen = evt?.content.isSpecialShapedScreen
        }
      )
    }
  },
  methods: {
    async FetchList() {
      this.loading = true
      this.hasError = false
      this.empty = false
      try {
        const res = await request.get('/sysMusicRecord/getLastEvaluationMusicalNotesPlayStats', {
          params: {
            recordId: this.$route.params.id,
          },
        })
        if (!res.data) {
          this.empty = true
          this.loading = false
          return
        }
        const detailRes = await request.get('/sysMusicScoreAccompaniment/queryPage', {
          params: {
            clientType: 'SMART_PRACTICE',
            sysMusicScoreId: res.data.musicalNotesPlayStats.examSongId,
          },
        })
        const worksid = detailRes.data[0]?.parentCategoriesId
        state.subjectId = detailRes.data[0]?.subjectId
        const { musicalNotesPlayStats, userMeasureScore, partIndex, ...rest } = res.data
        state.partIndex = partIndex || 0
        this.data = rest
        this.userMeasureScore = userMeasureScore
        this.allResNote = musicalNotesPlayStats.notesData
        const resXml = await requestOrigin.get(musicalNotesPlayStats.xmlUrl, {
          mode: 'cors',
        })
        this.score = onlyVisible(formatXML(resXml), state.partIndex)

        const isWorks = worksid == 26 || worksid == 43
        const partName = state.partListNames[state.partIndex]
        const partInfo = isWorks && partName ? ' - ' + getVoiceChinesName(partName) : ''
        this.data.sysMusicScoreName = this.data.sysMusicScoreName + partInfo
      } catch (error) {
        this.hasError = true
      }
      this.loading = false
    },
    onRerender(osmd: any) {
      this.svgHeight = (osmd?.container as HTMLDivElement)?.querySelector('svg')?.getBoundingClientRect().height || 0
      this.allNote = getAllNodes(osmd)
      state.times = this.allNote
      for (const note of this.allResNote) {
        const active = this.allNote[note.musicalNotesIndex]
        setTimeout(() => {
          const svgEl = document.getElementById('vf-' + active.id)
          svgEl?.classList.add(colorsClass[note.musicalErrorType])
        }, 300)
      }
      const setEvaluatings = (note: any, data: any, dontTransition = false) => {
        const startNote = getBoundingBoxByverticalNote(note)
        state.evaluatings = {
          ...state.evaluatings,
          [startNote.measureIndex]: {
            ...startNote,
            ...getLeveByScoreMeasure(data.score),
            score: data.score,
            dontTransition,
          },
        }
      }
      if (this.userMeasureScore) {
        for (const key in this.userMeasureScore) {
          if (Object.prototype.hasOwnProperty.call(this.userMeasureScore, key)) {
            const data = this.userMeasureScore[key]
            for (const time of this.allNote) {
              if (data.measureRenderIndex == time.noteElement.sourceMeasure.MeasureNumberXML - 1) {
                // if (state.evaluatings[data.measureRenderIndex]) {
                //   continue
                // }

                if (!time.noteElement.tie) {
                  setEvaluatings(time, data)
                } else {
                  for (const item of time.noteElement.tie.notes) {
                    const note = getParentNote(item)
                    if (!note) continue
                    setEvaluatings(note, data, item !== time.noteElement.tie.StartNote)
                    // const startNote = getBoundingBoxByverticalNote(note)
                    // state.evaluatings = {
                    //   ...state.evaluatings,
                    //   [startNote.measureIndex]: {
                    //     ...startNote,
                    //     ...getLeveByScoreMeasure(data.score),
                    //     score: data.score,
                    //     dontTransition: item !== time.noteElement.tie.StartNote,
                    //   },
                    // }
                  }
                }

                // const startNote = getBoundingBoxByverticalNote(time)
                // const endNote = getBoundingBoxByverticalNote(getNoteBySlursStart(time, true, 'end'))
                // state.evaluatings = {
                //   ...state.evaluatings,
                //   [data.measureRenderIndex]: {
                //     ...startNote,
                //     ...getLeveByScoreMeasure(data.score),
                //     score: data.score,
                //     measureRenderIndex: data.measureRenderIndex
                //   },
                // }
                // if (startNote.MeasureNumberXML !== endNote.MeasureNumberXML) {
                //   state.evaluatings = {
                //     ...state.evaluatings,
                //     [endNote.MeasureNumberXML - 1]: {
                //       ...endNote,
                //       ...getLeveByScoreMeasure(data.score),
                //       score: data.score,
                //       dontTransition: true
                //     },
                //   }
                // }

                // break
              }
            }
          }
        }
      }
    },
  },
  render() {
    return (
      <div class={styles.report} style={{ paddingTop: this.paddingTop / 2 + 'px' }}>
        <Header data={this.data} />
        <div class={styles.content} style={{ marginLeft: this.paddingLeft + 'px' }}>
          {this.hasError ? (
            <Empty
              image="error"
              description="请求错误"
              vSlots={{
                description: () => (
                  <span>
                    请求错误{' '}
                    <a style="color: #01C1B5;" href="javascript:;" onClick={this.FetchList}>
                      重新加载
                    </a>
                  </span>
                ),
              }}
            />
          ) : null}
          {this.empty ? <Empty description="暂无评测数据" /> : null}
          {!this.hasError && this.data ? (
            <div class={styles.demos}>
              <div>
                <Note fill="#01C1B5" />
                <span>演奏正确</span>
              </div>
              <div>
                <Note fill="#067DD7" />
                <span>节奏错误</span>
              </div>
              {!state.isPercussion ? (
                <>
                  <div>
                    <Note fill="#FFAB25" />
                    <span>音准错误</span>
                  </div>
                  <div>
                    <Note fill="#CC75FF" />
                    <span>完成度不足</span>
                  </div>
                </>
              ) : null}
              <div>
                <Note fill="#000" />
                <span>未演奏</span>
              </div>
            </div>
          ) : null}
          {/* 小节覆盖层 */}
          <SectionBox
            type="report"
            top={40}
            left={0}
            style={{
              position: 'absolute',
              width: '100%',
              height: this.svgHeight + 'px',
            }}
          />
          {this.score ? (
            <MusicScore class={styles.score} score={this.score} onRerender={this.onRerender} />
          ) : this.loading ? (
            <Skeleton row={6} />
          ) : null}
          {this.data?.videoFilePath ? (
            <PlayerPopup {...this.data}>
              <Button color="#01c1b5" round size="mini" icon="replay" class={styles.btn}>
                查看回放
              </Button>
            </PlayerPopup>
          ) : null}
        </div>
      </div>
    )
  },
})
