<template>
    <div class="page_dialog">
        <el-dialog 
            title="重新识别" 
            class="page_dialog" 
            :model-value="showDialog"  
            width="728px" 
            @close="handleClose"     
            append-to-body
        >
            <div class="dialog_center padding_20">
                <div class="re_identify">
                    <div class="identify_message">
                        已扫描{{ reIdentifyTotal }}张,点击"开始识别"进行重新识别。
                        <span style="color:#FF0000;">识别中过程不能关闭弹窗或离开页面。</span>
                    </div>
                    <div class="identify_center">
                        <div class="center_number_1">
                            <div class="center_title">
                                需识别张数<br>
                                <span class="span_number">{{ reIdentifyNumber }}</span>
                            </div>
                        </div>
                        <div class="center_number_1">
                            <div class="center_title">
                                已识别张数<br>
                                <span class="span_number">{{ recognizedNumber }}</span>
                            </div>
                        </div>
                    </div>
                    <div class="identify_progress">
                        <span>识别进度：</span>
                        <el-progress 
                            :percentage="reIdentifyProgress" 
                            :stroke-width="16" 
                            :color="customColor" 
                            :show-text="true"
                        ></el-progress>
                    </div>
                    <div class="identify_button">
                        <el-button 
                            type="primary" 
                            @click="StartReIdentify" 
                            :loading="reIdentifyLoading"
                        >
                            {{ reIdentifyText }}
                        </el-button>
                    </div>
                </div>
            </div>
        </el-dialog>
    </div>
</template>

<script lang="ts" setup>
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue';
// 1. 引入 Pinia store
import { useUserStore } from '@/store/user'
import { useExamStore } from '@/store/exam'

import WebSocketManager from '@/utils/webSocket.ts';
import { recognizeAgain } from '@/api/exam';
import { ElMessage } from 'element-plus';

// ==================== Props 定义 ====================
interface SchoolInfo {
    schoolId: string;      // 学校ID
    schoolName: string;    // 学校名称
}

const props = defineProps({
    /**
     * 控制弹窗显示/隐藏（v-model）
     */
    modelValue: {
        type: Boolean,
        required: true,
    },
    /**
     * 需要重新识别的总张数
     */
    reIdentifyTotal: {
        type: [String, Number],
        default: '0'
    },
    /**
     * 是否只识别客观题
     * 0 - 否（全部识别）
     * 1 - 是（仅客观题）
     */
    justObjective: {
        type: [String, Number],
        default: 1
    },
    /**
     * 学校信息对象
     */
    schoolInfo: {
        type: Object as () => SchoolInfo,
        default: () => ({
            schoolId: '',
            schoolName: ''
        })
    }
});

// ==================== Emits 定义 ====================
const emit = defineEmits([
    'update:modelValue',   // v-model 更新事件
    'ReIdentifyComplete'   // 重新识别完成事件
]);

// ==================== Store 实例化 ====================
const userStore = useUserStore()
const examStore = useExamStore()
// ==================== 响应式数据 ====================

// --- 上传相关（当前组件未使用，已注释）---
// const loading = ref(false);                          // 上传加载状态
// const selectedFiles = ref<any[]>([]);                // 选择的文件列表
// const previewImageList = ref<any[]>([]);             // 预览弹窗的图片列表
// const batchNumber = ref('');                         // 批次编号
// const batchNOID = ref('');                           // 批次号ID
// const sensitive = ref('165');                        // 灵敏度参数（0-255之间的奇数）
// const onnx = ref(0);                                 // 算法类型：0-正常算法，1-废资源算法
// const isUploading = ref(false);                      // 是否正在上传（防止重复点击）
// const debounceTimer = ref<any>(null);                // 防抖定时器
// const scanLoading = ref(false);                      // 扫描按钮loading状态

// --- 学校信息 ---
// const schoolId = ref('');        // 当前学校ID
const schoolName = ref('');      // 当前学校名称（带冒号后缀）

// --- 重新识别相关 ---
const reIdentifyUserId = ref('');           // 重新识别的用户ID（WebSocket连接标识）
const isReIdentify = ref(false);            // 是否处于重新识别状态
const reIdentifyNumber = ref(0);            // 需要识别的张数（剩余）
const recognizedNumber = ref(0);            // 已识别的张数
const reIdentifyProgress = ref(0);          // 重新识别进度百分比（0-100）
const reIdentifyText = ref('开始识别');     // 重新识别按钮文案
const reIdentifyLoading = ref(false);       // 重新识别按钮loading状态

// --- WebSocket 相关 ---
const websocketUrl = ref(import.meta.env.VUE_APP_WEB_SOCKET_URL || '');  // WebSocket链接地址
const socket = ref<any>(null);                                       // WebSocket实例对象

