import {
  defineComponent,
  onMounted,
  onUnmounted,
  reactive,
  ref,
  watch,
  toRef
} from 'vue';
import styles from './index.module.less';
import { postMessage } from '@/helpers/native-message';
import icon_title from './images/icon-title.png';
import icon_back from './images/icon-back.png';
import icon_back1 from './images/icon-back1.png';
import icon_setting from './images/icon-setting.png';
import iconPlay from './images/icon-play.png';
import iconPause from './images/icon-pause.png';
import beat from './images/btn-2.png';
import tempo from './images/btn-3.png';
import randDom from './images/btn-1.png';
import setImg from './images/setting.png';
import iconPlus from './images/icon-plus.png';
import iconAdd from './images/icon-add.png';
import { getImage } from './images/music';
import '@vant/touch-emulator';
// import j2 from './images/music/j-2.png';
import { Popover, Popup, showToast } from 'vant';
import SettingModal from './setting-modal';
import {
  randomScoreElement,
  renderScore,
  setting,
  elementDirection,
  setting_modal,
  initSelectScorePartModal,
  renderScoreModal
} from './setting';
import { handleStartTick, hendleEndTick } from './tick';
import { handleStartBeat, hendleEndBeat } from './beat-tick';
import { browser } from '@/helpers/utils';
import { useRoute } from 'vue-router';
import useDrag from '@/hooks/useDrag';
import useDragGuidance from '@/hooks/useDrag/useDragGuidance';
import { state as stateData } from '@/state';
import SettingPcModal from './setting-pc-modal';
import Draggable from 'vuedraggable';

