<template>
  <div class="writing-board-tool" @click.stop>
    <div class="writing-board-wrap"
      :style="{
        width: slideWidth + 'px',
        height: slideHeight + 'px',
      }"
      @click.stop
    >
      <WritingBoard 
        ref="writingBoardRef" 
        :color="writingBoardColor" 
        :blackboard="blackboard" 
        :model="writingBoardModel"
        :penSize="penSize"
        :markSize="markSize"
        :rubberSize="rubberSize"
        :shapeSize="shapeSize"
        :shapeType="shapeType"
        :readonly="readonly"
        @end="hanldeWritingEnd()"
      />
    </div>

    <MoveablePanel 
      v-if="!readonly"
      class="tools-panel" 
      :width="510" 
      :height="50"
      :left="left" 
      :top="top"
    >
      <div class="tools" @mousedown.stop>
        <div class="tool-content">
          <Popover placement="top" trigger="manual" :value="sizePopoverType === 'pen'" @hide="sizePopoverType = ''">
            <template #content>
              <div class="setting">
                <div class="label">{{ lang.ssInkWidth }}</div>
                <Slider class="size-slider" :min="4" :max="10" :step="2" v-model:value="penSize" />
              </div>
            </template>
            <div class="btn" :class="{ 'active': writingBoardModel === 'pen' }" v-tooltip="lang.ssPenTool" @click="changeModel('pen')">
              <IconWrite class="icon" />
            </div>
          </Popover>
          <Popover placement="top" trigger="manual" :value="sizePopoverType === 'shape'" @hide="sizePopoverType = ''">
            <template #content>
              <div class="setting shape">
                <div class="shapes">
                  <IconSquare class="icon" :class="{ 'active': shapeType === 'rect' }" @click="shapeType = 'rect'" />
                  <IconRound class="icon" :class="{ 'active': shapeType === 'circle' }" @click="shapeType = 'circle'" />
                  <IconArrowRight class="icon" :class="{ 'active': shapeType === 'arrow' }" @click="shapeType = 'arrow'" />
                </div>
                <Divider type="vertical" />
                <div class="label">{{ lang.ssInkWidth }}</div>
                <Slider class="size-slider" :min="2" :max="8" :step="2" v-model:value="shapeSize" />
              </div>
            </template>
            <div class="btn" :class="{ 'active': writingBoardModel === 'shape' }" v-tooltip="lang.ssShape" @click="changeModel('shape')">
              <IconGraphicDesign class="icon" />
            </div>
          </Popover>
          <Popover placement="top" trigger="manual" :value="sizePopoverType === 'mark'" @hide="sizePopoverType = ''">
            <template #content>
              <div class="setting">
                <div class="label">{{ lang.ssInkWidth }}</div>
                <Slider class="size-slider" :min="16" :max="40" :step="4" v-model:value="markSize" />
              </div>
            </template>
            <div class="btn" :class="{ 'active': writingBoardModel === 'mark' }" v-tooltip="lang.ssHighlight" @click="changeModel('mark')">
              <IconHighLight class="icon" />
            </div>
          </Popover>
          <Popover placement="top" trigger="manual" :value="sizePopoverType === 'eraser'" @hide="sizePopoverType = ''">
            <template #content>
              <div class="setting">
                <div class="label">{{ lang.ssEraserSz }}</div>
                <Slider class="size-slider" :min="20" :max="200" :step="20" v-model:value="rubberSize" />
              </div>
            </template>
            <div class="btn" :class="{ 'active': writingBoardModel === 'eraser' }" v-tooltip="lang.ssEraser" @click="changeModel('eraser')">
              <IconErase class="icon" />
            </div>
          </Popover>
          <div class="btn" v-tooltip="lang.ssClearInk" @click="clearCanvas()">
            <IconClear class="icon" />
          </div>
          <div class="btn" :class="{ 'active': blackboard }" v-tooltip="lang.ssBlackboard" @click="handleBlackboardToggle">
            <IconFill class="icon" />
          </div>
          <div class="colors">
            <div 
              class="color" 
              :class="{ 'active': color === writingBoardColor, 'white': color === '#ffffff' }"
              v-for="color in writingBoardColors"
              :key="color"
              :style="{ backgroundColor: color }"
              @click="changeColor(color)"
            ></div>
          </div>
        </div>
        <div class="btn close" v-tooltip="lang.ssClosePen" @click="closeWritingBoard()">
          <IconClose class="icon" />
        </div>
      </div>
    </MoveablePanel>
  </div>
</template>

<script lang="ts" setup>
import { ref, watch, useTemplateRef } from 'vue'
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import { db } from '@/utils/database'

import WritingBoard from '@/components/WritingBoard.vue'
import MoveablePanel from '@/components/MoveablePanel.vue'
import Slider from '@/components/Slider.vue'
import Popover from '@/components/Popover.vue'
import Divider from '@/components//Divider.vue'
import { lang } from '@/main'

const writingBoardColors = ['#000000', '#ffffff', '#1e497b', '#4e81bb', '#e2534d', '#9aba60', '#8165a0', '#47acc5', '#f9974c', '#ffff3a']

type WritingBoardModel = 'pen' | 'mark' | 'eraser' | 'shape'

