<template>
    <div class="app-container">
        <PermissionVerify ref="permissionVerify" />

        <template v-if="isAuthenticated">
            <div class="header-section">
                <div class="header-content">
                    <div class="title-area" @click="navigateHome">
                        <h1 class="page-title">电检工艺返修上线</h1>
                        <p class="page-subtitle">Electrical Repair Upline</p>
                    </div>
                    <div class="header-actions">
                        <!-- 电检开关控件 -->
                        <div class="switch-control">
                            <span class="switch-label">电检工艺路线：</span>
                            <el-switch v-model="electricStatus" active-value="1" inactive-value="0" active-text="开启"
                                inactive-text="关闭" inline-prompt :loading="electricSwitchLoading"
                                @change="handleElectricStatusChange" />
                        </div>
                        <div style="display: flex; align-items: center; color: #fff; opacity: 0.95; margin-left:16px;">
                            登录人：{{ loginUserName }}
                        </div>
                        <el-button type="danger" icon="SwitchButton" @click="handleLogout" size="small"
                            style="height: 30px; margin-left: 10px;">
                            退出登录
                        </el-button>
                    </div>
                </div>
            </div>

            <div class="scroll-container">
                <div class="mqtt-status-bar" v-if="mqttStatus.show" :class="mqttStatus.type">
                    <div class="mqtt-status-content">
                        <el-icon class="status-icon">
                            <component :is="mqttStatus.icon" />
                        </el-icon>
                        <span>{{ mqttStatus.message }}</span>
                    </div>
                </div>

                <!-- 上半部分：扫码与产品信息 -->
                <div class="top-section">
                    <div class="card">
                        <div class="form">
                            <div class="form-row">
                                <div class="form-item">
                                    <label class="form-label">产品扫码：</label>
                                    <el-input v-model.trim="scanCode" placeholder="支持 Model/PACK/箱体 码"
                                        @keyup.enter="handleScan" clearable prefix-icon="Scanner" />
                                </div>
                            </div>
                            <div class="form-row">
                                <div class="form-item">
                                    <label class="form-label">pack码：</label>
                                    <el-input v-model="formData.packNo" disabled prefix-icon="Tickets" />
                                </div>
                                <div class="form-item">
                                    <label class="form-label">发动机号：</label>
                                    <el-input v-model="formData.engineNo" disabled prefix-icon="Memo" />
                                </div>
                                <div class="form-item">
                                    <label class="form-label">产品型号：</label>
                                    <el-input v-model="formData.productType" disabled prefix-icon="Document" />
                                </div>
                            </div>

                            <div class="form-row">
                                <!-- <div class="form-item">
                                    <label class="form-label">机型代码：</label>
                                    <el-input v-model="formData.machineCode" disabled prefix-icon="Tools" />
                                </div> -->
                                <div class="form-item">
                                    <label class="form-label">上线时间：</label>
                                    <el-input v-model="formData.uplineTime" disabled prefix-icon="Clock" />
                                </div>
                                <div class="form-item">
                                    <label class="form-label">下线时间：</label>
                                    <el-input v-model="formData.downlineTime" disabled prefix-icon="Clock" />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 下半部分：返修上线口选择 -->
                <div class="bottom-section">
                    <div class="card">
                        <div class="form">
                            <div class="form-row">
                                <div class="form-item">
                                    <label class="form-label">返修上线口：</label>
                                    <el-input v-model.trim="repairUplineInput" placeholder="扫描返修上线口二维码"
                                        @keyup.enter="handleQueryRepairUpline" @input="handleRepairUplineInput"
                                        @blur="handleRepairUplineBlur" clearable @clear="handleClearRepairUpline"
                                        class="w-100">
                                        <template #prefix>
                                            <el-icon>
                                                <Rank />
                                            </el-icon>
                                        </template>
                                    </el-input>
                                </div>

                                <!-- <div class="form-item">
                                    <label class="form-label">再起始工位：</label>
                                    <el-input model-value="999 - 默认工位" disabled prefix-icon="Location" class="w-100" />
                                </div> -->

                                <!-- <div class="form-item">
                                    <label class="form-label">返修描述：</label>
                                    <el-input v-model.trim="formData.repairDesc" placeholder="请输入返修描述" clearable
                                        prefix-icon="EditPen" />
                                </div> -->
                                <div class="form-item form-actions">
                                    <el-button type="primary" :disabled="!canUpline" @click="handleUplineClick"
                                        icon="Upload">电检返修上线</el-button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 二次确认弹窗 -->
            <el-dialog v-model="confirmDialog.visible" title="返修上线确认" width="560px" :close-on-click-modal="false">
                <el-descriptions :column="1" border>
                    <el-descriptions-item label="pack码">{{ formData.packNo || '-' }}</el-descriptions-item>
                    <!-- <el-descriptions-item label="发动机号">{{ formData.engineNo || '-' }}</el-descriptions-item> -->
                    <el-descriptions-item label="产品型号">{{ formData.productType || '-' }}</el-descriptions-item>
                    <!-- <el-descriptions-item label="机型代码">{{ formData.machineCode || '-' }}</el-descriptions-item> -->
                    <!-- <el-descriptions-item label="返修描述">{{ formData.repairDesc || '-' }}</el-descriptions-item> -->
                    <!-- <el-descriptions-item label="再起始工位">999 (默认)</el-descriptions-item> -->
                    <el-descriptions-item label="返修上线口">{{ selectedRepairUplineStationLabel }}</el-descriptions-item>
                </el-descriptions>
                <template #footer>
                    <div style="display:flex; justify-content:flex-end; gap:8px;">
                        <el-button @click="confirmDialog.visible = false" icon="Close">取 消</el-button>
                        <el-button type="primary" :loading="confirmDialog.loading" @click="confirmPublish"
                            icon="Upload">确 认 上 线</el-button>
                    </div>
                </template>
            </el-dialog>
        </template>

        <div v-else class="auth-loading">
            <i class="el-icon-loading"></i>
            <p>正在进行权限验证...</p>
        </div>
    </div>
