<template>
	<view class="chat-panel" v-if="show">
		<!-- 头部 -->
		<view class="chat-panel__header">
			<text class="chat-panel__title">消息</text>
			<view class="chat-panel__close" @tap="handleClose">✕</view>
		</view>

		<!-- 消息列表 -->
		<view class="chat-panel__body">
			<scroll-view
				scroll-y
				class="chat-panel__scroll"
				:scroll-into-view="scrollPosition"
				scroll-with-animation
				@scrolltoupper="onScrollToUpper"
			>
				<view class="chat-panel__list">
					<view
						v-for="(item, index) in messageList"
						:key="index"
						:id="'msg-' + item.msgID"
					>
						<!-- 普通消息（文字/图片） -->
						<view
							v-if="item.msgType === '1'"
							class="chat-panel__item"
							:class="{ 'chat-panel__item--right': item.direction === 'right' }"
						>
							<view class="chat-panel__bubble-wrap">
								<!-- 气泡 -->
								<view
									class="chat-panel__bubble"
									:class="item.direction === 'right' ? 'chat-panel__bubble--sent' : 'chat-panel__bubble--received'"
								>
									<!-- 箭头 -->
									<view v-if="item.direction === 'left'" class="chat-panel__arrow chat-panel__arrow--left"></view>
									<view v-else class="chat-panel__arrow chat-panel__arrow--right"></view>

									<!-- 文字消息 -->
									<text v-if="item.consultText" class="chat-panel__bubble-text">{{ item.consultText }}</text>

									<!-- 图片消息 -->
									<image
										v-if="item.picture && !item.pictureLoading"
										class="chat-panel__bubble-image"
										:src="item.picture"
										mode="widthFix"
										@tap="viewOriginal(item)"
									/>
									<view v-if="item.pictureLoading" class="chat-panel__loading">
										<text>发送中...</text>
									</view>
								</view>
							</view>
						</view>

						<!-- 系统消息 -->
						<view v-else class="chat-panel__system">
							<text v-if="item.msgType === '3'">{{ item.sendTime }}</text>
						</view>
					</view>
					<view id="msg-bottom"></view>
				</view>
			</scroll-view>
		</view>

		<!-- 输入区域 -->
		<view class="chat-panel__footer">
			<view class="chat-panel__input-wrap">
				<input
					class="chat-panel__input"
					v-model="messageContent"
					type="text"
					maxlength="200"
					confirm-type="send"
					placeholder="请输入消息"
					placeholder-style="color: #bbb; font-size: 28rpx;"
					@confirm="onSendMessage"
				/>
			</view>
			<i class="iconfont icon-tupian chat-panel__img-btn" @tap="onChooseImage"></i>
			<view class="chat-panel__send-btn" @tap="onSendMessage">发送</view>
		</view>
	</view>
</template>

