<template>
    <div class="patient-test">
        <el-card>
            <template #header>
                <div class="card-header">
                    <span>医疗助理端 - 接听来电</span>
                </div>
            </template>
            
            
            <div v-if="!initialized" class="init-section">
                <el-alert 
                    type="info" 
                    :closable="false"
                    class="mb-4"
                >
                    <p><strong>当前登录用户:</strong> {{ currentUser.nickname || currentUser.name || '未知' }}</p>
                    <p><strong>用户ID:</strong> {{ currentUser.id || '未获取' }}</p>
                    <p><strong>状态:</strong> 正在初始化...</p>
                </el-alert>
                
                <el-button 
                    type="primary" 
                    @click="initPatient" 
                    :loading="loading"
                    size="large"
                    v-if="!loading"
                >
                    重新初始化
                </el-button>
            </div>
            
            <div v-if="initialized" class="status">
                <el-alert 
                    :type="hasIncomingCall ? 'warning' : 'success'" 
                    :closable="false"
                >
                    <template #title>
                        <div class="flex items-center">
                            <el-icon class="mr-2" :class="{ 'animate-pulse': hasIncomingCall }">
                                <Phone />
                            </el-icon>
                            <span>{{ hasIncomingCall ? '收到来电！' : '医疗助理端已初始化，等待来电...' }}</span>
                        </div>
                    </template>
                    <div class="mt-2">
                        <p><strong>医疗助理ID:</strong> {{ currentUserId }}</p>
                        <p><strong>状态:</strong> {{ hasIncomingCall ? '来电中' : '在线' }}</p>
                        <p v-if="hasIncomingCall && incomingCallInfo">
                            <strong>通话类型:</strong> {{ incomingCallInfo.isGroup ? '群组视频通话' : '视频通话' }}
                        </p>
                    </div>
                </el-alert>
                
                <!-- 调试信息 -->
               
                
                <!-- 来电操作按钮 -->
                <div v-if="hasIncomingCall" class="call-actions mt-4">
                    <el-button 
                        type="success" 
                        size="large"
                        @click="acceptCall"
                        :icon="Phone"
                    >
                        接听
                    </el-button>
                    <el-button 
                        type="danger" 
                        size="large"
                        @click="rejectCall"
                    >
                        拒绝
                    </el-button>
                </div>
                
                <el-button 
                    v-else
                    type="danger" 
                    @click="reset"
                    class="mt-4"
                >
                    重置
                </el-button>
            </div>
            
            <div v-if="hasIncomingCall || callConnected" id="call-container" class="call-container phone-call-shell">
                <TUICallKit class="TUICallKit-mobile" />
            </div>
            
            <div v-else-if="initialized" class="waiting-container">
                <el-empty description="等待来电中...">
                    <template #image>
                        <el-icon :size="80" color="#909399">
                            <Phone />
                        </el-icon>
                    </template>
                </el-empty>
            </div>
            
            <!-- 离屏挂载：手机视口尺寸，避免 display:none 宽高为 0；与小程序端比例接近 -->
            <div
                v-if="initialized && !hasIncomingCall && !callConnected"
                class="phone-call-kit-host phone-call-kit-host--offscreen"
                aria-hidden="true"
            >
                <TUICallKit class="TUICallKit-mobile" />
            </div>
        </el-card>
    </div>
</template>

<script setup lang="ts">
import { ref, onUnmounted, computed, onMounted, nextTick } from 'vue'
import { Phone } from '@element-plus/icons-vue'
import {
    TUICallKitServer,
    TUICallKit,
    STATUS,
    TUIStore,
    StoreName,
    NAME,
    CallRole
} from '@tencentcloud/call-uikit-vue'
import { ElMessage, ElNotification } from 'element-plus'
import request from '@/utils/request'
import useUserStore from '@/stores/modules/user'

const userStore = useUserStore()
const currentUser = computed(() => userStore.userInfo)

const form = ref({
    patientId: computed(() => currentUser.value.id?.toString() || '1')
})

const loading = ref(false)
const initialized = ref(false)
const currentUserId = ref('')
const hasIncomingCall = ref(false)
const callConnected = ref(false)  // 添加通话连接状态
const incomingCallInfo = ref<any>(null)
const statusCheckTimer = ref<any>(null)
/** 从 TUIStore 同步：解决「未打开本页时来电，进入后 statusChanged 不触发」的问题 */
let storeUnwatch: (() => void) | null = null

// 页面加载时自动初始化
onMounted(() => {
    initPatient()
})