export default defineComponent({
  name: 'tempo-practice',
  props: {
    dataJson: {
      type: Object,
      default: () => {}
    },
    modeType: {
      type: String,
      default: ''
    },
    show: {
      type: Boolean,
      default: false
    }
  },
  setup(props, { expose }) {
    const route = useRoute();
    const state = reactive({
      modeType: '' as any,
      platform: route.query.platform,
      win: route.query.win,
      settingStatus: false,
      settingPcStatus: false,
      speedList: [
        { text: '40', value: 40, color: '#060606' },
        { text: '50', value: 50, color: '#060606' },
        { text: '60', value: 60, color: '#060606' },
        { text: '70', value: 70, color: '#060606' },
        { text: '80', value: 80, color: '#060606' },
        { text: '90', value: 90, color: '#060606' },
        { text: '100', value: 100, color: '#060606' },
        { text: '110', value: 110, color: '#060606' },
        { text: '120', value: 120, color: '#060606' },
        { text: '130', value: 130, color: '#060606' },
        { text: '140', value: 140, color: '#060606' },
        { text: '150', value: 150, color: '#060606' },
        { text: '160', value: 160, color: '#060606' },
        { text: '170', value: 170, color: '#060606' },
        { text: '180', value: 180, color: '#060606' },
        { text: '190', value: 190, color: '#060606' },
        { text: '200', value: 200, color: '#060606' }
      ],
      dataJson: {} as any,
      playPos: (route.query.imagePos || 'left') as 'left' | 'right' // 数字课堂老师端上课 镜像字段
    });
    // 拖拽临时数据
    const tempDragData = ref<any>({});
    // 返回
    const goback = (e: any) => {
      e.stopPropagation();
      if (route.query.backBtnType === 'microapp') {
        // microapp 老师端应用里面打开单独处理返回逻辑
        window.parent.postMessage(
          {
            api: 'iframe_exit'
          },
          '*'
        );

        return;
      }
      if (!browser().isApp) {
        window.close();
        return;
      }
      postMessage({ api: 'goBack' });
    };

    /* 修改设置的某个值 */
    const updateSettingValue = (key: string, value: any) => {
      if (state.settingStatus) {
        setting_modal[key] = value;
      } else {
        setting[key] = value;
      }
    };
    /* 获取设置的某一个值 */
    const getSettingValue = (key: string) => {
      let value: any = null;
      if (state.settingStatus) {
        value = setting_modal[key];
      } else {
        value = setting[key];
      }
      return value;
    };

    /** 播放切换 */
    const handlePlay = async () => {
      const playState = getSettingValue('playState');
      const playType = getSettingValue('playType');

      if (playState === 'pause') {
        updateSettingValue('playState', 'play');
        if (playType === 'beat') {
          await handleStartTick(state.settingStatus);
        } else {
          await handleStartBeat(state.settingStatus);
        }
      } else {
        handleStop();
      }
    };

    /** 播放切换 */
    const handlePlay2 = async () => {
      const playState = getSettingValue('playState');
      const playType = getSettingValue('playType');

      if (playState === 'pause') {
        updateSettingValue('playState', 'play');
        if (playType === 'beat') {
          await handleStartTick(state.settingStatus);
        } else {
          await handleStartBeat(state.settingStatus);
        }
      }
    };
    /** 播放类型 */
    const handlePlayType = () => {
      handleStop();
      // 判断是否有设置
      const playType = getSettingValue('playType');
      if (playType === 'beat') {
        updateSettingValue('playType', 'tempo');
      } else {
        updateSettingValue('playType', 'beat');
      }
    };

    const handleStop = () => {
      const playType = getSettingValue('playType');
      updateSettingValue('playState', 'pause');

      if (playType === 'beat') {
        hendleEndTick(state.settingStatus);
      } else {
        hendleEndBeat(state.settingStatus);
      }
    };

    // {"element":"jianpu","beat":"4-4","barLine":"1","tempo":["1","2","3"]}'
    const onIframeHandle = (ev: MessageEvent) => {
      // 获取配置
      if (ev.data.api === 'getTempoSetting') {
        window.parent.postMessage(
          {
            api: 'getTempoSetting',
            data: JSON.stringify({
              setting: {
                element: setting.element,
                beat: setting.beat,
                barLine: setting.barLine,
                tempo: setting.tempo,
                scorePart: setting.scorePart,
                playType: setting.playType,
                speed: setting.speed
              },
              coverImg: ''
            })
          },
          '*'
        );
      }

      if (ev.data.api === 'setPlayState') {
        if (ev.data.data) {
          handlePlay();
        } else {
          handleStop();
        }
      }

      if (ev.data.api === 'resetPlay') {
        resetSetting();
      }
      if (ev.data.api === 'imagePos') {
        if (ev.data.data === 'right') {
          state.playPos = 'right';
        } else {
          state.playPos = 'left';
        }
      }
    };

    const resetSetting = () => {
      try {
        let dataJson = props.dataJson;
        if (route.query.dataJson) {
          dataJson = JSON.parse(route.query.dataJson as any);
        }

        if (dataJson) {
          setting.element = dataJson.element;
          setting.beat = dataJson.beat;
          setting.barLine = dataJson.barLine;
          setting.tempo = dataJson.tempo;
          setting.scorePart = dataJson.scorePart;
          setting.playType = dataJson.playType;
          setting.speed = dataJson.speed;

          setting_modal.element = dataJson.element;
          setting_modal.beat = dataJson.beat;
          setting_modal.barLine = dataJson.barLine;
          setting_modal.tempo = dataJson.tempo;
          setting_modal.scorePart = dataJson.scorePart;
          setting_modal.playType = dataJson.playType;
          setting_modal.speed = dataJson.speed;

          state.dataJson = dataJson;
        }
      } catch (e) {
        //
        console.log(e, '1');
      }
    };
    // watch(
    //   () => props.show,
    //   val => {
    //     console.log(val, props.show);
    //     if (!val) {
    //       // resetSetting();
    //       handleStop();
    //     } else {
    //       resetSetting();
    //     }
    //   }
    // );

    /** 打开设置 */
    const onOpenSetting = () => {
      handleStop();
      // 初始化设置的数据
      for (let i in setting) {
        setting_modal[i] = JSON.parse(JSON.stringify(setting[i]));
      }

      if (state.win === 'pc' || state.platform === 'modal') {
        state.settingPcStatus = true;
      } else {
        state.settingStatus = true;
      }
    };

    onMounted(() => {
      // 安卓的状态栏
      postMessage({
        api: 'setStatusBarVisibility',
        content: {
          isVisibility: 0
        }
      });
      if (route.query.modeType) {
        state.modeType = route.query.modeType;
      }
      resetSetting();
      state.speedList.forEach((item: any) => {
        if (item.value === setting.speed) item.color = '#1CACF1';
      });
      if (setting?.scorePart?.length <= 0) {
        renderScore();
      }

      window.addEventListener('message', onIframeHandle);
    });

    onUnmounted(() => {
      window.removeEventListener('message', onIframeHandle);
    });

    watch(
      () => state.settingStatus,
      () => {
        if (!state.settingStatus) {
          state.speedList.forEach((item: any) => {
            if (item.value === getSettingValue('speed')) {
              item.color = '#1CACF1';
            } else {
              item.color = '#060606';
            }
          });
          handleStop();
        }
      }
    );

    expose({
      resetSetting
    });
    let settingBoxDragData: any;
    let settingBoxClass: string;
    if (state.platform === 'modal') {
      settingBoxClass = 'settingBoxClass_drag';
      settingBoxDragData = useDrag(
        [
          `${settingBoxClass} .iconTitBoxMove`,
          `${settingBoxClass} .bom_drag_point`,
          `${settingBoxClass} .bom_drag_point_right`
        ],
        settingBoxClass,
        toRef(state, 'settingPcStatus'),
        stateData.user.data.id
      );
    }
    // 引导页
    const { guidanceShow, setGuidanceShow } = useDragGuidance();
    return () => (
      <div
        onClick={() => {
          state.settingStatus = false;
          window.parent.postMessage(
            {
              api: 'clickTempo'
            },
            '*'
          );
        }}
        class={[
          styles.tempoPractice,
          state.win === 'pc' ? styles.pc : '',
          state.platform === 'modal' ? styles.modal : '',
          state.modeType === 'courseware' ? styles.courseware : ''
        ]}>
        <div
          class={[
            styles.containerLeft,
            state.settingStatus ? styles.leftShow : ''
          ]}>
          <div class={styles.head}>
            {state.modeType !== 'courseware' && (
              <div
                class={[styles.back, styles.iconBack]}
                onClick={goback}
                style={{ cursor: 'pointer' }}>
                <img src={icon_back} />
              </div>
            )}
            <div class={styles.title}>
              <img src={icon_title} />
            </div>
            {state.modeType !== 'courseware' &&
            state.platform !== 'modal' &&
            !state.settingStatus ? (
              <div
                class={styles.back}
                style={{ cursor: 'pointer' }}
                onClick={(e: any) => {
                  e.stopPropagation();
                  onOpenSetting();
                }}>
                <img src={icon_setting} />
              </div>
            ) : (
              <div class={styles.back}></div>
            )}
          </div>

          <div class={styles.conCon}>
            <div class={styles.container}>
              {getSettingValue('scorePart')?.map((item: any, i: number) => (
                <div
                  class={[
                    styles.beatSection,
                    getSettingValue('scorePart').length >= 2 &&
                      item.length !== 1 &&
                      styles.small
                  ]}>
                  {item.map((child: any, jIndex: number) => (
                    <Draggable
                      modelValue={[child]}
                      itemKey="index"
                      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                      // @ts-ignore
                      group={{
                        name: 'description',
                        pull: 'clone',
                        put: true
                      }}
                      animation={200}
                      sort={false}
                      componentData={{
                        draggable: 'row-nav',
                        itemKey: 'index',
                        tag: 'div',
                        pull: 'clone',
                        put: true,
                        animation: 200,
                        group: 'description'
                      }}
                      onChange={(evt: any) => {
                        tempDragData.value = evt.added || '';
                      }}
                      onAdd={() => {
                        const added = tempDragData.value?.element || {};
                        // 判断是否有数据
                        if (added.url && added.sourceFrom === 'setting-modal') {
                          handleStop();
                          setting_modal.scorePart.forEach(
                            (part: Array<any>, ci: number) => {
                              part.forEach((child: any, cj: number) => {
                                if (i === ci && jIndex === cj) {
                                  child.url = added.url;
                                  child.index = added.index;
                                }
                              });
                            }
                          );
                        }
                      }}
                      onStart={(evt: any) => {
                        evt.from.classList.add('onstart');
                        tempDragData.value = {};
                      }}
                      onEnd={(evt: any) => {
                        evt.from.classList.remove('onstart');
                        tempDragData.value = {};
                      }}
                      onClick={(e: any) => {
                        e.stopPropagation();
                        // 编辑时可以操作
                        if (state.settingStatus) {
                          handleStop();
                          if (setting_modal.scorePart[i][jIndex].selected) {
                            initSelectScorePartModal();
                          } else {
                            initSelectScorePartModal(i, jIndex);
                          }
                        }
                      }}
                      class={[
                        styles.beat,
                        child.selected ? styles.active : '',
                        state.settingStatus && styles.disabledChange
                      ]}>
                      {{
                        item: (element: any) => {
                          const child = element.element;
                          const jIndex = element.index;
                          return (
                            <div>
                              {/* 编辑时不可上下切换 */}
                              {!state.settingStatus && (
                                <div class={styles.direction}>
                                  <div
                                    class={styles.up}
                                    style={{ cursor: 'pointer' }}
                                    onClick={() => {
                                      if (setting.playState === 'play') return;
                                      if (setting.tempo.length <= 1) {
                                        showToast(
                                          '无法切换，请选择至少2种节奏型'
                                        );
                                        return;
                                      }
                                      // const obj = randomScoreElement(child.index);
                                      const obj = elementDirection(
                                        'up',
                                        child.index
                                      );
                                      child.index = obj.index;
                                      child.url = obj.url;
                                    }}></div>
                                  <div
                                    class={styles.down}
                                    style={{ cursor: 'pointer' }}
                                    onClick={() => {
                                      if (setting.playState === 'play') return;
                                      if (setting.tempo.length <= 1) {
                                        showToast(
                                          '无法切换，请选择至少2种节奏型'
                                        );
                                        return;
                                      }
                                      // const obj = randomScoreElement(child.index);
                                      const obj = elementDirection(
                                        'down',
                                        child.index
                                      );
                                      child.index = obj.index;
                                      child.url = obj.url;
                                    }}></div>
                                </div>
                              )}
                              <div class={styles.imgSection}>
                                <img src={getImage(child.url)} />
                              </div>
                            </div>
                          );
                        }
                      }}
                    </Draggable>
                  ))}
                </div>
              ))}
            </div>
          </div>

          <div
            class={styles.footer}
            onClick={(e: any) => {
              e.stopPropagation();
            }}>
            {/* 播放 */}
            {state.playPos === 'left' && (
              <>
                {route.query.back === 'show' && (
                  <div
                    class={[styles.play]}
                    onClick={goback}
                    style={{ cursor: 'pointer' }}>
                    <img src={icon_back1} />
                  </div>
                )}
                <div class={styles.play} onClick={handlePlay}>
                  {getSettingValue('playState') === 'pause' ? (
                    <img src={iconPause} />
                  ) : (
                    <img src={iconPlay} />
                  )}
                </div>
              </>
            )}
            {/* 老师端来的时候的设置按钮 */}
            {state.platform === 'modal' && state.playPos === 'right' && (
              <div
                class={styles.setting}
                onClick={() => {
                  onOpenSetting();
                }}>
                <img src={setImg} />
              </div>
            )}
            {/* 播放类型 */}
            <div class={styles.playType} onClick={handlePlayType}>
              {getSettingValue('playType') === 'beat' ? (
                <img src={beat} />
              ) : (
                <img src={tempo} />
              )}
            </div>
            {/* 随机生成 */}
            <div
              class={styles.randomTempo}
              onClick={() => {
                if (state.settingStatus) {
                  renderScoreModal();
                } else {
                  renderScore();
                }
                handleStop();
              }}>
              <img src={randDom} />
            </div>
            {/* 速度 */}
            <div class={styles.speedChange}>
              <img
                src={iconPlus}
                class={styles.speedPlus}
                onClick={() => {
                  const speed = getSettingValue('speed');
                  if (speed <= 40) return;
                  updateSettingValue('speed', speed - 1);
                  handleStop();

                  state.speedList.forEach((item: any) => {
                    if (item.value === getSettingValue('speed')) {
                      item.color = '#1CACF1';
                      updateSettingValue('speed', getSettingValue('speed'));
                    } else {
                      item.color = '#060606';
                    }
                  });
                }}
              />
              <Popover
                placement="top"
                class={styles.popupContainer}
                actions={state.speedList}
                onSelect={(val: any) => {
                  const speed = getSettingValue('speed');
                  if (val.value === speed) return;
                  state.speedList.forEach((item: any) => {
                    if (item.value === val.value) {
                      item.color = '#1CACF1';
                      updateSettingValue('speed', val.value);
                    } else {
                      item.color = '#060606';
                    }
                  });
                  handleStop();
                }}>
                {{
                  reference: () => (
                    <div class={styles.speedNum}>
                      {getSettingValue('speed')}
                    </div>
                  )
                }}
              </Popover>

              <img
                src={iconAdd}
                class={styles.speedAdd}
                onClick={() => {
                  const speed = getSettingValue('speed');

                  if (speed >= 200) return;
                  updateSettingValue('speed', speed + 1);
                  handleStop();

                  state.speedList.forEach((item: any) => {
                    if (item.value === getSettingValue('speed')) {
                      item.color = '#1CACF1';
                      updateSettingValue('speed', getSettingValue('speed'));
                    } else {
                      item.color = '#060606';
                    }
                  });
                }}
              />
            </div>
            {/* 播放 */}
            {state.playPos === 'right' && (
              <div class={styles.play} onClick={handlePlay}>
                {getSettingValue('playState') === 'pause' ? (
                  <img src={iconPause} />
                ) : (
                  <img src={iconPlay} />
                )}
              </div>
            )}
            {/* 老师端来的时候的设置按钮 */}
            {state.platform === 'modal' && state.playPos === 'left' && (
              <div
                class={styles.setting}
                onClick={() => {
                  onOpenSetting();
                }}>
                <img src={setImg} />
              </div>
            )}
          </div>
        </div>
        <div
          class={[
            styles.containerRight,
            state.settingStatus ? '' : styles.rightHide
          ]}
          onClick={(e: any) => {
            e.stopPropagation();
          }}>
          <SettingModal
            class={styles.settingModalShow}
            onClose={() => (state.settingStatus = false)}
          />
        </div>

        <Popup
          style={
            state.platform === 'modal' ? settingBoxDragData.styleDrag.value : {}
          }
          closeOnClickOverlay={false}
          v-model:show={state.settingPcStatus}
          class={[styles.settingPopup, settingBoxClass]}>
          <SettingPcModal
            onGuideDone={setGuidanceShow}
            showGuide={guidanceShow.value}
            onClose={() => (state.settingPcStatus = false)}
          />
        </Popup>
      </div>
    );
  }
});