<script>
	import $http from '@/utils/https';
	import httpConfig from '@/utils/httpConfig';

	// 条件编译引入 TIM SDK
	// #ifdef MP-WEIXIN
	import IMGTXTTIM from 'tim-wx-sdk';
	// #endif
	// #ifdef H5
	import IMGTXTTIM from 'tim-js-sdk';
	// #endif

	const app = getApp();

	export default {
		name: 'ChatPanel',
		props: {
			/** 是否显示面板 */
			show: {
				type: Boolean,
				default: false
			},
			/**
			 * 业务配置对象
			 * @property {string} admID        - 问诊ID
			 * @property {string} frUserID     - 当前用户ID
			 * @property {string} toUserID     - 对方用户ID
			 * @property {string} doctorName   - 医生名称
			 * @property {string} patName      - 患者名称
			 * @property {string} patID        - 患者ID
			 * @property {string} isTextChat   - 是否纯文字模式 'yes'|'no'
			 */
			config: {
				type: Object,
				default: () => ({})
			}
		},
		data() {
			return {
				messageContent: '',
				messageList: [],
				maxMessageListLength: 10,
				moreMsgFlag: 'Y',
				lastMsgID: '',
				scrollPosition: ''
			};
		},
		computed: {
			admID() {
				return this.config.admID || '';
			},
			frUserID() {
				return this.config.frUserID || '';
			},
			toUserID() {
				return this.config.toUserID || '';
			},
			doctorName() {
				return this.config.doctorName || '医生';
			},
			patName() {
				return this.config.patName || '自己';
			}
		},
		watch: {
			show(val) {
				if (val && this.messageList.length === 0) {
					this.getChatData('bottom');
				}
			}
		},
		methods: {
			/**
			 * 关闭面板
			 */
			handleClose() {
				this.$emit('close');
			},

			/**
			 * 获取聊天记录
			 * @param {string} scroll - 滚动方式 'bottom'|'noBottom'
			 */
			getChatData(scroll) {
				const data = {
					params: [{
						admID: this.admID,
						frUser: this.frUserID,
						toUser: this.toUserID,
						lastMsgID: this.lastMsgID
					}]
				};
				$http.post('urlS', this, {
					code: '02090005',
					data,
					namespace: 'Y',
					success: (res) => {
						if (+res.errorCode === 0) {
							const chatData = res.result && res.result.msgData instanceof Array ?
								res.result.msgData : [];
							chatData.forEach((item, i) => {
								item.key = i + 1;
							});
							this.messageList = chatData;
							this.moreMsgFlag = res.result.moreMsgFlag;
							this.$nextTick(() => {
								let pos = '';
								if (scroll === 'bottom' && this.messageList.length > 0) {
									pos = 'msg-' + this.messageList[this.messageList.length - 1]
										.msgID;
								} else if (scroll === 'noBottom' && this.lastMsgID) {
									pos = 'msg-' + this.lastMsgID;
								}
								if (pos) {
									this.scrollPosition = pos;
								}
							});
						} else {
							this.messageList = [];
							this.moreMsgFlag = 'N';
						}
					}
				});
			},

			/**
			 * 发送文字消息（业务接口 + IM通道）
			 */
			handleSendMessage(textVal) {
				const data = {
					params: [{
						admID: this.admID,
						frUser: this.frUserID,
						toUser: this.toUserID,
						consultText: textVal,
						picture: ''
					}]
				};
				$http.post('urlS', this, {
					code: '02090004',
					data,
					namespace: 'Y',
					success: (res) => {
						if (+res.errorCode === 0) {
							const obj = {
								consultText: textVal,
								direction: 'right',
								msgType: '1',
								isWithdraw: true,
								msgID: res.result && res.result.msgID ? res.result.msgID : ''
							};
							this.messageList.push(obj);
							this.messageContent = '';
							this.$nextTick(() => {
								this.scrollPosition = 'msg-' + this.messageList[this
									.messageList.length - 1].msgID;
							});
							this.sendTextViaIM(res, textVal);
							this.$emit('send-success', { ...obj });
						} else {
							uni.showToast({
								title: res.errorMessage || '发送失败',
								icon: 'none'
							});
						}
					}
				});
			},

			/**
			 * 通过 IM SDK 发送文字推送通知
			 */
			sendTextViaIM(res, textVal) {
				if (!app.globalData || !app.globalData.tim) {
					console.log('[ChatPanel] TIM SDK 未初始化，跳过 IM 推送');
					return;
				}
				const messagePayload = {
					userID: this.config.toUser ? this.config.toUser.slice(4) : '',
					admID: this.admID,
					patID: this.config.patID || '',
					patName: this.patName,
					userName: this.doctorName,
					type: 'M',
					text: textVal
				};
				const message = app.globalData.tim.createTextMessage({
					to: this.toUserID,
					conversationType: IMGTXTTIM.TYPES.CONV_C2C,
					payload: {
						text: JSON.stringify(messagePayload)
					}
				});
				app.globalData.tim.sendMessage(message).then(() => {
					console.log('[ChatPanel] IM 文字推送成功');
				}).catch((err) => {
					console.log('[ChatPanel] IM 文字推送失败', err);
				});
			},

			/**
			 * 发送按钮 / 键盘确认 入口
			 */
			onSendMessage() {
				const text = this.messageContent.trim();
				if (!text) {
					uni.showToast({
						title: '发送内容不能为空',
						icon: 'none'
					});
					return;
				}
				// 检查是否离线
				if (app.globalData && app.globalData.isLogOut === false) {
					this.$emit('handleLoginShow');
					return;
				}
				this.handleSendMessage(text);
			},

			/**
			 * 选择图片
			 */
			onChooseImage() {
				uni.chooseImage({
					count: 1,
					sizeType: ['original', 'compressed'],
					sourceType: ['album', 'camera'],
					success: (res) => {
						console.log(res)
						const path = res.tempFilePaths && res.tempFilePaths[0] || '';
						const ext = path.split('.').pop().toLowerCase();
						// 插入 loading 占位
						const idx = this.messageList.length + 1;
						const loadingObj = {
							pictureLoading: true,
							direction: 'right',
							msgType: '1',
							isWithdraw: true,
							msgID: 'loading-' + idx
						};
						this.messageList.push(loadingObj);
						this.$nextTick(() => {
							this.scrollPosition = 'msg-' + loadingObj.msgID;
							this.uploadImage(res);
						});
					}
				});
			},

			/**
			 * 上传图片到服务器
			 */
			uploadImage(fileData) {
				const path = fileData.tempFilePaths && fileData.tempFilePaths[0] || '';
				const ext = path.split('.').pop().toLowerCase();
				// if (!['jpg', 'png', 'jpeg', 'gif'].includes(ext)) {
				// 	this.removeLoading();
				// 	uni.showToast({
				// 		title: '图片格式不支持',
				// 		icon: 'none'
				// 	});
				// 	return;
				// }

				const userData = uni.getStorageSync('userData') || {};
				const uploadUrl = userData.upLoadUrl ||
					(httpConfig.ipDeault + '/uploadFile?fileType=consult');

				uni.uploadFile({
					url: uploadUrl,
					filePath: path,
					name: 'file',
					success: (uploadRes) => {
						if (uploadRes.statusCode === 200) {
							let imgName = '';
							try {
								imgName = JSON.parse(uploadRes.data).filePath;
							} catch (e) {
								this.removeLoading();
								uni.showToast({
									title: '上传解析失败',
									icon: 'none'
								});
								return;
							}
							const data = {
								params: [{
									admID: this.admID,
									frUser: this.frUserID,
									toUser: this.toUserID,
									consultText: '',
									picture: imgName
								}]
							};
							$http.post('urlS', this, {
								code: '02090004',
								data,
								namespace: 'Y',
								success: (res) => {
									if (+res.errorCode === 0) {
										const downLoadUrl = userData.downLoadUrl ||
											(httpConfig.ipDeault +
												'/images/consult/');
										const imgObj = {
											picture: downLoadUrl + imgName,
											direction: 'right',
											msgType: '1',
											isWithdraw: true,
											msgID: res.result && res.result
												.msgID ? res.result.msgID : ''
										};
										this.replaceLoading(imgObj);
										this.sendImageViaIM();
										this.$emit('send-success', { ...imgObj });
									} else {
										this.removeLoading();
										uni.showToast({
											title: '发送失败',
											icon: 'none'
										});
									}
								},
								error: () => {
									this.removeLoading();
									uni.showToast({
										title: '网络异常，请稍后再试',
										icon: 'none'
									});
								}
							});
						} else {
							this.removeLoading();
							uni.showToast({
								title: '上传失败',
								icon: 'none'
							});
						}
					},
					fail: () => {
						this.removeLoading();
						uni.showToast({
							title: '网络异常，请稍后再试',
							icon: 'none'
						});
					}
				});
			},

			/**
			 * 替换 loading 占位为实际图片消息
			 */
			replaceLoading(imgObj) {
				let lastIdx = -1;
				for (let i = this.messageList.length - 1; i >= 0; i--) {
					if (this.messageList[i].pictureLoading) {
						lastIdx = i;
						break;
					}
				}
				if (lastIdx >= 0) {
					this.$set(this.messageList, lastIdx, imgObj);
					this.$nextTick(() => {
						this.scrollPosition = 'msg-' + imgObj.msgID;
					});
				}
			},

			/**
			 * 删除 loading 占位（发送失败时）
			 */
			removeLoading() {
				let lastIdx = -1;
				for (let i = this.messageList.length - 1; i >= 0; i--) {
					if (this.messageList[i].pictureLoading) {
						lastIdx = i;
						break;
					}
				}
				if (lastIdx >= 0) {
					this.messageList.splice(lastIdx, 1);
					if (this.messageList.length > 0) {
						this.$nextTick(() => {
							this.scrollPosition = 'msg-' + this.messageList[this
								.messageList.length - 1].msgID;
						});
					}
				}
			},

			/**
			 * 通过 IM 发送图片推送通知
			 */
			sendImageViaIM() {
				if (!app.globalData || !app.globalData.tim) {
					console.log('[ChatPanel] TIM SDK 未初始化，跳过 IM 图片推送');
					return;
				}
				const messagePayload = {
					userID: this.config.toUserID ? this.config.toUserID.slice(4) : '',
					admID: this.admID,
					patID: this.config.userID || this.config.patID || '',
					patName: this.patName,
					userName: this.config.toUserName || this.doctorName,
					type: 'M',
					text: '',
					image: 'Y'
				};
				const message = app.globalData.tim.createTextMessage({
					to: this.toUserID,
					conversationType: IMGTXTTIM.TYPES.CONV_C2C,
					payload: {
						text: JSON.stringify(messagePayload)
					}
				});
				const promise = app.globalData.tim.sendMessage(message);
				if (promise) {
					promise.then(() => {
						console.log('[ChatPanel] IM 图片推送成功');
					}).catch((err) => {
						console.log('[ChatPanel] IM 图片推送失败', err);
					});
				}
			},

			/**
			 * 图片预览（查看原图）
			 */
			viewOriginal(item) {
				const urls = this.messageList
					.filter(m => m.picture && !m.pictureLoading && m.msgType === '1')
					.map(m => m.picture);
				uni.previewImage({
					current: item.picture,
					urls
				});
			},

			/**
			 * 滚动到顶部 → 加载更多历史消息
			 */
			onScrollToUpper() {
				if (this.moreMsgFlag === 'N') {
					if (this.messageList.length > 0 &&
						this.messageList[0].sendTime !== '没有更多消息记录了。') {
						this.messageList.unshift({
							direction: 'right',
							msgType: '3',
							sendTime: '没有更多消息记录了。'
						});
					}
					return;
				}
				this.lastMsgID = this.messageList.length > 0 ? this.messageList[0].msgID : '';
				this.getChatData('noBottom');
			}
		}
	};
