<template>
    <view class="call-center">
		<view v-if="contacts.length" class="contact-list">
			<view class="contact-card" v-for="contact in contacts" :key="contact.id">
			
				<view class="contact-info">
					<image class="contact-avatar" :src="contact.avatar" mode="aspectFill" />
					<view class="contact-meta">
						<text class="contact-name">{{ contact.username }}</text>
						<text class="contact-desc">{{ contact.className }}</text>
					</view>
				</view>
				<view class="action-buttons">
					<view class="action-btn" @click="startVoiceCall(contact)">
						<view class="action-btn-icon">
							<image src="/static/icon/audio.png" mode="aspectFit" />
						</view>
						<text>音频</text>
					</view>
					<view class="action-btn" @click="startVideoCall(contact)">
						<view class="action-btn-icon">
							<image src="/static/icon/video.png" mode="aspectFit" />
						</view>
						<text>视频</text>
					</view>
					<view class="action-btn" :class="{ 'message-point': contact.hasPoints }" @click="goToMessage(contact)">
						<view class="action-btn-icon">
							<image src="/static/icon/message.png" mode="aspectFit" />
						</view>
						<text>留言</text>
					</view>
				</view>
			</view>
		</view>
		<view v-else class="empty-tip">
			<text>暂未关联可呼叫的设备</text>
		</view>
	</view>
</template>

<script>
import { getImageUrl } from '@/utils/util'

const CALL_END_STORAGE_KEY = 'parentLastCallInfo'
const CALL_END_PAGE_URL = '/pages/parent/call-center'  // 通话结束返回通话中心页

let wmpfVoip = null
try {
	if (typeof requirePlugin === 'function') {
		wmpfVoip = requirePlugin('wmpf-voip').default
	}
} catch (error) {
	console.warn('wmpf-voip 插件暂不可用', error)
}

const miniprogramState = (() => {
	if (typeof wx === 'undefined' || typeof wx.getAccountInfoSync !== 'function') {
		return 'formal'
	}
	const accountInfo = wx.getAccountInfoSync()
	if (accountInfo && accountInfo.miniProgram) {
		const platform = { develop: 'developer', trial: 'trial', release: 'formal' }
		return platform[accountInfo.miniProgram.envVersion]
	}
	return 'formal'
})()


const DEFAULT_AVATAR = '/static/logo.png'
const DEFAULT_CLASS_NAME = '所属班级'