/**
 * 与 SDK 内 CallStatus 一致：idle / calling / connected
 * statusChanged 只在状态「变化」时回调；晚进页面时可能已在 calling，需读 Store。
 */
function syncIncomingFromTUIStore(from: string) {
    try {
        const callStatus = TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS) as string
        const callRole = TUIStore.getData(StoreName.CALL, NAME.CALL_ROLE) as string
        const isGroup = !!TUIStore.getData(StoreName.CALL, NAME.IS_GROUP)

        const wasIncoming = hasIncomingCall.value

        // 被叫振铃：calling + callee
        if (callStatus === 'calling' && callRole === CallRole.CALLEE) {
            hasIncomingCall.value = true
            incomingCallInfo.value = { isGroup, from }
            if (!wasIncoming) {
                ElMessage.info('检测到待接听的来电，请点击接听')
                ElNotification({
                    title: '来电提醒',
                    message: '有待接听的视频通话',
                    type: 'warning',
                    duration: 0,
                    position: 'top-right'
                })
            }
            callConnected.value = false
            return
        }

        // 已接通
        if (callStatus === 'connected') {
            hasIncomingCall.value = false
            incomingCallInfo.value = null
            callConnected.value = true
            return
        }

        // 空闲
        if (callStatus === 'idle') {
            if (hasIncomingCall.value || callConnected.value) {
                hasIncomingCall.value = false
                callConnected.value = false
                incomingCallInfo.value = null
            }
        }
    } catch (e) {
        console.warn('syncIncomingFromTUIStore:', from, e)
    }
}

function onStoreCallField() {
    syncIncomingFromTUIStore('watch')
}

function bindTUIStoreWatch() {
    if (storeUnwatch) {
        storeUnwatch()
        storeUnwatch = null
    }
    const opts = {
        [NAME.CALL_STATUS]: onStoreCallField,
        [NAME.CALL_ROLE]: onStoreCallField
    }
    try {
        TUIStore.watch(StoreName.CALL, opts)
        storeUnwatch = () => {
            try {
                TUIStore.unwatch(StoreName.CALL, opts)
            } catch {
                //
            }
        }
    } catch (e) {
        console.warn('TUIStore.watch 失败:', e)
    }
}

// 定时从 Store 拉状态（TIM 同步可能有延迟，前 45 秒加密轮询）
const startStatusCheck = () => {
    if (statusCheckTimer.value) {
        clearInterval(statusCheckTimer.value)
    }
    let ticks = 0
    const maxTicks = 90
    statusCheckTimer.value = setInterval(() => {
        ticks += 1
        syncIncomingFromTUIStore('poll')
        if (ticks >= maxTicks) {
            if (statusCheckTimer.value) {
                clearInterval(statusCheckTimer.value)
                statusCheckTimer.value = null
            }
        }
    }, 500)
}

// 监听状态变化
const handleStatusChange = ({ oldStatus, newStatus }: any) => {
    console.log('========================================')
    console.log('=== 通话状态变化回调触发 ===')
    console.log('oldStatus:', oldStatus)
    console.log('newStatus:', newStatus)
    console.log('STATUS 常量:', STATUS)
    console.log('========================================')
    
    // 收到来电邀请（与聊天组件同一套 SDK：@tencentcloud/call-uikit-vue）
    if (newStatus === STATUS.BE_INVITED) {
        console.log('>>> 收到来电邀请')
        hasIncomingCall.value = true
        incomingCallInfo.value = { oldStatus, newStatus }
        
        ElNotification({
            title: '来电提醒',
            message: '收到视频通话请求',
            type: 'info',
            duration: 0,
            position: 'top-right'
        })
        ElMessage.success('收到来电，请点击接听按钮')
    }
    
    // 通话接通
    if (newStatus === STATUS.CALLING_C2C_VIDEO || newStatus === STATUS.CALLING_GROUP_VIDEO) {
        console.log('>>> 通话已接通')
        ElMessage.success('通话已接通')
        hasIncomingCall.value = false
        callConnected.value = true  // 设置通话连接状态
    }
    
    // 通话结束，回到空闲状态（STATUS.IDLE 与聊天组件一致）
    if (newStatus === STATUS.IDLE) {
        if (hasIncomingCall.value || callConnected.value) {
            console.log('>>> 通话已结束')
            hasIncomingCall.value = false
            callConnected.value = false
            incomingCallInfo.value = null
            ElMessage.info('通话已结束')
        }
    }
}