</script>

<style lang="scss" scoped>
	.chat-panel {
		position: absolute;
		z-index: 100;
		display: flex;
		flex-direction: column;
		width: 90vw;
		height: 40vh;
		top: 50vh;
		left: 50vw;
		transform: translate(-50%, -50%);
		padding: 20rpx 0;
		border-radius: 10rpx;
		font-size: 28rpx;
		color: #333;
		background-color: #fff;
		box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.15);
	}

	/* 头部 */
	.chat-panel__header {
		display: flex;
		justify-content: center;
		align-items: center;
		position: relative;
		padding-bottom: 16rpx;
		border-bottom: 1px solid rgba(0, 0, 0, 0.08);
	}

	.chat-panel__title {
		font-size: 32rpx;
		font-weight: 500;
	}

	.chat-panel__close {
		position: absolute;
		top: -8rpx;
		right: 16rpx;
		width: 48rpx;
		height: 48rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 28rpx;
		color: rgba(0, 0, 0, 0.4);
	}

	/* 消息列表 */
	.chat-panel__body {
		flex: 1;
		overflow: hidden;
	}

	.chat-panel__scroll {
		height: 100%;
	}

	.chat-panel__list {
		box-sizing: border-box;
		padding: 16rpx 24rpx;
	}

	/* 单条消息 */
	.chat-panel__item {
		display: flex;
		flex-direction: row;
		padding-bottom: 16rpx;
	}

	.chat-panel__item--right {
		flex-direction: row-reverse;
	}

	/* 气泡包裹层 */
	.chat-panel__bubble-wrap {
		position: relative;
		max-width: 80%;
		margin: 0 8rpx;
		display: flex;
		flex-direction: column;
	}

	/* 气泡主体 */
	.chat-panel__bubble {
		position: relative;
		padding: 16rpx 20rpx;
		border-radius: 8rpx;
		word-break: break-all;
	}

	/* 发送气泡 - 蓝色（参考 bubble-sent） */
	.chat-panel__bubble--sent {
		background-color: #5cadff;
		color: #fff;
	}

	/* 接收气泡 - 白色（参考 bubble-received） */
	.chat-panel__bubble--received {
		background-color: #f5f5f5;
		color: #333;
		box-shadow: 0 1rpx 4rpx rgba(0, 0, 0, 0.06);
	}

	/* 气泡文字 */
	.chat-panel__bubble-text {
		font-size: 28rpx;
		line-height: 1.6;
		white-space: pre-wrap;
	}

	/* 气泡箭头 - 发送方（右侧三角） */
	.chat-panel__arrow {
		position: absolute;
		top: 14rpx;
		width: 0;
		height: 0;
		border-width: 8rpx 12rpx;
		border-style: solid;
	}
	.chat-panel__arrow--right {
		right: -10rpx;
		border-color: transparent transparent transparent #5cadff;
		border-width: 8rpx 0 8rpx 12rpx;
	}
	.chat-panel__arrow--left {
		left: -10rpx;
		border-color: transparent #f5f5f5 transparent transparent;
		border-width: 8rpx 12rpx 8rpx 0;
	}

	/* 气泡图片 */
	.chat-panel__bubble-image {
		min-width: 200rpx;
		max-width: 300rpx;
		max-height: 400rpx;
		border-radius: 6rpx;
	}

	/* 发送中 */
	.chat-panel__loading {
		padding: 8rpx 0;
		color: rgba(0, 0, 0, 0.35);
		font-size: 24rpx;
	}

	/* 系统消息 */
	.chat-panel__system {
		width: 100%;
		text-align: center;
		padding: 8rpx 0;

		text {
			display: inline-block;
			padding: 4rpx 24rpx;
			border-radius: 24rpx;
			background-color: rgba(0, 0, 0, 0.06);
			color: #999;
			font-size: 22rpx;
		}
	}

	/* 底部输入区 */
	.chat-panel__footer {
		width: 100%;
		box-sizing: border-box;
		padding: 16rpx 20rpx;
		display: flex;
		flex-direction: row;
		align-items: center;
		background-color: #f2f2f2;
		border-top: 1px solid rgba(0, 0, 0, 0.06);
	}

	.chat-panel__input-wrap {
		flex: 1;
		margin-right: 12rpx;
		height: 64rpx;
	}

	.chat-panel__input {
		font-size: 28rpx;
		padding: 0 20rpx;
		border-radius: 32rpx;
		height: 100%;
		background-color: #fff;
		color: #333;
		border: none;
	}

	.chat-panel__img-btn {
		font-size: 44rpx;
		padding: 0 12rpx;
		flex-shrink: 0;
	}

	.chat-panel__send-btn {
		display: inline-block;
		height: 64rpx;
		line-height: 64rpx;
		width: 110rpx;
		text-align: center;
		font-size: 28rpx;
		color: #fff;
		background-color: #5cadff;
		border-radius: 32rpx;
		flex-shrink: 0;
		margin-left: 8rpx;

		&:active {
			background-color: #4a9ae8;
		}
	}
</style>
