import { Icon, Toast } from 'vant'
import { defineComponent, watchEffect, TransitionGroup, ref, Ref, reactive } from 'vue'
import event from '/src/components/music-score/event'
import SettingState from '/src/pages/detail/setting-state'
import state from '../state'
import runtime, { getFirsrNoteByMeasureListIndex, getBoundingBoxByNote, changeSpeed } from '../runtime'
import { getActtiveNoteByTimes, getBoundingBoxByverticalNote, getNoteBySlursStart, setSettionBackground } from '../helpers'
import { formatZoom } from '/src/helpers/utils'
import styles from './index.module.less'
import classNames from 'classnames'
import { modelType } from '/src/subpages/colexiu/buttons'
import { restPromptData } from '/src/helpers/restPrompt'
import { unitTestData } from '/src/subpages/colexiu/unitTest'
import { metronomeData } from "/src/helpers/metronome";

const sectionRef: Ref = ref(null)

const noteInfoItems = reactive({
  duration: false,
  numerator: false,
  denominator: false,
  i: false,
  time: false,
  speed: false,
})

;(window as unknown as Window & { setNoteInfoItems: (data: typeof noteInfoItems) => void }).setNoteInfoItems = (
  data
) => {
  for (const key in data) {
    if (Object.prototype.hasOwnProperty.call(data, key)) {
      noteInfoItems[key as keyof typeof noteInfoItems] = data[key as keyof typeof noteInfoItems]
    }
  }
}

/** 根据位置去重复 */
const uniqueByPosition = (list: any[]) => {
  const data: {
    [key in string]: any
  } = {}
  for (const item of list) {
    if (item && item.start_x) {
      data[`${item.x}-${item.y}`] = item
    }
  }
  return data
}

watchEffect(() => {
  // 监听状态节点选择状态并且开启提示
  if (state.sectionStatus) {
    if (!state.section.length) {
      state.befireSection = null
      Toast.clear()
      Toast({ duration: 0, message: '请选择开始节点', position: 'top' })
    } else if (state.section.length === 1) {
      Toast.clear()
      Toast({ duration: 0, message: '请选择结束节点', position: 'top' })
    }
  } else {
    state.section = []
    state.sectionBoundingBoxs = []
    Toast.clear()
  }
})