const props = withDefaults(defineProps<{
  slideWidth: number
  slideHeight: number
  left?: number
  top?: number
  readonly?: boolean
  syncDataURL?: string | null
  syncBlackboard?: boolean | null
}>(), {
  left: -5,
  top: -5,
  readonly: false,
  syncDataURL: null,
  syncBlackboard: null,
})

const emit = defineEmits<{
  (event: 'close'): void
  (event: 'drawing-end', dataURL: string): void
  (event: 'blackboard-change', blackboard: boolean): void
}>()

const { currentSlide } = storeToRefs(useSlidesStore())

const writingBoardRef = useTemplateRef<InstanceType<typeof WritingBoard>>('writingBoardRef')
const writingBoardColor = ref('#e2534d')
const writingBoardModel = ref<WritingBoardModel>('pen')
const blackboard = ref(false)
const sizePopoverType = ref<'' | WritingBoardModel>('')
const shapeType = ref<'rect' | 'circle' | 'arrow'>('rect')

const penSize = ref(6)
const markSize = ref(24)
const rubberSize = ref(80)
const shapeSize = ref(4)

const changeModel = (model: WritingBoardModel) => {
  writingBoardModel.value = model
  sizePopoverType.value = sizePopoverType.value === model ? '' : model
}

// 清除画布上的墨迹
const clearCanvas = () => {
  writingBoardRef.value!.clearCanvas()
}

// 修改画笔颜色，如果当前处于橡皮状态则先切换到画笔状态
const changeColor = (color: string) => {
  if (writingBoardModel.value === 'eraser') writingBoardModel.value = 'pen'
  writingBoardColor.value = color
}

// 处理小黑板切换
const handleBlackboardToggle = () => {
  if (props.readonly) return // 只读模式下不允许切换
  blackboard.value = !blackboard.value
  // 通知父组件小黑板状态变化
  emit('blackboard-change', blackboard.value)
}

// 关闭写字板
const closeWritingBoard = () => {
  // 只读模式下不允许关闭
  if (props.readonly) {
    console.log('📝 只读模式下不允许关闭画图工具')
    return
  }
  emit('close')
}

// 打开画笔工具或切换页面时，将数据库中存储的墨迹绘制到画布上
watch(currentSlide, () => {
  if (props.readonly) return // 只读模式下不从数据库加载
  db.writingBoardImgs.where('id').equals(currentSlide.value.id).toArray().then(ret => {
    const currentImg = ret[0]
    writingBoardRef.value!.setImageDataURL(currentImg?.dataURL || '')
  })
}, { immediate: true })

// 监听同步数据（学生端接收老师端的画图数据）
watch(() => props.syncDataURL, (newDataURL) => {
  if (props.readonly && newDataURL && writingBoardRef.value) {
    writingBoardRef.value.setImageDataURL(newDataURL)
  }
}, { immediate: true })

// 监听同步小黑板状态（学生端接收老师端的小黑板状态）
watch(() => props.syncBlackboard, (newBlackboard) => {
  if (props.readonly && newBlackboard !== null) {
    blackboard.value = newBlackboard
  }
}, { immediate: true })

// 每次绘制完成后将绘制完的图片更新到数据库
const hanldeWritingEnd = () => {
  if (props.readonly) return // 只读模式下不保存
  const dataURL = writingBoardRef.value!.getImageDataURL()
  if (!dataURL) return

  db.writingBoardImgs.where('id').equals(currentSlide.value.id).toArray().then(ret => {
    const currentImg = ret[0]
    if (currentImg) db.writingBoardImgs.update(currentImg, { dataURL })
    else db.writingBoardImgs.add({ id: currentSlide.value.id, dataURL })
  })
  
  // 触发绘制结束事件，用于同步
  emit('drawing-end', dataURL)
}
</script>

<style lang="scss" scoped>
.writing-board-tool {
  font-size: 12px;
  z-index: 10;
  @include absolute-0();

  .writing-board-wrap {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }

  .tools {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .tool-content {
    display: flex;
    align-items: center;
  }
  .btn {
    padding: 5px;
    margin-right: 5px; 
    border-radius: $borderRadius;
    cursor: pointer;

    &:hover {
      color: $themeColor;
    }
    &.active {
      background-color: rgba($color: $themeColor, $alpha: .5);
      color: #fff;
    }
    &.close {
      margin-right: 0;
      margin-left: 5px;
    }
  }
  .icon {
    font-size: 20px;
  }
  .colors {
    display: flex;
    padding: 0 5px;
  }
  .color {
    width: 16px;
    height: 16px;
    border-radius: $borderRadius;
    cursor: pointer;

    &:hover {
      transform: scale(1.15);
    }
    &.active {
      transform: scale(1.3);
    }
    &.white {
      border: 1px solid #f1f1f1; 
    }

    & + .color {
      margin-left: 8px;
    }
  }
}
.setting {
  width: 200px;
  display: flex;
  align-items: center;
  user-select: none;
  font-size: 13px;

  &.shape {
    width: 280px;
  }

  .shapes {
    display: flex;
    align-items: center;

    .icon {
      font-size: 20px;
      cursor: pointer;

      & + .icon {
        margin-left: 6px; 
      }

      &.active {
        color: $themeColor;
      }
    }
  }

  .label {
    width: 70px;
  }
  .size-slider {
    flex: 1;
  }
}
</style>