const initPatient = async () => {
    try {
        loading.value = true
        
        const patientId = currentUser.value.id
        if (!patientId) {
            throw new Error('未获取到当前用户ID，请重新登录')
        }
        
        console.log('=== 开始初始化医疗助理端 ===')
        console.log('当前用户ID:', patientId)
        ElMessage.info('正在获取签名...')
        
        // 获取医疗助理签名
        const result = await request.get({
            url: '/tcm.diagnosis/getDoctorSignature',
            params: {
                patient_id: patientId
            }
        })
        
        if (!result) {
            throw new Error('获取签名失败')
        }
        
        const { sdkAppId, userId, userSig } = result
        currentUserId.value = userId
        
        console.log('医疗助理签名获取成功:', { userId, sdkAppId, userSigLength: userSig.length })
        console.log('完整签名信息:', result)
        ElMessage.info('正在初始化通话组件...')
        
        // 与聊天组件一致：使用 @tencentcloud/call-uikit-vue 的 TUICallKitServer（正式打包可收视频）
        console.log('=== 开始调用 TUICallKitServer.init ===')
        
        if (!TUICallKitServer || typeof TUICallKitServer.init !== 'function') {
            throw new Error('TUICallKitServer 未正确加载，请刷新页面重试')
        }
        
        try {
            await TUICallKitServer.init({
                userID: userId,
                userSig: userSig,
                SDKAppID: Number(sdkAppId)
            })
        } catch (initError: any) {
            console.warn('TUICallKitServer.init 出现错误，但继续执行:', initError)
        }
        
        console.log('=== TUICallKitServer.init 完成 ===')
        
        const callbacks = {
            statusChanged: handleStatusChange,
            onError: (error: any) => {
                console.error('=== TUICallKit 错误回调 ===', error)
                ElMessage.error(`通话错误: ${error?.message || '未知错误'}`)
            },
            onInvited: (inviteData: any) => {
                console.log('=== 收到邀请回调 (onInvited) ===', inviteData)
                ElMessage.info('收到通话邀请 (onInvited)')
            },
            afterCalling: () => {
                console.log('=== afterCalling 回调 ===')
            }
        }
        
        try {
            TUICallKitServer.setCallback(callbacks)
        } catch (callbackError: any) {
            console.warn('设置回调时出现错误，但继续执行:', callbackError)
        }
        
        console.log('回调设置完成')
        
        ElMessage.info('等待初始化完成...')
        
        // 等待 TIM/引擎就绪（未在本页时收到的邀请会在登录后由 SDK 同步）
        await new Promise(resolve => setTimeout(resolve, 2000))
        
        initialized.value = true
        await nextTick()
        await new Promise((r) => setTimeout(r, 300))

        // 需在 TUICallKit 挂载后订阅 Store（见模板里 v-if="initialized && ..." 的隐藏组件）
        bindTUIStoreWatch()
        syncIncomingFromTUIStore('post-init')
        startStatusCheck()

        ElMessage.success('医疗助理端初始化成功，等待来电...')
        
        console.log('=== 医疗助理端初始化完成 ===')
        console.log('userId:', userId)
        console.log('等待来电中...')
        console.log('请在医生端发起群组通话，目标用户ID应该是:', userId)
        
    } catch (error: any) {
        console.error('=== 初始化失败 ===', error)
        ElMessage.error(error.message || '初始化失败')
    } finally {
        loading.value = false
    }
}

/** 接听后自动关闭本地麦克风（助理端只听不说） */
async function muteLocalMicAfterAccept(): Promise<boolean> {
    await nextTick()
    await new Promise((r) => setTimeout(r, 400))
    try {
        const server = TUICallKitServer as typeof TUICallKitServer & {
            closeMicrophone?: () => Promise<void>
        }
        if (typeof server.closeMicrophone === 'function') {
            await server.closeMicrophone()
            return true
        }
        const engine = server.getTUICallEngineInstance?.()
        if (engine && typeof engine.closeMicrophone === 'function') {
            await engine.closeMicrophone()
            return true
        }
    } catch (e) {
        console.warn('接听后关闭麦克风失败（可在通话条手动关麦）:', e)
    }
    return false
}

// 接听来电
const acceptCall = async () => {
    try {
        console.log('接听来电')
        await TUICallKitServer.accept()
        ElMessage.success('已接听通话')
        hasIncomingCall.value = false
        callConnected.value = true  // 设置通话连接状态
        const muted = await muteLocalMicAfterAccept()
        if (muted) {
            ElMessage.info('已关闭本地麦克风')
        }
    } catch (error: any) {
        console.error('接听失败:', error)
        ElMessage.error(error.message || '接听失败')
    }
}