export default defineComponent({
  name: 'section-box',
  props: {
    type: {
      type: String,
      default: 'evaluating',
    },
    top: {
      type: Number,
      default: 0,
    },
    left: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      sectionTop: 0,
      sectionLeft: 0,
    }
  },
  methods: {
    setSection(evt: MouseEvent) {
      const activeNote = getActtiveNoteByTimes(evt)
      if (activeNote && state.section.length < 2) {
        const sectionLength = state.section.length
        if (sectionLength === 0) {
          const note = getNoteBySlursStart(activeNote, true)
          state.section.push(state.times[note.i - note.si])
        }
        if (sectionLength === 1) {
          const note = getNoteBySlursStart(activeNote, true, 'end')
          state.section.push(state.times[note.i - note.si + note.noteLength - 1])
          // 选段状态需要重置播放倍率为1
          runtime.basePlayRate = 1;
          const currentItem: any = state.section[0];
          const currentSpeed = currentItem?.measureSpeed ? currentItem.measureSpeed : state.activeSpeed;
          changeSpeed(currentSpeed)
        }
      }
      if (state.section.length === 2) {
        Toast.clear()
        setSettionBackground()
      }
    },
    sectionClick(evt: MouseEvent): void {
      metronomeData.isClick = true;
      if (!state.sectionStatus) {
        if (state.mode !== 'contact' || runtime.evaluatingStatus) {
          return
        }
        event.emit('section-click', evt)
      } else {
        // console.log(state.sectionStatus, evt)
        this.setSection(evt)
      }
    },
    /** 重复时仅处理一次 */
    filterTimes(times: any[]) {
      const ids: string[] = []
      return times.filter((item) => {
        const has = ids.includes(item.id)
        ids.push(item.id)
        return !has
      })
    },
  },
  mounted() {
    Toast.clear()
    state.section = []
    this.sectionTop = sectionRef.value?.getBoundingClientRect().top
    this.sectionLeft = sectionRef.value?.getBoundingClientRect().left
  },
  beforeUnmount() {
    Toast.clear()
    state.sectionStatus = false
    state.section = []
  },
  render() {
    const eyeBorderColor = SettingState.sett.eyeProtection
      ? 'var(--eye-section-border-color)'
      : 'var(--section-border-color)'
    const eyeBackground = (item: any) => {
      if (SettingState.sett.eyeProtection) {
        return item.before ? 'var(--section-background-color)' : 'var(--eye-section-background-color)'
      } else {
        return item.before ? 'var(--eye-section-background-color)' : 'var(--section-background-color)'
      }
    }
    // console.log(uniqueByPosition(Object.values(state.evaluatings)), 'state.evaluatings')
    // console.log('state.sectionFlash', state.sectionFlash)
    const activeNumberXml = state.times[runtime.activeIndex]?.noteElement?.sourceMeasure?.MeasureNumberXML || -2
    const restMeasure = restPromptData.list.find((n) => {
      const m = activeNumberXml - n.measureNumberXML
      return n.allRests && m >= 0 && m < n.multipleRestMeasures
    })
    const restNumber = restMeasure ? activeNumberXml - restMeasure.measureNumberXML + 1 : 0
    const img: HTMLElement = document.querySelector('#cursorImg-0')!
    if (restMeasure){
      img && metronomeData.cursorMode === 2 && img.classList.remove('lineHide')
    } else {
      img && metronomeData.cursorMode === 2 && img.classList.add('lineHide')
    }
    return (
      <div class={styles.section} ref={sectionRef}>
        {/* 为每个音符添加一个遮罩方便点击 */}
        {this.filterTimes(state.times).map((item) => {
          if (!item.svgElelent) {
            return null
          }
          let bbox: any
          try {
            bbox = item.svgElelent.bbox || item.svgElelent.getBoundingBox?.()
            if (!bbox && item.svgElelent?.attrs?.el) {
              bbox = item.svgElelent.attrs.el.getBBox()
              bbox.w = bbox.width < 15 ? 15 : bbox.width
              bbox.h = bbox.height < 11 ? 11 : bbox.height
            }
          } catch (error) {
            console.log(error)
          }
          if (!bbox) {
            return null
          }
          if (SettingState.sett.type === 'jianpu' && item.svgElelent) {
            if (item.svgElelent.top_y && item.svgElelent.note_height) {
              bbox.y = item.svgElelent.top_y - item.svgElelent.note_height
            }
          }
          let { x, y, h, w } = bbox

          let boundingBox = null
          // let measureBg = false
          const activeNumberIndex = (item?.noteElement?.sourceMeasure?.measureNumber + 1) || -2;
          // console.log(activeNumberIndex,'👀👀',metronomeData.activeMetro?.measureNumberXML)
          if (item.si === 0) {
            boundingBox = getBoundingBoxByNote(item.noteElement)
          }
          return (
            <>
              {item.si === 0 && boundingBox && (
                <div
                  data-id={item.id}
                  data-num={item.noteElement.sourceMeasure.MeasureNumberXML}
                  style={{
                    position: 'absolute',
                    top: formatZoom(boundingBox.y) + 'px',
                    left: formatZoom(boundingBox.x) + 'px',
                    height: formatZoom(boundingBox.height) + 'px',
                    width: formatZoom(boundingBox.width) + 'px',
                    background: unitTestData.isSelectMeasureMode && state.sectionStatus
                      ? `${
                          item?.noteElement?.sourceMeasure?.MeasureNumberXML <
                            state.section[0]?.noteElement?.sourceMeasure?.MeasureNumberXML ||
                          item?.noteElement?.sourceMeasure?.MeasureNumberXML >
                            state.section[1]?.noteElement?.sourceMeasure.MeasureNumberXML
                            ? 'rgba(0, 0, 0,.28)'
                            : 'var(--section-background-color)'
                        }`
                      : '',
                  }}
                  onClick={state.sectionStatus ? this.sectionClick : undefined}
                >
                  {metronomeData.cursorMode === 2 && activeNumberIndex === metronomeData.activeMetro?.measureNumberXML && <div class={styles.lineTEST} style={{ left: metronomeData.activeMetro.left }}></div>}
                </div>
              )}
              <div
                data-id={item.id}
                data-vf={'vf' + item.id}
                class={styles.noteWrap}
                style={{
                  position: 'absolute',
                  top: formatZoom(y) + 'px',
                  left: formatZoom(x) + 'px',
                  height: formatZoom(h) + 'px',
                  width: formatZoom(w) + 'px',
                  // background: 'rgba(0, 0, 0, 0.5)',
                  background: Object.values(noteInfoItems).find((v) => v === true) ? 'rgba(255, 255, 255, 0.8)' : '',
                }}
                onClick={this.sectionClick}
              >
                {noteInfoItems.duration && (
                  <>
                    {parseInt(item.duration * 100 + '') / 100}
                    <br />
                  </>
                )}
                {noteInfoItems.time && (
                  <>
                    {item.time.toFixed(2)}
                    <br />
                  </>
                )}
                {noteInfoItems.numerator && (
                  <>
                    {item.noteElement.sourceMeasure.activeTimeSignature.numerator}
                    <br />
                    <br />
                  </>
                )}
                {noteInfoItems.denominator && (
                  <>
                    {item.noteElement.sourceMeasure.activeTimeSignature.denominator}
                    <br />
                    <br />
                  </>
                )}
                {noteInfoItems.i && (
                  <>
                    {item.i}
                    <br />
                    <br />
                  </>
                )}
                {noteInfoItems.speed && (
                  <>
                    {item.speed.toFixed(0)}
                    <br />
                    <br />
                  </>
                )}
                <div class={[styles.noteBase, styles.noteRight]}>
                  <Icon name="success" size="16" color="#2DC7AA" />
                </div>
                <div class={[styles.noteBase, styles.noteError]}>
                  <Icon name="cross" size="16" color="red" />
                </div>
              </div>
            </>
          )
        })}
        {/* 范围的两个括号 */}
        {state.section.map((item, index) => {
          const boundingBox = getBoundingBoxByverticalNote(item)
          let X: number | undefined = undefined
          try {
            const bbox = item.svgElelent?.bbox || item.svgElelent?.getBoundingBox && item.svgElelent?.getBoundingBox()
            X = formatZoom(bbox?.x || (index === 0 ? boundingBox.start_x : boundingBox.end_x))
          } catch (error) {
            console.log(error)
          }
          if (!X) {
            return null
          }
          if (index === 0 && boundingBox) {
            // console.log('左',formatZoom(boundingBox.y) - 5, formatZoom(boundingBox.x),X,SettingState.sett.scoreSize)
            return (
              <div
                style={{
                  position: 'absolute',
                  top: formatZoom(boundingBox.y) + 'px',
                  left: formatZoom(boundingBox.x) + 'px',
                  height: formatZoom(boundingBox.height) + 'px',
                  border: `5px solid ${eyeBorderColor}`,
                  borderColor: `${eyeBorderColor} transparent ${eyeBorderColor} ${eyeBorderColor}`,
                  borderRight: 'none',
                  width: '5px',
                }}
              ></div>
            )
          }
          if (index === 1 && boundingBox) {
            // console.log('右',formatZoom(boundingBox.y - 5), formatZoom(boundingBox.end_x),X)
            return (
              <div
                style={{
                  position: 'absolute',
                  top: formatZoom(boundingBox.y) + 'px',
                  left: formatZoom(boundingBox.end_x) + 'px',
                  height: formatZoom(boundingBox.height) + 'px',
                  border: `5px solid ${eyeBorderColor}`,
                  borderColor: `${eyeBorderColor} ${eyeBorderColor} ${eyeBorderColor} transparent`,
                  borderLeft: 'none',
                  width: '5px',
                }}
              ></div>
            )
          }
          return null
        })}
        {/* 添加选择背景 */}
        {state.sectionBoundingBoxs.map((item) => {
          return (
            <div
              class={{
                [styles.flash]: item.before && state.sectionFlash && runtime.playState === 'play',
              }}
              style={{
                position: 'absolute',
                top: formatZoom(item.y) + 'px',
                left: formatZoom(item.x) + 'px',
                height: formatZoom(getBoundingBoxByverticalNote(state.section[0])?.height) + 'px',
                width: formatZoom(item.width) + 'px',
                backgroundColor: eyeBackground(item),
              }}
            ></div>
          )
        })}
        {/* 分数信息 */}
        <TransitionGroup name="list" duration={800}>
          {Object.values(uniqueByPosition(Object.values(state.evaluatings))).map((item: any) => {
            if (!item) return <span />
            return (
              <div
                key={item.y + item.x + item.text}
                class={classNames(styles[item.text], styles.measure, { [styles.dontTransition]: item.dontTransition })}
                style={{
                  position: 'absolute',
                  top: formatZoom(item.y) + this.top + 'px',
                  left: formatZoom(item.x) + this.left + 'px',
                  height: formatZoom(item.height) + 'px',
                  width: formatZoom(item.width) + 'px',
                }}
              >
                {this.type === 'evaluating' ? (
                  <span class={styles.after}>
                    <span class={styles.img}></span>
                    <span class={styles.font}>{item.score}</span>
                  </span>
                ) : null}
              </div>
            )
          })}
        </TransitionGroup>

        {/* 休止符等待 */}
        {restMeasure && (
          <div class={['dotWrap', styles.restMeasure]} style={restMeasure.staveBox}>
            <div class="dot">{restNumber}</div>
          </div>
        )}
      </div>
    )
  },
})
