<script setup>
import { provide, ref } from 'vue';
import { CirclePlusFilled } from '@element-plus/icons-vue';
import { ElMessage, ElSplitter, ElSplitterPanel, ElCard, ElButton, ElIcon } from 'element-plus';
import ClassBox from './teachableModel/ClassBox.vue';
import CameraBox from './teachableModel/CameraBox.vue';
import ModelArea from './teachableModel/ModelArea.vue';
import TrainArea from './teachableModel/TrainArea.vue';

// import 'element-plus/theme-chalk/src/message.scss';
// import 'element-plus/theme-chalk/src/splitter.scss';
// import 'element-plus/theme-chalk/src/splitter-panel.scss';
// import 'element-plus/theme-chalk/src/card.scss';
// import 'element-plus/theme-chalk/src/button.scss';
// import 'element-plus/theme-chalk/src/icon.scss';


// 存放所有拍摄的内容
const shotList = ref([])
provide('shotList', shotList)

// 存放类别和每个类别内含有的图片样本
const picList = ref([
    { title: '类别 1', list: [], disabled: false },
    { title: '类别 2', list: [], disabled: false },
])
provide('picList', picList)

// 训练状态
const states = ref({
    isTraining: 0, // 0为未开始，1为训练中，2为训练完成
})
provide('states', states)

// 向某个类别添加一个样本
async function handleAddSample(idx, data) {
    // 类别已被禁用
    if (picList.value[idx].disabled) {
        ElMessage.error('该类别已被禁用')
        return
    }
    // 可能传入 base64 字符串上传图片
    if (data) {
        // data 是 base64，说明是上传图片
        picList.value[idx].list.push(data)
        return
    }
    // 否则是拍摄，调用摄像头拍摄
    await handleParentShot()
    // 检查是否成功拍摄到图片
    if (
        !shotList.value[shotList.value.length - 1]
        || shotList.value[shotList.value.length - 1] === 'data:,'
    ) {
        ElMessage.error('未获取到有效样本')
        return
    }
    // 拍摄到的图片添加到类别中
    picList.value[idx].list.push(shotList.value[shotList.value.length - 1])
}

// 添加一个类别
function handleAddClass() {
    picList.value.push({
        title: `类别 ${picList.value.length + 1}`,
        list: [],
        disabled: false,
    })
}

// 删除一个类别
function handleDeleteClass(idx) {
    picList.value.splice(idx, 1)
}

// 禁用/启用一个类别
function handleDisableClass(idx) {
    picList.value[idx].disabled = !picList.value[idx].disabled
}

// 重命名一个类别
function handleRenameClass(idx, newTitle) {
    picList.value[idx].title = newTitle
}

// 清空一个类别的样本
function handleClearSamples(idx) {
    picList.value[idx].list = []
}

// 显示模型区域与否
const showModelArea = ref(true)

// 令摄像头拍摄一张图片加入shotList
const cameraBoxRef = ref(null)
async function handleParentShot() {
    await cameraBoxRef.value?.captureShot()
}

// 训练模型
const modelAreaRef = ref(null)
async function handleTrain() {
    await modelAreaRef.value.train()
}
</script>

<template>
    <div class="main-splitter">
        <ElSplitter>
            <ElSplitterPanel size="70%" :min="200">
                <div class="class-area">
                    <ClassBox v-for="(item, idx) in picList" :key="idx" :title="item.title" :pic-list="item.list"
                        :disabled="item.disabled" @add-sample="(data) => handleAddSample(idx, data)" @delete-sample="
                            (url) => (picList[idx].list = picList[idx].list.filter((i) => i !== url))
                        " @delete-class="handleDeleteClass(idx)" @disable-class="handleDisableClass(idx)"
                        @rename-class="(newTitle) => handleRenameClass(idx, newTitle)"
                        @clear-samples="handleClearSamples(idx)">
                        <ElButton type="primary" size="mini" @click="handleAddSample(idx)">
                            添加样本
                        </ElButton>
                    </ClassBox>
                    <ElCard class="add-class-card" @click="handleAddClass">
                        <div class="add-class-content">
                            添加一个类别
                            <ElIcon>
                                <CirclePlusFilled />
                            </ElIcon>
                        </div>
                    </ElCard>
                </div>
            </ElSplitterPanel>
            <ElSplitterPanel :min="200">
                <CameraBox ref="cameraBoxRef" />
                <transition name="fade-scale">
                    <ModelArea v-if="showModelArea" ref="modelAreaRef" @shot="handleParentShot" />
                </transition>
                <TrainArea @train="handleTrain" />
            </ElSplitterPanel>
        </ElSplitter>
    </div>
</template>

<style scoped>
.title {
    font-size: 24px;
    font-weight: 500;
    color: #011216;
    margin: 10px;
    padding: 10px;
    border-radius: 5px;
    background: linear-gradient(to right, #d7dee1, transparent, transparent, transparent);
    text-align: left;
}

.teachable-model-container {
    width: 80%;
    height: 80vh;
    margin: 20px;
    padding: 5px;
    border: 2px solid #000;
    border-radius: 5px;
    box-shadow: 0px 0px 10px #000;
}

.main-splitter {
    height: 100%;
    width: 100%;
    box-shadow: var(--el-border-color-light) 0px 0px 10px;
    user-select: none;
}

.add-class-card {
    margin: 10px auto;
    border: 1px dotted #000;
    max-width: 50vw;
    cursor: default;
    user-select: none;
    box-sizing: border-box;
}

.add-class-card:hover {
    cursor: pointer;
    color: #409eff;
}

.fade-scale-enter-active {
    transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
}

.fade-scale-leave-active {
    transition: all 0.3s cubic-bezier(0.55, 0, 0.1, 1);
}

.fade-scale-enter-from {
    opacity: 0;
    transform: scale(0.8);
}

.fade-scale-enter-to {
    opacity: 1;
    transform: scale(1);
}

.fade-scale-leave-from {
    opacity: 1;
    transform: scale(1);
}

.fade-scale-leave-to {
    opacity: 0;
    transform: scale(0.8);
}
</style>
