<template>
  <scoring-panel-container
    v-model="modalVisible"
    draggable
    title="键盘给分"
    modal-class="no-mask"
    :width="useVW(550)"
    :modal="false"
    @close="onToggleClick"
  >
    <div class="scoring-panel-box" :class="getClass('modal-box')">
      <template v-for="(question, index) in questionList" :key="question.mainNumber + question.subNumber">
        <scoring-panel-item
          v-model:score="scoreValues[index]"
          :active="activeIndex === index"
          :modal="dialogMode"
          :toggle-modal="props.toggleModal && index === 0"
          :question="question"
          @enter="() => onEnter(index)"
          @focused="() => onFocused(index)"
          @toggle-click="onToggleClick"
        ></scoring-panel-item>
      </template>
    </div>
    <template #footer>
      <el-button type="primary" class="full-w m-t-base" :disabled="!allowSubmit" @click="onSubmit">确定</el-button>
    </template>
  </scoring-panel-container>
</template>

<script setup lang="ts" name="ScoringPanel">
import { watch, withDefaults, ref, defineComponent, useSlots, computed } from 'vue'

import { ElButton } from 'element-plus'
import BaseDialog from '@/components/element/BaseDialog.vue'
import ScoringPanelItem from './ScoringPanelItem.vue'
import useVModel from '@/hooks/useVModel'
import useVW from '@/hooks/useVW'
import useFetch from '@/hooks/useFetch'

const props = withDefaults(
  defineProps<{
    /** 弹窗模式? */
    modal?: boolean
    /** 是否可以切换显示模式 */
    toggleModal?: boolean
    /** 显示隐藏 */
    visible?: boolean
    /** 分值 */
    score: (number | string)[]
    mainNumber?: number | null
  }>(),
  { modal: false, toggleModal: true, score: () => [], mainNumber: null }
)

const emits = defineEmits(['submit', 'update:score', 'update:visible'])

const dialogMode = ref<boolean>(props.modal)

const LessRenderComponent = defineComponent({
  name: 'LessRender',
  inheritAttrs: false,
  props: {
    modelValue: {
      type: Boolean,
      default: false,
    },
  },
  render() {
    return this.modelValue ? useSlots()?.default?.() : null
  },
})

const ScoringPanelContainer = computed(() => {
  return dialogMode.value ? BaseDialog : LessRenderComponent
})

const modalVisible = useVModel(props, 'visible')

watch(modalVisible, () => {
  if (!modalVisible.value) {
    activeIndex.value = 0
  }
})

const getClass = (val: string, callback?: string) => {
  return dialogMode.value ? val : callback || ''
}

const scoreValues = useVModel(props, 'score')

const activeIndex = ref<number>(0)

const { fetch: getQuestionStruct, reset: resetQuestionStruct, result: questionStruct } = useFetch('getQuestionStruct')

watch(
  () => props.mainNumber,
  () => {
    /** reset scores */
    scoreValues.value = []
    /** auto show */
    modalVisible.value = !!props.mainNumber
    if (props.mainNumber) {
      resetQuestionStruct()
      getQuestionStruct({ mainNumber: props.mainNumber })
    }
  },
  { immediate: true }
)

const questionList = computed(() => {
  if (!questionStruct.value) {
    return []
  }
  const { mainNumber, mainTitle, questionList = [] } = questionStruct.value
  return questionList.map((q) => ({ ...q, mainNumber, mainTitle }))
})

const allowSubmit = computed(() => {
  return questionList.value?.length && scoreValues.value?.length === questionList.value?.length
})

const onSubmit = () => {
  emits('submit', questionStruct.value)
}

const onEnter = (index: number) => {
  activeIndex.value = index + 1
  if (activeIndex.value >= questionList.value?.length) {
    onSubmit()
  }
}

const onFocused = (index: number) => {
  activeIndex.value = index
}

const onToggleClick = () => {
  dialogMode.value = props.toggleModal ? !dialogMode.value : dialogMode.value
  if (!props.toggleModal) {
    modalVisible.value = false
  }
}
</script>

<style scoped lang="scss">
.modal-box {
  max-height: 50vh;
  min-height: 8vw;
}
</style>