// --- 进度条配置 ---
/**
 * 自定义进度条颜色配置
 * 不同进度阶段显示不同颜色（当前统一为蓝色 #2E64FA）
 */
const customColor = [
    { color: '#2E64FA', percentage: 20 },
    { color: '#2E64FA', percentage: 40 },
    { color: '#2E64FA', percentage: 60 },
    { color: '#2E64FA', percentage: 80 },
    { color: '#2E64FA', percentage: 100 }
];

// ==================== 计算属性 ====================

/**
 * 弹窗显示状态（双向绑定）
 */
const showDialog = computed({
    get: () => props.modelValue,
    set: (val) => emit('update:modelValue', val)
});

/**
 * 当前考试科目ID
 * 从 Vuex Store 中获取
 */
const examSubjectId = computed(() => {
  return examStore.currentExam?.id
})//计算属性

const schoolId = computed(() => {
    return userStore.userInfo.schoolId;
});

/**
 * 剩余未上传完成的文件数量
 * 当前组件未使用，已注释
 */
// const remainCount = computed(() => {
//     return selectedFiles.value.filter(file => file.uploadStatus !== 0).length;
// });

/**
 * 账号学校类型
 * 0 - 单校版
 * 1 - 联校版
 * 当前组件未使用，已注释
 */
// const schoolType = computed(() => {
//     return store.state.user?.schoolType;
// });

/**
 * 考试学校类型
 * 0 - 单校版
 * 1 - 联校版
 * 当前组件未使用，已注释
 */
// const examSchoolType = computed(() => {
//     return store.state.makeTemplate?.examDetail?.schoolType;
// });

// ==================== 监听器 ====================

/**
 * 监听 reIdentifyTotal 变化
 * 当父组件传入的总张数变化时，同步更新本地变量
 */
watch(
    () => props.reIdentifyTotal,
    (newVal) => {
        reIdentifyNumber.value = Number(newVal);
    }
);

/**
 * 监听 schoolInfo 变化
 * 当学校信息变化时，更新本地的 schoolId 和 schoolName
 */
watch(
    () => props.schoolInfo,
    (newVal) => {
        console.log("监听到学校信息的改变了", newVal);
        if (newVal) {
            // schoolId.value = newVal.schoolId || '';
            schoolName.value = newVal.schoolName ? newVal.schoolName + ':' : '';
        }
    },
    { deep: true, immediate: true }
);

// ==================== 生命周期 ====================

/**
 * 组件挂载时执行
 * 初始化重新识别张数
 */
onMounted(() => {
    console.log("打印学校id", props.schoolInfo);
    reIdentifyNumber.value = Number(props.reIdentifyTotal);
});

/**
 * 组件卸载前执行
 * 清理资源：关闭WebSocket连接、清除定时器
 */
onBeforeUnmount(() => {
    // 清理 WebSocket 连接
    if (socket.value && socket.value.getSocketStatus() === WebSocket.OPEN) {
        socket.value.closeWebSocket();
    }
    // 清理定时器（当前未使用，保留以防后续扩展）
    // if (debounceTimer.value) {
    //     clearTimeout(debounceTimer.value);
    // }
});

// ==================== 方法定义 ====================

/**
 * 建立重新识别的 WebSocket 连接
 * @description 用于接收后端实时推送的识别进度消息
 */
const ReIdentifyWebSocketLink = () => {
    // 如果已有连接且处于打开状态，先关闭
    if (socket.value && socket.value.getSocketStatus() === WebSocket.OPEN) {
        socket.value.closeWebSocket();
    }

    // 构建 WebSocket 用户标识：AGAIN_ + 科目ID
    let userCourseId = '';
    console.log("打印用户信息", userStore.userInfo);
    userCourseId = "AGAIN_" + examSubjectId.value;
    reIdentifyUserId.value = userCourseId;
    console.log("打印重新识别的userCourseId", userCourseId);
    console.log("import.meta.env.NODE_ENV", import.meta.env.NODE_ENV);
    // 根据环境设置 WebSocket URL
    if (import.meta.env.MODE === 'development') {
        // 开发环境使用固定地址
        websocketUrl.value = 'wss://dev3.k12100.net/teaching/api/v1/teaching/websocket/';
    } else if (import.meta.env.MODE === 'production') {
        // 生产环境使用环境变量
        websocketUrl.value = import.meta.env.VUE_APP_WEB_SOCKET_URL || '';
    }

    // 拼接完整的 WebSocket URL
    const url = websocketUrl.value + userCourseId;
    console.log("打印websocket链接地址url", url);
    
    // 创建并启动 WebSocket 连接
    socket.value = new WebSocketManager(url, MessageBack);
    socket.value.start();
};