export default {
	data() {
		return {
			parentInfo: {
				xm: '张小同',
				openid: 'oKFvD4pG_iKBJR0wfjiDicm7fjaA'
				// openid: 'oKFvD4jogQe9DTDRNgFjW5ybobEU'
			},
			contacts: [
				{
					id: 'stu-001',
					username: '张小小同',
					className: '三年级二班',
					avatar: '/static/images/yishuzhao_nan.svg',
					deviceSn: 'A100006B623E86',
					pushToken: 'BgAADLbeQ1s4jDjapuGe4HKnrI-I-5D57-TLABuqXrB0saDv-fuzNlT-32rTadDMrLrpNLxcUMe1y6FlESz7-EVGC4kjHaK_P7WZQUfEhHzxP55ndPPrYOSzvq6aez115InzFIOM1PZhdNS5U6pItMBid7zqVX4',
				}
			],
			currentContact: null,
			_voipEndPathSet: false,
			_voipEventRegistered: false,
			defaultAvatar: DEFAULT_AVATAR,
			defaultClassName: DEFAULT_CLASS_NAME
		}
	},
	onLoad() {
		this.initParentInfo()
		this.registerVoipEvent()
	},
	methods: {
		initParentInfo() {
			let info = uni.getStorageSync('userInfo')
			if (typeof info === 'string') {
				try {
					info = JSON.parse(info)
				} catch (error) {
					info = null
				}
			}

			if (!info) {
				this.loadContactList()
				return
			}

			this.parentInfo = {
				...this.parentInfo,
				...info
			}

			this.loadContactList()
		},
		loadContactList() {
			// 统一处理联系人来源：仅格式化 data 中已有的联系人，保持展示/拨号结构一致
			const formatContact = (item = {}, index = 0) => ({
				id: item.id || `contact-${index}`,
				username: item.username || item.name || '学生',
				avatar: this.formatAvatar(item.avatar || item.yszwj),
				className: item.className || item.bjmc || item.bmmc || item.bjmcName || this.defaultClassName,
				deviceSn: item.deviceSn || item.sn || item.devId || '',
				pushToken: item.pushToken || item.voipToken || '',
				deviceName: item.deviceName || item.username || item.name || '家庭设备',
				hasPoints: !!item.hasPoints,
			})

			this.contacts = (this.contacts || []).map(formatContact)
		},
		formatAvatar(value) {
			if (!value) return this.defaultAvatar
			if (typeof value === 'string' && (value.startsWith('http') || value.startsWith('https') || value.startsWith('data:'))) {
				return value
			}
			return getImageUrl(value)
		},
		async startVoiceCall(contact) {
			await this.startCall(contact, 'voice')
		},
		async startVideoCall(contact) {
			await this.startCall(contact, 'video')
		},
		async startCall(contact, roomType) {
			if (!wmpfVoip) {
				uni.showToast({ title: '通话能力暂不可用', icon: 'none' })
				return
			}

			const callerId = this.parentInfo?.openid
			
			if (!callerId) {
				uni.showToast({ title: '缺少家长身份标识', icon: 'none' })
				return
			}

			if (!contact?.deviceSn) {
				uni.showToast({ title: '未找到可呼叫的设备编号', icon: 'none' })
				return
			}

			if (!contact?.pushToken) {
				uni.showToast({ title: '设备未上报通话凭证', icon: 'none' })
				return
			}

			uni.showLoading({ title: '呼叫中...', mask: true })
			this.currentContact = contact

			const callInfo = {
				name: contact.username || '家庭设备',
				avatar: contact.avatar || '/static/logo.png',
				duration: 0,
				time: new Date().toLocaleString(),
				type: roomType,
				status: '呼叫中'
			}
			uni.setStorageSync(CALL_END_STORAGE_KEY, callInfo)
			this.setVoipEndPagePath()

			console.log(callerId)
			console.log(this.parentInfo?.xm)
			console.log(contact.deviceSn)
			console.log(contact.username)
			console.log(contact.pushToken)
			console.log(miniprogramState)

			try {
				const res = await wmpfVoip.initByCaller({
					roomType,
					caller: {
						id: callerId,
						name: this.parentInfo?.xm || '家长'
					},
					listener: {
						id: contact.deviceSn,
						name: contact.username
					},
					businessType: 2,
					voipToken: contact.pushToken,
					miniprogramState: "formal"
				})
				if (res.isSuccess) {
					uni.hideLoading()
					uni.redirectTo({ url: wmpfVoip.CALL_PAGE_PATH })
					return
				}
				uni.hideLoading()
				console.error('呼叫失败', res)
				uni.showToast({ title: '呼叫失败', icon: 'error' })
			} catch (error) {
				uni.hideLoading()
				console.error('通话异常：', error)
				uni.showToast({ title: '发起通话失败', icon: 'none' })
			}
		},
		setVoipEndPagePath(forceUpdate = false) {
			if (this._voipEndPathSet && !forceUpdate) return
			if (!wmpfVoip) return
			const callInfo = uni.getStorageSync(CALL_END_STORAGE_KEY) || {}
			const options = callInfo.name ?
				`name=${encodeURIComponent(callInfo.name)}&avatar=${encodeURIComponent(callInfo.avatar)}&duration=${callInfo.duration || 0}&type=${callInfo.type || 'voice'}&status=${encodeURIComponent(callInfo.status || '通话已结束')}` : ''
			wmpfVoip.setVoipEndPagePath({
				url: CALL_END_PAGE_URL,
				key: 'Call',
				options,
				routeType: 'redirectTo'
			})
			this._voipEndPathSet = true
		},
		registerVoipEvent() {
			if (this._voipEventRegistered || !wmpfVoip) return
			wmpfVoip.onVoipEvent((event) => {
				const eventName = event.eventName
				const hangupEvent = ['hangUpVoip', 'endVoip']
				const cancelEvent = ['cancelVoip']
				const timeoutEvent = ['timeout']
				const rejectEvent = ['rejectVoip']
				const callInfo = uni.getStorageSync(CALL_END_STORAGE_KEY) || {}

				if (hangupEvent.includes(eventName)) {
					callInfo.duration = event.data?.keepTime || 0
					callInfo.status = event.data?.keepTime > 0 ? '通话已结束' : '未接通'
				} else if (cancelEvent.includes(eventName)) {
					callInfo.duration = 0
					callInfo.status = '已取消'
				} else if (timeoutEvent.includes(eventName)) {
					callInfo.duration = 0
					callInfo.status = '未接听'
				} else if (rejectEvent.includes(eventName)) {
					callInfo.duration = 0
					callInfo.status = '已拒绝'
				}

				if ([...hangupEvent, ...cancelEvent, ...timeoutEvent, ...rejectEvent].includes(eventName)) {
					callInfo.endType = eventName
					callInfo.endTime = Date.now()
					uni.hideLoading()
					uni.setStorageSync(CALL_END_STORAGE_KEY, callInfo)
					this.setVoipEndPagePath(true)
				}
			})
			this._voipEventRegistered = true
		},
		goToMessage(contact) {
			const params = {
				role: 'parent'
			}
			if (contact?.studentId) {
				params.studentId = contact.studentId
			}
			if (contact?.id) {
				params.contactId = contact.id
			}
			const query = Object.keys(params)
				.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
				.join('&')
			uni.navigateTo({
				url: `/pages/parent/message?${query}`
			})
		}
	}
}
</script>