// 拒绝来电
const rejectCall = async () => {
    try {
        console.log('拒绝来电')
        await TUICallKitServer.reject()
        ElMessage.info('已拒绝通话')
        hasIncomingCall.value = false
        incomingCallInfo.value = null
    } catch (error: any) {
        console.error('拒绝失败:', error)
        ElMessage.error(error.message || '拒绝失败')
    }
}

const reset = () => {
    initialized.value = false
    currentUserId.value = ''
    hasIncomingCall.value = false
    callConnected.value = false
    incomingCallInfo.value = null
}

// 组件卸载时清理
onUnmounted(() => {
    if (statusCheckTimer.value) {
        clearInterval(statusCheckTimer.value)
        statusCheckTimer.value = null
    }
    if (storeUnwatch) {
        storeUnwatch()
        storeUnwatch = null
    }
    
    if (initialized.value) {
        // 清理资源
        hasIncomingCall.value = false
        callConnected.value = false
        incomingCallInfo.value = null
    }
})
</script>

<style scoped>
.patient-test {
    padding: 20px;
    max-width: 1200px;
    margin: 0 auto;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 18px;
    font-weight: bold;
}

.init-section {
    text-align: center;
    padding: 20px;
}

.status {
    margin: 20px 0;
}

.call-actions {
    display: flex;
    gap: 16px;
    justify-content: center;
}

/* 手机视口：375×667（逻辑像素），圆角边框模拟机身 */
.phone-call-shell {
    width: 375px;
    height: 667px;
    max-width: 100%;
    margin: 20px auto 0;
    padding: 0;
    border-radius: 36px;
    border: 12px solid #2c2c2e;
    box-shadow:
        0 0 0 2px #3a3a3c inset,
        0 16px 48px rgba(0, 0, 0, 0.22);
    background: #000;
    box-sizing: border-box;
}

.call-container {
    display: flex;
    align-items: stretch;
    justify-content: stretch;
    overflow: hidden;
    position: relative;
}

.call-container > * {
    width: 100%;
    height: 100%;
    flex: 1;
}

.waiting-container {
    width: 100%;
    min-height: 360px;
    margin-top: 20px;
    background: #f5f5f5;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* 离屏监听：保持真实手机宽高，利于 SDK 内部布局 */
.phone-call-kit-host {
    width: 375px;
    height: 667px;
    overflow: hidden;
    border-radius: 28px;
    background: #000;
}

.phone-call-kit-host--offscreen {
    position: fixed;
    left: -9999px;
    top: 0;
    z-index: -1;
    pointer-events: none;
    opacity: 0;
}

/* 确保 TUICallKit 组件正确显示 */
:deep(.call-container) {
    .tui-call-kit {
        width: 100%;
        height: 100%;
    }
    
    video {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }
}

/* 强制 TUICallKit 组件撑满容器 */
:deep(.TUICallKit) {
    width: 100% !important;
    height: 100% !important;
    position: relative !important;
}

:deep(.tui-call-kit) {
    width: 100% !important;
    height: 100% !important;
}

:deep(.tui-call-kit-mini) {
    display: none !important;
}

/* 隐藏 TUICallKit 的默认最小化窗口 */
:deep(.tui-call-kit-window) {
    width: 100% !important;
    height: 100% !important;
    min-height: 0 !important;
}

/* 确保视频容器撑满 */
:deep(.tui-video-container) {
    width: 100% !important;
    height: 100% !important;
}

:deep(.tui-call-kit-video) {
    width: 100% !important;
    height: 100% !important;
}

/* 隐藏所有可能的最小化或浮窗样式 */
:deep([class*="mini"]) {
    display: none !important;
}

:deep([class*="float"]) {
    width: 100% !important;
    height: 100% !important;
}

.mb-4 {
    margin-bottom: 16px;
}

.mt-2 {
    margin-top: 8px;
}

.mt-4 {
    margin-top: 16px;
}

.mr-2 {
    margin-right: 8px;
}

.flex {
    display: flex;
}

.items-center {
    align-items: center;
}

.animate-pulse {
    animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes pulse {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0.5;
    }
}

:deep(.el-alert__description) {
    margin-top: 8px;
}

:deep(.el-alert__description ol) {
    margin: 8px 0;
    padding-left: 20px;
}

:deep(.el-alert__description li) {
    margin: 4px 0;
}

.debug-info {
    font-size: 14px;
    line-height: 1.8;
}

.debug-info code {
    background: #f5f5f5;
    padding: 2px 6px;
    border-radius: 3px;
    color: #e6a23c;
    font-weight: bold;
}

.debug-info ul {
    margin: 8px 0;
    padding-left: 20px;
}

.debug-info li {
    margin: 4px 0;
}
</style>