/**
 * 开始重新识别
 * @description 调用后端接口触发重新识别，并建立 WebSocket 连接接收进度
 */
const StartReIdentify = () => {
    // 如果已经识别完成，点击按钮则关闭弹窗并重置状态
    if (reIdentifyText.value === '识别完成') {
        showDialog.value = false;
        reIdentifyLoading.value = false;
        reIdentifyProgress.value = 0;
        reIdentifyText.value = '开始识别';
        return;
    }

    // 重置进度状态
    reIdentifyProgress.value = 0;
    reIdentifyLoading.value = true;
    reIdentifyText.value = '识别中';
    
    // 建立 WebSocket 连接
    ReIdentifyWebSocketLink();

    // 构建请求参数
    const param = {
        examSubjectId: examSubjectId.value,        // 考试科目ID
        recognizeNumber: props.reIdentifyTotal,    // 需要识别的总张数
        justObjective: props.justObjective,        // 是否只识别客观题
        schoolId: schoolId.value        // 学校ID
    };

    // 调用重新识别接口
    recognizeAgain(param).then(res => {
        console.log("重新识别结果", res);
        // reIdentifyLoading.value = false;
        if (res.code == 200) {
            // ElMessage.success("重新识别完成!");
            console.log("开始重新识别");
        }
        else
        {   
            
            ElMessage.error("重新识别失败！" + res.msg);
        }
    }).catch(err => {
        console.error("重新识别请求失败", err);
        ElMessage.error("网络请求失败");
    });
};

/**
 * WebSocket 消息回调处理
 * @param data - WebSocket 返回的消息字符串（JSON格式）
 * @description 接收后端推送的识别进度，更新UI显示
 */
const MessageBack = (data: string) => {
    const msg = JSON.parse(data);
    console.log("Websocket消息返回处理", msg);

    // code: 0-建立成功, 200-业务成功, 400-业务失败/异常
    if (msg.code === 200) {
        // 已识别张数 +1
        recognizedNumber.value++;
        // 待识别张数 -1
        reIdentifyNumber.value--;
        
        // 计算进度百分比
        const process = Math.round((Number(recognizedNumber.value) / Number(props.reIdentifyTotal)) * 100);
        reIdentifyProgress.value = Math.min(process, 100); // 确保不超过100%

        // 如果进度达到100%，表示识别完成
        if (reIdentifyProgress.value === 100) {
            ElMessage.success("重新识别完成!");
            
            // 重置所有状态
            reIdentifyNumber.value = 0;
            recognizedNumber.value = 0;
            reIdentifyProgress.value = 0;
            reIdentifyText.value = '识别完成';
            reIdentifyLoading.value = false;
            
            // 关闭弹窗
            showDialog.value = false;
            
            // 通知父组件识别完成
            emit('ReIdentifyComplete');
        }
    }
};

/**
 * 格式化文件名
 * @param fileName - 原始文件名
 * @returns 格式化后的文件名（超过17位时显示前5位+...+后12位）
 * @description 当前组件未使用，保留以备后续扩展
 */
// const FormatFileName = (fileName: string): string => {
//     if (fileName.length <= 17) {
//         return fileName;
//     }
//     const prefix = fileName.substring(0, 5);
//     const suffix = fileName.substring(fileName.length - 12);
//     return prefix + '...' + suffix;
// };

/**
 * 检查文件是否为图片
 * @param fileName - 文件名
 * @returns 是否为图片文件
 * @description 当前组件未使用，保留以备后续扩展
 */
// const isImageFile = (fileName: string): boolean => {
//     const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'];
//     const lowerFileName = fileName.toLowerCase();
//     return imageExtensions.some(ext => lowerFileName.endsWith(ext));
// };

/**
 * 获取文件预览URL
 * @param file - 文件对象
 * @returns 预览URL
 * @description 当前组件未使用，保留以备后续扩展
 */
// const getFilePreviewUrl = (file: File): string => {
//     if (window.URL && file) {
//         return window.URL.createObjectURL(file);
//     }
//     return '';
// };

/**
 * 关闭弹窗
 * @description 重置状态并通知父组件
 */
const handleClose = () => {
    showDialog.value = false;
    // selectedFiles.value = [];  // 当前未使用
    emit('close');
};

/**
 * 取消上传
 * @description 当前组件未使用，保留以备后续扩展
 */
// const CancelUpload = () => {
//     selectedFiles.value = [];
//     emit('CancelUpload', batchNumber.value);
//     showDialog.value = false;
// };

// ==================== 暴露方法 ====================
defineExpose({
    handleClose
    // CancelUpload  // 当前未使用
});
</script>

<style lang="scss" scoped>
// 样式保持不变
</style>