<style scoped>

.call-center {
	min-height: 100vh;
	padding: 32rpx;
	background: #f5f5f5;
	box-sizing: border-box;
}

.contact-list {
	display: flex;
	flex-direction: column;
	gap: 24rpx;
}

.contact-card {
	background: #fff;
	border-radius: 12rpx;
	border: 2rpx solid #e4e7ed;
	padding: 24rpx;
	display: flex;
	justify-content: space-between;
	align-items: center;
	box-shadow: 0 6rpx 12rpx rgba(0, 0, 0, 0.05);
}

.contact-info {
	display: flex;
	align-items: center;
}

.contact-avatar {
	width: 96rpx;
	height: 96rpx;
	border-radius: 8rpx;
	margin-right: 16rpx;
	background: #f0f0f0;
}

.contact-meta {
	display: flex;
	flex-direction: column;
	gap: 8rpx;
}

.contact-name {
	font-size: 30rpx;
	color: #333;
	font-weight: 500;
}

.contact-desc {
	font-size: 26rpx;
	color: #8c8c8c;
}

.empty-tip {
	margin-top: 60rpx;
	text-align: center;
	color: #888;
	font-size: 28rpx;
}

.action-buttons {
	display: flex;
	gap: 18rpx;
}

.action-btn {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6rpx;
}

.action-btn-icon {
	width: 56rpx;
	height: 56rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	background: #ffffff;
	border: 2rpx solid #e0e0e0;
	border-radius: 10rpx;
}

.action-btn-icon image {
	width: 32rpx;
	height: 32rpx;
}

.action-btn text {
	font-size: 24rpx;
	color: #333;
}

.message-point {
	position: relative;
}

.message-point::after {
	content: '';
	position: absolute;
	width: 12rpx;
	height: 12rpx;
	background-color: #eb6100;
	border-radius: 50%;
	top: -4rpx;
	right: -4rpx;
}
</style>
