import { Tag, Image, Button } from 'vant'
import { computed, defineComponent, nextTick, onMounted, PropType, reactive, ref } from 'vue'
import styles from './index.module.less'
import { useRect } from '@vant/use'
import { AnswerType, QuestionType } from '../../unit'
import AnserTitle from '../anser-title'
import AnswerAnalysis from '../answer-analysis'

// 单选和多选题
export default defineComponent({
  name: 'keep-look-question',
  props: {
    value: {
      type: Array,
      default: () => []
    },
    index: {
      // 题目是第几道
      type: Number,
      default: 1
    },
    data: {
      type: Object,
      default: () => ({})
    },
    /* 只读 */
    readOnly: {
      type: Boolean,
      default: false
    },
    showRate: {
      type: Boolean,
      default: false
    },
    showAnalysis: {
      // 是否显示解析
      type: Boolean,
      default: false
    },
    analysis: {
      type: Object,
      default: () => ({
        message: '',
        topic: false, // 是否显示结果
        userResult: true // 用户答题对错
      })
    }
  },
  emits: ['update:value'],
  setup(props, { emit }) {
    const canvasRef = ref()
    const state = reactive({
      answerDomId: 'answer' + +new Date(),
      answerRect: {} as any,
      sortable: null as any,
      list: [] as any,
      options: [] as any,
      drawLineList: [] as any,
      selectItem: [] as any
    })
    /* 
    drawLineList 下的对象 
      {
          startPoint: { x: 0, y: 0 },
          endPoint: { x: 0, y: 0},
          leftIndex: 1,
          rightIndex: 2
        }
    */
    const onLeftClick = (e: any, item: any) => {
      // 是否只读
      if (props.readOnly) return
      state.options.forEach((option: any) => {
        if (!option.leftLocked && item.index !== option.index) {
          option.left = false
        }
      })

      const selectd = isDrawLine(item.index, 'left')
      // 判断当前元素是否已经连线了
      if (selectd.status) {
        state.options.forEach((option: any) => {
          if (!option.rightLocked) {
            option.right = false
          }
        })
        state.selectItem = []
        // 如果已经连线了则去掉
        state.drawLineList.splice(selectd.selectIndex, 1)
        // 重新绘制
        renderDrawLine(canvasRef.value)

        state.options.forEach((option: any) => {
          if (selectd.selectOption.leftIndex === option.index) {
            option.left = false
            option.leftLocked = false
          }
          if (selectd.selectOption.rightIndex === option.index) {
            option.right = false
            option.rightLocked = false
          }
        })
      } else {
        item.left = !item.left
        if (item.left) {
          // 为true时添加定位
          state.selectItem[0] = {
            index: item.index
          }
        } else {
          state.selectItem[0] = null
        }

        // 判断是否有二个的关联
        if (state.selectItem[0] && state.selectItem[1]) {
          const postion = calcPoint()
          state.drawLineList.push(postion)
          state.selectItem = []

          renderDrawLine(canvasRef.value)
        }
      }

      onSelect()
    }

    const onRightClick = (e: any, item: any) => {
      // 是否只读
      if (props.readOnly) return
      // 去掉
      state.options.forEach((option: any) => {
        if (!option.rightLocked && item.index !== option.index) {
          option.right = false
        }
      })
      const selectd = isDrawLine(item.index, 'right')

      // 判断当前元素是否已经连线了
      if (selectd.status) {
        state.options.forEach((option: any) => {
          if (!option.leftLocked) {
            option.left = false
          }
        })
        state.selectItem = []
        // console.log(
        //   selectd,
        //   'selected',
        //   JSON.stringify(state.drawLineList),
        //   state.drawLineList,
        //   state.drawLineList.length
        // )
        // 如果已经连线了则去掉
        state.drawLineList.splice(selectd.selectIndex, 1)
        // 重新绘制
        renderDrawLine(canvasRef.value)

        state.options.forEach((option: any) => {
          if (selectd.selectOption.leftIndex === option.index) {
            option.left = false
            option.leftLocked = false
          }
          if (selectd.selectOption.rightIndex === option.index) {
            option.right = false
            option.rightLocked = false
          }
        })
      } else {
        item.right = !item.right

        if (item.right) {
          // 为true时添加定位
          state.selectItem[1] = {
            index: item.index
          }
        } else {
          state.selectItem[1] = null
        }

        // 判断是否有二个的关联
        if (state.selectItem[0] && state.selectItem[1]) {
          const postion = calcPoint()
          state.drawLineList.push(postion)
          state.selectItem = []
          renderDrawLine(canvasRef.value)
        }
      }

      onSelect()
    }

    /**
     * @description 判断是否已连接
     * @param key 选中的选项标识
     * @returns status 状态,  selectIndex 索引, selectOption 选中选项
     */
    const isDrawLine = (key: number, type = 'left') => {
      const drawLineList = state.drawLineList || []
      let status = false // true 连，false 没连
      let selectIndex = 0 // 连了所在的索引
      let selectOption: any = {}
      drawLineList.forEach((item: any, index: number) => {
        if (item.leftIndex === key && type === 'left') {
          selectOption = item
          status = true
          selectIndex = index
        } else if (item.rightIndex === key && type === 'right') {
          selectOption = item
          status = true
          selectIndex = index
        }
      })
      return {
        status,
        selectIndex,
        selectOption
      }
    }

    /**
     * @description 计算连线坐标位置及左右关联编号，每次计算坐标的时候都取元素最新位置定位
     * @returns 连线的坐标
     */
    const calcPoint = () => {
      const canvasPostion = useRect(canvasRef.value)
      const leftSectionItem = state.selectItem[0]
      const firstPostion: any = useRect(
        document.getElementById(leftSectionItem.index + '-left') as any
      )
      firstPostion.index = leftSectionItem.index
      // console.log('🚀 ~ calcPoint ~ leftObj', leftObj)
      const rightSectionItem = state.selectItem[1]
      const secondPostion: any = useRect(
        document.getElementById(rightSectionItem.index + '-right') as any
      )
      secondPostion.index = rightSectionItem.index
      console.log(state.selectItem, firstPostion, secondPostion)
      const startPoint = {
        x: firstPostion.width,
        y: firstPostion.top + firstPostion.height / 2 - canvasPostion.top
      }

      const endPoint = {
        x: secondPostion.left - canvasPostion.left,
        y: secondPostion.top + secondPostion.height / 2 - canvasPostion.top
      }

      state.options.forEach((item: any) => {
        if (item.index === firstPostion.index) {
          item.leftLocked = true
        }
        if (item.index === secondPostion.index) {
          item.rightLocked = true
        }
      })
      return {
        startPoint,
        endPoint,
        leftIndex: firstPostion.index,
        rightIndex: secondPostion.index
      }
    }

    /**
     * @description 绘制连线
     * @param canvasRef 对象
     */
    const renderDrawLine = (canvasRef: any) => {
      // 重新画线
      if (canvasRef.getContext) {
        const ctx = canvasRef.getContext('2d')
        ctx.clearRect(0, 0, state.answerRect.width, state.answerRect.height)
        state.drawLineList.forEach((item: any) => {
          drawLine(ctx, item.startPoint, item.endPoint)
        })
      }
    }

    /**
     * @description 连线
     * @param ctx canvas 对象
     * @param startPoint 开始坐标
     * @param endPoint 结束坐标
     * @returns void(0)
     */
    const drawLine = (ctx: any, startPoint: any, endPoint: any) => {
      ctx.beginPath()
      ctx.moveTo(startPoint.x, startPoint.y)
      ctx.lineTo(endPoint.x, endPoint.y)
      ctx.lineWidth = 2
      ctx.strokeStyle = '#FF8057'
      ctx.stroke()
    }

    // 返回选中的结果
    const onSelect = () => {
      const options = state.options || []
      const drawLineList = state.drawLineList || []
      const result: any = []
      drawLineList.forEach((item: any) => {
        const leftOption = options.find((child: any) => child.index === item.leftIndex)
        const rightOption = options.find((child: any) => child.index === item.rightIndex)
        result.push({
          answerId: leftOption.index,
          answer: leftOption.leftValue,
          answerExtra: rightOption.rightValue
        })
      })
      emit('update:value', result)
    }

    const initOptions = () => {
      const answers = props.data.answers || []
      const userAnswer = props.data.userAnswer || [] // 用户填写的答案
      // console.log(answers, '111')
      answers.forEach((answer: any) => {
        const tmp = {
          index: answer.examinationQuestionAnswerId, // 左边的值
          leftValue: answer.questionAnswer, // 左边的值
          rightValue: answer.questionExtra, // 右边的值
          leftType: answer.questionAnswerTypeCode || 'TXT', // 左边类型
          rightType: answer.questionExtraTypeCode || 'TXT', // 右边类型
          left: false, // 左边是否选中
          right: false, // 右边是否选中
          leftLocked: false, // 是否已经连线
          rightLocked: false // 是否已经连线
        }

        state.options.push(tmp)
      })

      // 反显答案-初始化数据
      // console.log(userAnswer)
      userAnswer.forEach((user: any) => {
        const temps: any = {
          startPoint: { x: 0, y: 0 },
          endPoint: { x: 0, y: 0 },
          leftIndex: 0,
          rightIndex: 0
        }
        state.options.forEach((option: any) => {
          // 左边状态
          if (option.index === user.answerId) {
            option.left = true
            option.leftLocked = true
            temps.leftIndex = option.index
          }
          // 右边状态
          // console.log(option, user, '----')
          if (option.rightValue === user.answerExtra) {
            option.right = true
            option.leftLocked = true
            temps.rightIndex = option.index
          }
        })
        state.drawLineList.push(temps)
      })

      // console.log(state.drawLineList, state.options)
      // 反显答案-连线
      nextTick(() => {
        state.drawLineList.forEach((draw: any) => {
          state.selectItem = []
          const leftObj: any = useRect(document.getElementById(draw.leftIndex + '-left') as any)
          leftObj.index = draw.leftIndex
          state.selectItem[0] = leftObj
          const rightObj: any = useRect(document.getElementById(draw.rightIndex + '-right') as any)
          rightObj.index = draw.rightIndex
          state.selectItem[1] = rightObj
          const postion = calcPoint()
          draw.endPoint = postion.endPoint
          draw.startPoint = postion.startPoint
          state.selectItem = []
        })
        setTimeout(() => {
          renderDrawLine(canvasRef.value)
        }, 100)
      })
    }

    onMounted(() => {
      initOptions()
      // 获取canvas 对象
      nextTick(() => {
        // 获取canvas元素定位
        const answer: any = document.getElementById(state.answerDomId)
        const answerRect = useRect(answer)
        state.answerRect = answerRect
      })
    })

    return () => (
      <>
        <div class={styles.unitSubject}>
          {/* 标题 */}
          <AnserTitle
            index={props.index}
            name={props.data.name}
            score={props.data.totalScore}
            showRate={props.showRate}
            answerType={QuestionType.LINK}
            extra={{
              questionDetail: props.data.questionDetail,
              mediaUrls: props.data.mediaUrls,
              rightRate: props.data.rightRate
            }}
          />

          <div class={[styles.unitAnswers]} id={state.answerDomId}>
            <canvas
              ref={canvasRef}
              class={styles.canvasSection}
              width={state.answerRect.width || 0}
              height={state.answerRect.height || 0}
            ></canvas>
            {state.options.map((item: any) => (
              <div class={styles.answerItem}>
                <div
                  class={[styles.unitItem, item.left && styles.active]}
                  id={item.index + '-left'}
                  onClick={(e: any) => onLeftClick(e, item)}
                >
                  {item.leftType === AnswerType.TXT && item.leftValue}
                  {item.leftType === AnswerType.IMAGE && (
                    <Image src={item.leftValue} class={styles.img} />
                  )}
                </div>
                <div
                  class={[styles.unitItem, item.right && styles.active]}
                  id={item.index + '-right'}
                  onClick={(e: any) => onRightClick(e, item)}
                >
                  {item.rightType === AnswerType.TXT && item.rightValue}
                  {item.rightType === AnswerType.IMAGE && (
                    <Image src={item.rightValue} class={styles.img} />
                  )}
                </div>
              </div>
            ))}
          </div>
          <div class={styles.resetBtnGroup}>
            <Button
              round
              type="primary"
              disabled={props.readOnly}
              onClick={() => {
                state.drawLineList = []
                renderDrawLine(canvasRef.value)

                // 清除所有的选中状态
                state.options.forEach((item: any) => {
                  item.left = false
                  item.right = false
                  item.leftLocked = false
                  item.rightLocked = false
                })
                // 清除所有的选择的内容
                state.selectItem = []
              }}
            >
              重置
            </Button>
          </div>
        </div>

        {props.showAnalysis && (
          <div class={styles.unitSubject}>
            <AnswerAnalysis
              answerAnalysis={props.analysis.message}
              topic={props.analysis.topic}
              userResult={props.analysis.userResult}
            />
          </div>
        )}
      </>
    )
  }
})