</template>

<script setup>
import { ref, reactive, onMounted, inject, computed, onBeforeUnmount, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import PermissionVerify from '@/components/PermissionVerify.vue'
import Cookie from 'js-cookie'
import { useRouter } from 'vue-router'
import { Location, Rank, Tickets, Memo, Document, Clock, EditPen, Upload, Close, Warning, CircleCheck, CircleClose } from '@element-plus/icons-vue'
import { Mqtt } from '@/utils/mqtt.js'

// 注入后端执行方法
const ExecDatabaseByParam = inject('ExecDatabaseByParam')
const CreateData = inject('CreateData')
const ExecDatabase = inject('ExecDatabase')

// 路由
const router = useRouter()

// 返回导航首页
const navigateHome = () => {
    router.push('/')
}

// 权限
const isAuthenticated = ref(false)
const permissionVerify = ref(null)
const userInfo = ref({})
const loginUserName = computed(() => Cookie.get('userName') || userInfo.value.姓名 || userInfo.value.userName || '-')

// 电检开关
const electricStatus = ref('0')
const electricSwitchLoading = ref(false)
const E_STATUS_NAME = '电检工艺路线开启状态'

// 表单与数据
const scanCode = ref('')
const loadingScan = ref(false)
const formData = reactive({
    id: null,
    packNo: '',
    engineNo: '',
    machineCode: '',
    productType: '',
    uplineTime: '',
    downlineTime: '',
    repairDesc: ''
})

// 下拉与选择
const uplineStationList = ref([]) // 返修上线口下拉
const selectedRepairUplineStation = ref('')
const repairUplineInput = ref('')

// 计算显示文本
const getLabelByValue = (listRef, value) => {
    if (!value) return ''
    const item = listRef.value.find(x => String(x.value) === String(value))
    return item ? item.label : value
}

const selectedRepairUplineStationLabel = computed(() => getLabelByValue(uplineStationList, selectedRepairUplineStation.value))

// 提交按钮是否可用
const canUpline = computed(() => {
    return !!(formData.packNo && selectedRepairUplineStation.value)
})

// 持久化变量读取
const readPersistentValue = (name) => {
    const param = []
    param[0] = ['工位号', 'PLCS']
    param[1] = ['名称', name]
    const Data = CreateData('11', 'MES_持久化变量_读取', param)
    return ExecDatabase(Data).then(response => {
        const row = response.data && response.data.length ? response.data[0] : null
        return row && row.值 ? String(row.值).trim() : ''
    })
}

// 持久化变量写入
const writePersistentValue = (name, value) => {
    const param = []
    param[0] = ['工位号', 'PLCS']
    param[1] = ['名称', name]
    param[2] = ['值', value || '']
    const Data = CreateData('12', 'MES_持久化变量_写入', param)
    return ExecDatabase(Data)
}

// 初始化读取电检状态
const fetchElectricStatus = async () => {
    try {
        const val = await readPersistentValue(E_STATUS_NAME)
        electricStatus.value = val === '1' ? '1' : '0'
    } catch (e) {
        ElMessage.error('读取电检工艺状态失败')
    }
}

// 修改电检状态
const handleElectricStatusChange = async (val) => {
    electricSwitchLoading.value = true
    try {
        await writePersistentValue(E_STATUS_NAME, val)
        ElMessage.success(`电检工艺路线已${val === '1' ? '开启' : '关闭'}`)
        const newVal = await readPersistentValue(E_STATUS_NAME)
        electricStatus.value = newVal === '1' ? '1' : '0'
    } catch (e) {
        ElMessage.error('设置电检工艺状态失败')
        // 恢复旧值
        const oldVal = await readPersistentValue(E_STATUS_NAME)
        electricStatus.value = oldVal === '1' ? '1' : '0'
    } finally {
        electricSwitchLoading.value = false
    }
}

// MQTT连接状态
const mqttStatus = reactive({
    show: false,
    type: 'success', // success, error, warning
    message: '',
    icon: 'CircleCheck'
})

// MQTT
let mqttTimeout = null
let mqttClient = null
const mqttConnection = reactive({
    host: window.g.mqttIP,
    port: window.g.mqttPortNumber,
    endpoint: '/mqtt',
    clean: true,
    connectTimeout: 4000,
    reconnectPeriod: 4000,
    clientId: '',
    username: '',
    password: ''
})
const publication = reactive({ topic: window.g.mqttPublishTopic, qos: 0, payload: '' })
const subscription = reactive({ topic: '', qos: 0 })

const createMqttConnection = () => {
    try {
        if (mqttClient) mqttClient.destroyConnection()

        mqttStatus.show = true
        mqttStatus.type = 'warning'
        mqttStatus.icon = 'Warning'
        mqttStatus.message = 'MQTT连接中...'

        mqttClient = new Mqtt(mqttConnection)
        mqttClient.createConnection()

        mqttClient.client.on('connect', () => {
            console.log('MQTT connected in electricRepairOnline')
            mqttStatus.show = true
            mqttStatus.type = 'success'
            mqttStatus.icon = 'CircleCheck'
            mqttStatus.message = 'MQTT已连接'
            setTimeout(() => {
                if (mqttStatus.type === 'success') {
                    mqttStatus.show = false
                }
            }, 3000)
        })

        mqttClient.client.on('reconnect', () => {
            mqttStatus.show = true
            mqttStatus.type = 'warning'
            mqttStatus.icon = 'Warning'
            mqttStatus.message = 'MQTT重新连接中...'
        })

        mqttClient.client.on('error', err => {
            mqttStatus.show = true
            mqttStatus.type = 'error'
            mqttStatus.icon = 'CircleClose'
            mqttStatus.message = `MQTT错误: ${err.message || '未知错误'}`
        })

        subscription.topic = window.g.mqttSubscriptionTopic
        mqttClient.doSubscribe(subscription)

        mqttClient.client.on('message', (topic, message) => {
            const parts = message.toString().split('|')
            const source = parts[0]
            const command = parts[1]
            if (source === 'MES' && command === 'RepairUplineMES') {
                const returnedUplineStation = (parts[2] || '').trim()
                const returnedProductNo = (parts[3] || '').trim()
                // 发的是 packNo 或 barcode，以触发扫码的为准
                if (
                    returnedUplineStation === String(selectedRepairUplineStation.value || '').trim() &&
                    returnedProductNo === String(scanCode.value || '').trim()
                ) {
                    onMqttRepairUplineSuccess()
                }
            }
        })
    } catch (e) {
        console.error('MQTT setup failed', e)
    }
}

const onMqttRepairUplineSuccess = async () => {
    try {
        clearTimeout(mqttTimeout)
        confirmDialog.loading = false
        confirmDialog.visible = false

        // MES_工位返修记录_上线口增加 @ID, @返修上线口, @再起始工位, @返修描述
        const param = []
        param[0] = ['ID', formData.id || 0]
        param[1] = ['返修上线口', selectedRepairUplineStation.value || '']
        param[2] = ['再起始工位', '999']
        param[3] = ['返修描述', formData.repairDesc || '']

        const data = CreateData('12', 'MES_工位返修记录_上线口增加', param)
        const res = await ExecDatabase(data)
        if (res.data && res.data.length >= 0) {
            if (res.data[0].result === "1" || res.data[0].result === 1) {
                ElMessage.success('返修上线成功，已记录数据库')
                resetForm(false)
            } else {
                ElMessage.error('数据库记录失败 请重试')
            }
        } else {
            ElMessage.warning('数据返回异常，请重发')
        }
    } catch (e) {
        ElMessage.error('数据库交互失败，请联系管理员')
    }
}

// 扫码查询产品信息
const handleScan = async () => {
    if (!scanCode.value) {
        ElMessage.warning('请先扫码或输入条码')
        return
    }
    loadingScan.value = true
    try {
        const param = []
        param[0] = ['barCode', scanCode.value]
        const data = CreateData('11', 'MES_电检艺路线返修上线_产品查询', param)
        const res = await ExecDatabase(data)

        const rows = Array.isArray(res.data) ? res.data : []
        if (!rows.length) {
            ElMessage.warning('未查询到该产品信息')
            clearProduct()
            return
        }

        const row = rows[0]
        formData.id = row.ID || null
        formData.packNo = row.pack码 || ''
        formData.engineNo = row.发动机号 || ''
        formData.machineCode = row.机型代码 || ''
        formData.productType = row.产品型号 || ''
        formData.uplineTime = row.上线时间 || ''
        formData.downlineTime = row.下线时间 || ''

    } catch (e) {
        console.error('扫码查询异常:', e)
        ElMessage.error('查询异常')
    } finally {
        loadingScan.value = false
    }
}

const clearProduct = () => {
    formData.packNo = ''
    formData.engineNo = ''
    formData.machineCode = ''
    formData.productType = ''
    formData.uplineTime = ''
    formData.downlineTime = ''
    formData.repairDesc = ''
}

const resetForm = (clearScan = true) => {
    if (clearScan) scanCode.value = ''
    clearProduct()
    selectedRepairUplineStation.value = ''
    repairUplineInput.value = ''
}

// 查询返修上线口
const handleQueryRepairUpline = async () => {
    if (!repairUplineInput.value) return
    try {
        const param = []
        param[0] = ['OpCode', repairUplineInput.value]
        const res = await ExecDatabaseByParam('11', 'MES_工位返修记录_编号查询上线口', param)

        if (res.data && res.data.length > 0) {
            const row = res.data[0]
            selectedRepairUplineStation.value = row.工位号
            repairUplineInput.value = `${row.工位号} - ${row.工位名称 || ''}`
        } else {
            ElMessage.warning('工位码不正确')
            repairUplineInput.value = ''
            selectedRepairUplineStation.value = ''
        }
    } catch (e) {
        ElMessage.error('查询上线口失败')
        repairUplineInput.value = ''
        selectedRepairUplineStation.value = ''
    }
}

const handleClearRepairUpline = () => {
    repairUplineInput.value = ''
    selectedRepairUplineStation.value = ''
}

const handleRepairUplineInput = () => {
    selectedRepairUplineStation.value = ''
}

const handleRepairUplineBlur = () => {
    if (!selectedRepairUplineStation.value) {
        repairUplineInput.value = ''
    }
}

// 加载返修上线口下拉 (沿用原接口)
const loadUplineStationList = async () => {
    try {
        const resUpline = await ExecDatabaseByParam('11', 'MES_计划BOM_工位与名称_查询_返修上线口', [])
        if (resUpline.data && resUpline.data.length > 0) {
            uplineStationList.value = resUpline.data.map(x => ({
                label: `${x.工位号} - ${x.工位名称 || ''}`,
                value: x.工位号
            }))
        }
    } catch (e) {
        ElMessage.error('加载返修上线口列表失败')
    }
}

// 二次确认弹窗
const confirmDialog = reactive({ visible: false, loading: false })
const handleUplineClick = async () => {
    if (!canUpline.value) {
        ElMessage.warning('产品和返修上线口不能为空')
        return
    }
    confirmDialog.visible = true
}

const confirmPublish = async () => {
    try {
        confirmDialog.loading = true
        // 格式：WEB|RepairUplineMES|返修上线口工位|再起始工位号^产品编号(使用扫描入的code)^订单号^产品型号^产品型号代码
        // 此模块固定999，很多字段为空也可以用下划线或者空代替，保持协议层一致
        const pubCode = scanCode.value || ''
        const pubType = formData.productType || ''
        const pubTypeCode = formData.machineCode || '0'
        const payload = `WEB|RepairUplineMES|${selectedRepairUplineStation.value}|999^${pubCode}^^${pubType}^${pubTypeCode}`

        publication.topic = window.g.mqttPublishTopic
        publication.payload = payload
        console.log(publication)
        const ok = mqttClient?.doPublish(publication)
        if (ok) {
            ElMessage.success('上线请求已发送，等待回执...')
            mqttTimeout = setTimeout(() => {
                confirmDialog.loading = false
                ElMessage.error('超时，未收到后端确认消息，请重试')
            }, 10000)
        } else {
            ElMessage.error('消息发送失败')
            confirmDialog.loading = false
        }
    } catch (e) {
        ElMessage.error('发送异常')
        confirmDialog.loading = false
    }
}

// 登录初始化相关
const checkPermission = async () => {
    try {
        const cookieUserId = Cookie.get('userId')
        const cookieUserName = Cookie.get('userName')
        if (cookieUserId && cookieUserName) {
            isAuthenticated.value = true
            userInfo.value = { UserID: cookieUserId, 姓名: cookieUserName }
            ElMessage.success(`欢迎 ${cookieUserName} 登录`)
            await initPage()
            return
        }

        // 需要管理员权限
        const result = await permissionVerify.value.show({
            title: '电检返修上线登录',
            promptText: '请刷卡验证 (管理员权限)',
            permissionLevel: '管理员'
        })
        if (result.success) {
            isAuthenticated.value = true
            userInfo.value = result.data
            ElMessage.success(`欢迎管理员 ${result.data.姓名 || result.data.userName} 登录`)
            await initPage()
        }
    } catch (e) {
        if (e.cancelled) {
            ElMessage.warning('已取消登录')
        } else {
            ElMessage.error('权限验证失败')
        }
    }
}

const initPage = async () => {
    await loadUplineStationList()
    await fetchElectricStatus()
    createMqttConnection()
}

// 退出登录
const handleLogout = async () => {
    try {
        await ElMessageBox.confirm('确定退出吗？', '提示', { type: 'warning' })
        isAuthenticated.value = false
        resetForm()
        Cookie.remove('userId')
        Cookie.remove('userName')
        router.push('/')
    } catch { }
}

const lastSubscribed = ref('')
const handleReSubscribe = () => {
    if (!mqttClient || !mqttClient.client) return
    const topic = window.g.mqttSubscriptionTopic + "/RepairUplinePAD"
    if (lastSubscribed.value && lastSubscribed.value !== topic) {
        mqttClient.doUnSubscribe({ topic: lastSubscribed.value })
    }
    subscription.topic = topic
    mqttClient.doSubscribe(subscription)
    lastSubscribed.value = topic
}

watch(
    () => selectedRepairUplineStation.value,
    async (newVal) => {
        if (isAuthenticated.value) handleReSubscribe()
    }
)

watch(() => confirmDialog.visible, (newVal) => {
    if (!newVal) {
        clearTimeout(mqttTimeout)
        confirmDialog.loading = false
    }
})

onMounted(() => {
    setTimeout(() => {
        if (permissionVerify.value) {
            permissionVerify.value.setCreateData(CreateData)
            permissionVerify.value.setExecDatabase(ExecDatabase)
            permissionVerify.value.setStore({
                state: {
                    station: { stationNumber: '' },
                    user: { name: Cookie.get('userName') || '' }
                }
            })
            checkPermission()
        }
    }, 300)
})

onBeforeUnmount(() => {
    try {
        if (mqttClient) mqttClient.destroyConnection()
    } catch { }
})
</script>

<style lang="scss" scoped>
.app-container {
    width: 100%;
    height: 100vh;
    background: #f0f2f5;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.scroll-container {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding-bottom: 20px;
}

.header-section {
    background: linear-gradient(135deg, #1f4037 0%, #99f2c8 100%);
    color: white;
    padding: 12px 16px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    flex-shrink: 0;
}

.header-content {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.title-area {
    cursor: pointer;
}

.page-title {
    font-size: 20px;
    font-weight: 600;
    margin: 0 0 4px 0;
    text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
}

.page-subtitle {
    font-size: 12px;
    opacity: 0.9;
    margin: 0;
}

.header-actions {
    display: flex;
    align-items: center;
}

.switch-control {
    background: rgba(255, 255, 255, 0.15);
    padding: 6px 12px;
    border-radius: 20px;
    display: flex;
    align-items: center;
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.2);
}

.switch-label {
    margin-right: 8px;
    font-size: 14px;
    font-weight: 500;
}

.top-section,
.bottom-section {
    padding: 12px;
}

.card {
    background: white;
    border-radius: 8px;
    padding: 16px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.form {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.form-row {
    display: flex;
    gap: 16px;
    align-items: flex-start;
}

.form-item {
    display: flex;
    align-items: center;
    flex: 1;
}

.form-item.form-actions {
    flex: none;
    justify-content: flex-end;
    gap: 12px;
}

.form-label {
    width: 135px;
    flex-shrink: 0;
    text-align: right;
    color: #606266;
    font-size: 14px;
    font-weight: 500;
    margin-right: 8px;
    white-space: nowrap;
}

.w-100 {
    width: 100%;
}

.mqtt-status-bar {
    padding: 8px 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    transition: all 0.3s ease;
}

.mqtt-status-bar.success {
    background-color: #f0f9ff;
    color: #67c23a;
    border-bottom: 1px solid #b3e19d;
}

.mqtt-status-bar.error {
    background-color: #fef0f0;
    color: #f56c6c;
    border-bottom: 1px solid #fab6b6;
}

.mqtt-status-bar.warning {
    background-color: #fdf6ec;
    color: #e6a23c;
    border-bottom: 1px solid #f5dab1;
}

.mqtt-status-content {
    display: flex;
    align-items: center;
    gap: 8px;
}

.status-icon {
    font-size: 16px;
}

.auth-loading {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100vh;
    color: #909399;
}

@media (max-width: 1200px) {
    .form-row {
        flex-wrap: wrap;
    }

    .form-item {
        min-width: 100%;
        margin-bottom: 4px;
    }

    .form-label {
        width: 140px;
        text-align: left;
    }
}

@media (orientation: portrait) {
    .app-container {
        height: 100dvh;
    }

    .page-title {
        font-size: 18px;
    }

    .form-label {
        width: 140px;
        font-size: 15px;
    }

    :deep(.el-input__wrapper) {
        min-height: 42px;
    }

    :deep(.el-input__icon) {
        font-size: 16px;
    }

    :deep(.el-button) {
        height: 42px;
    }
}
</style>