<template>
  <!-- 根容器 -->
  <view class="chat-container">

    <!-- ================= 顶部导航栏 (保持原样) ================= -->
    <view class="chat-header">
      <view class="header-main" @click="toggleDoctorDetail">
        <view class="doctor-info-group">
          <text class="doctor-name">{{ doctorUserInfo.nick_name }}</text>
          <view class="doctor-badges">
            <text class="status-dot"></text>
            <text class="sub-text">在线</text>
          </view>
        </view>
        <view class="header-action">
          <text class="expand-tip">{{ showDoctorDetail ? '收起' : '详情' }}</text>
          <u-icon :name="showDoctorDetail ? 'arrow-up' : 'arrow-down'" size="12" color="#0A84FF"></u-icon>
        </view>
      </view>

      <view class="doctor-detail-panel" :class="{ 'panel-show': showDoctorDetail }">
        <view class="detail-grid">
          <view class="detail-row">
            <text class="label">职称</text>
            <text class="value tag-value">{{ doctorDetailInfo.title || '--' }}</text>
          </view>
          <view class="detail-row">
            <text class="label">医院</text>
            <text class="value">{{ doctorDetailInfo.hospital || '--' }}</text>
          </view>
          <view class="detail-row full-width">
            <text class="label">擅长</text>
            <text class="value desc-value">{{ doctorDetailInfo.good_at || '--' }}</text>
          </view>
        </view>
      </view>
    </view>

    <!-- ================= 聊天消息滚动区域 ================= -->
    <scroll-view
        class="chat-messages"
        :style="scrollViewStyle"
        scroll-y="true"
        :scroll-into-view="scrollIntoView"
        :scroll-top="scrollTop"
        scroll-with-animation
        @scrolltoupper="loadHistory"
        @scroll="onScroll"
    >
      <view class="message-list-container" id="msglist" :style="{ paddingBottom: (keyboardHeight > 0 ? keyboardHeight + 10 : 0) + 'px' }">

        <!-- 加载指示器 -->
        <view v-if="loading" class="loading-spinner">
          <view class="spinner"></view>
          <text class="spinner-text">历史记录加载中...</text>
        </view>

        <!-- 无更多消息 -->
        <view v-if="isEmpty" class="empty-state">
          <text class="empty-text">没有更多消息了</text>
        </view>

        <!-- 消息列表循环 -->
        <view v-for="(msg, index) in messages" :key="index" class="message-wrapper">

          <!-- 时间 -->
          <view class="time-divider" v-if="shouldShowTime(msg, index)">
            <text class="time-text">{{ msg.created_at_text || msg.time }}</text>
          </view>

          <!-- 使用抽离的组件 -->
          <MessageBubble
              :msg="msg"
              :is-mine="isMsgMine(msg)"
              :avatar="getMsgAvatar(msg)"
              :is-playing="isPlaying(msg)"
              @previewImage="previewImage"
              @playAudio="playAudio"
              @viewRegister="viewRegister"
              @viewPrescription="viewPrescription"
              @goToOrderMedicine="goToOrderMedicine"
              @viewOrder="viewOrder"
          />

        </view>

        <!-- 底部锚点 -->
        <view id="chat-bottom-anchor" style="height: 1px; width: 100%;"></view>
      </view>

      <!-- 底部静态占位 -->
      <view style="height: 180rpx;"></view>
    </scroll-view>

    <!-- ================= 底部输入与工具栏 (重构优化版) ================= -->
    <view class="chat-footer safe-area-inset-bottom" :style="{ bottom: keyboardHeight + 'px' }">
      <view v-if="isConsultationEnded" class="consultation-ended-notice">
        <u-icon name="checkmark-circle-fill" size="18" color="#999"></u-icon>
        <text>本次问诊已结束</text>
      </view>

      <template v-else>
        <!-- 相册工具栏 -->
        <view class="toolbar-area" v-if="false">
          <!-- 暂时隐藏 -->
        </view>

        <view class="input-bar">
          <!-- 左侧：语音切换按钮 -->
          <view class="icon-btn left" @click="toggleVoiceInput">
            <u-icon :name="voiceInputActive ? 'close' : 'mic'" size="26" color="#333"></u-icon>
          </view>

          <!-- 中间：输入框 / 按住说话 -->
          <view class="input-field-wrapper">
            <input
                v-if="!voiceInputActive"
                v-model="newMessage"
                class="main-input"
                :adjust-position="false"
                confirm-type="send"
                @confirm="sendTextMessage"
                cursor-spacing="20"
            />
            <view v-else class="voice-btn"
                  :class="{ 'recording': recording }"
                  @touchstart="startVoiceRecording"
                  @touchend="stopVoiceRecording"
                  @touchcancel="stopVoiceRecording">
              <text>{{ recording ? '松开 发送' : '按住 说话' }}</text>
            </view>
          </view>

          <!-- 右侧：发送按钮 或 加号 -->
          <view class="right-action">
            <view v-if="newMessage.trim()" class="send-btn" @click="sendTextMessage">发送</view>
            <view v-else class="icon-btn" @click="openMediaPicker('image')">
              <u-icon name="plus-circle" size="26" color="#333"></u-icon>
            </view>
          </view>
        </view>
      </template>
    </view>

    <!-- 录音蒙层 (保持原样) -->
    <view v-if="showRecordingModal" class="recording-overlay">
      <view class="recording-box">
        <view class="wave-animation"></view>
        <view style="margin: 20rpx 0;">
          <u-icon name="mic-fill" size="40" color="#fff"></u-icon>
        </view>
        <text class="timer">正在录音 {{ recordingTime }}s</text>
        <text class="tip">手指上滑取消</text>
      </view>
    </view>
  </view>
</template>

<script>
import MessageBubble from './components/MessageBubble.vue'; // 引入组件
import { webSocketManager } from '@/utils/ws/websocket';
import { ChatManager } from '@/store/chat/chat.js';
import {getChatRegisterInfoApi, sendToUserApi, upLoadChatFileApi, getDoctorInfoApi, getRoomStatusApi} from "@/request/api/im";
import { checkDev } from '@/utils/utils';

// 根据环境获取上传URL
const isDev = checkDev('dev');
const uploadBaseUrl = isDev ? 'http://127.0.0.1:18001/api/mobile' : 'https://api.xiaokang88.com/api/mobile';

// 辅助函数保留在父组件逻辑中
function getParsedContent(messageType, messageContent) {
  if ([4, 9, 10, 11, 12, 13].includes(messageType)) {
    try {
      return typeof messageContent === 'object' ? messageContent : JSON.parse(messageContent);
    } catch (e) {
      return messageContent;
    }
  }
  return messageContent;
}

export default {
  components: {
    MessageBubble
  },
  data() {
    return {
      doctorUserInfo: { id: 0, avatar: '', nick_name: '医生', room_id: '' },
      doctorDetailInfo: { title: '', hospital: '', good_at: '' }, // 医生详情信息
      showDoctorDetail: false,
      currentUserId: '',
      doctorId: 'doctor-1',
      doctorAvatar: 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk_upload_20250108/29bdb9560340373bb3096394a845afa5.jpg',
      userAvatar: 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk_upload_20250108/29bdb9560340373bb3096394a845afa5.jpg',
      messages: [],
      newMessage: '',
      voiceInputActive: false, // 默认文字输入
      recording: false,
      recordingTime: 0,
      recordingTimer: null,
      showRecordingModal: false,
      currentPlayingAudio: null,
      innerAudioContext: null, // 音频播放上下文
      hasRecordPermission: false,
      scrollTop: 0,
      scrollIntoView: '',
      scrollViewHeight: 0,
      oldScrollViewHeight: 0,
      scrollViewStyle: '',
      currentScrollPosition: 0,
      page: 1,
      pageSize: 20,
      hasMore: true,
      loading: false,
      isEmpty: false,
      isLoadHistory: false,
      isConsultationEnded: false,
      keyboardHeight: 0,
    };
  },

  onLoad: function (option) {
    this.doctorUserInfo = option;
    if (option.avatar) this.doctorAvatar = option.avatar;
    this.currentUserId = 'user-' + uni.getStorageSync('user_id') || 'user-2512';

    let doctorId = option.user_id || '';
    if (doctorId.includes('-type-')) doctorId = doctorId.split('-type-')[0];
    this.doctorId = doctorId;

    if (typeof ChatManager !== 'undefined') {
      ChatManager.enterRoom(option.room_id);
      ChatManager.resetUnreadCount(option.room_id);
      this.messages = ChatManager.getRoomMessages(option.room_id);
      if (option.room_status === '1' || option.room_status === 1) this.isConsultationEnded = true;
      else if (this.messages.some(msg => msg.message_type === 13)) this.isConsultationEnded = true;
    }

    if (option.room_id) this.fetchRoomStatus(option.room_id);

    // 无论是否有nickName，都需要获取医生详情信息（职称、医院、擅长）
    this.fetchDoctorInfo(doctorId);
    
    const nickName = this.doctorUserInfo.nick_name;
    if (nickName && nickName !== 'undefined' && nickName !== 'null') {
      uni.setNavigationBarTitle({ title: `与${nickName}医生的对话` });
    }

    this.$nextTick(() => {
      this.scrollToBottom();
    });

    uni.onKeyboardHeightChange(res => {
      this.keyboardHeight = res.height;
      if (res.height > 0) this.scrollToBottom();
    });
  },

  onUnload() {
    if (this.innerAudioContext) {
      this.innerAudioContext.destroy();
    }
    if (typeof ChatManager !== 'undefined') ChatManager.leaveRoom();
  },

  onShow() {
    uni.$on('new-room-message', this.handleNewRoomMessage);
    uni.$on('load-room-message', this.handLoadMessageList);
    uni.$on('no-more-history', this.handNoMessageList);
  },

  onHide() {
    this.stopAudio(); // 页面隐藏时停止播放
    uni.$off('new-room-message', this.handleNewRoomMessage);
    uni.$off('load-room-message', this.handLoadMessageList);
    uni.$off('no-more-history', this.handNoMessageList);
  },

  mounted() {
    this.recorderManager = uni.getRecorderManager();
    this.initRecorder();
    if (typeof webSocketManager !== 'undefined') webSocketManager.addMessageHandler(this.handleSocketMessage);
    this.calculateScrollViewHeight();
  },

  beforeDestroy() {
    if (typeof webSocketManager !== 'undefined') webSocketManager.removeMessageHandler(this.handleSocketMessage);
  },

  methods: {
    // === 新增辅助方法 ===
    isMsgMine(msg) {
      return this.getSenderIdWithoutPrefix(msg.sender_user_id) === this.getCurrentUserIdWithoutPrefix();
    },

    getMsgAvatar(msg) {
      if (this.isMsgMine(msg)) {
        return this.userAvatar;
      }
      let avatar = this.doctorUserInfo.avatar || this.doctorAvatar || 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk_upload_20250108/29bdb9560340373bb3096394a845afa5.jpg';
      try {
        return decodeURIComponent(avatar);
      } catch (e) {
        return avatar;
      }
    },

    // === 音频播放逻辑 ===
    playAudio(msg) {
      const audioUrl = getParsedContent(msg.message_type, msg.message_content);

      // 如果点击的是当前正在播放的，则暂停/停止
      if (this.currentPlayingAudio === msg.id) {
        this.stopAudio();
        return;
      }

      // 停止当前正在播放的
      this.stopAudio();

      if (!audioUrl) {
        uni.showToast({ title: '无效的音频地址', icon: 'none' });
        return;
      }

      // 初始化音频上下文
      if (!this.innerAudioContext) {
        this.innerAudioContext = uni.createInnerAudioContext();

        // 监听自然播放结束
        this.innerAudioContext.onEnded(() => {
          this.currentPlayingAudio = null;
        });

        // 监听播放错误
        this.innerAudioContext.onError((res) => {
          console.error('音频播放错误', res);
          this.currentPlayingAudio = null;
          uni.showToast({ title: '播放失败', icon: 'none' });
        });
      }

      this.innerAudioContext.src = audioUrl;
      this.innerAudioContext.play();
      this.currentPlayingAudio = msg.id;
    },

    stopAudio() {
      if (this.innerAudioContext) {
        this.innerAudioContext.stop();
      }
      this.currentPlayingAudio = null;
    },

    isPlaying(msg) {
      return this.currentPlayingAudio === msg.id;
    },

    // ... 所有的业务逻辑方法保持原样，无需改动 ...
    async fetchDoctorInfo(doctorId) {
      try {
        const cleanDoctorId = String(doctorId).replace('doctor-', '');
        const res = await getDoctorInfoApi({ doctor_id: cleanDoctorId });
        if (res.data && res.data.result) {
          const doctorInfo = res.data.result;
          this.doctorUserInfo = {
            ...this.doctorUserInfo,
            nick_name: doctorInfo.nick_name || '医生',
            avatar: doctorInfo.avatar || this.doctorAvatar,
          };
          // 保存完整的医生详情信息
          this.doctorDetailInfo = {
            title: doctorInfo.title || '',
            hospital: doctorInfo.hospital || '',
            good_at: doctorInfo.good_at || ''
          };
          if (doctorInfo.avatar) this.doctorAvatar = doctorInfo.avatar;
          uni.setNavigationBarTitle({ title: `与${this.doctorUserInfo.nick_name}医生的对话` });
        }
      } catch (error) { console.error('获取医生信息失败:', error); }
    },

    async fetchRoomStatus(roomId) {
      try {
        const res = await getRoomStatusApi({ room_id: roomId });
        if (res.data && res.data.result) this.isConsultationEnded = res.data.result.status === 1;
      } catch (error) { console.error('获取房间状态失败:', error); }
    },

    checkPrivacyAuthorize() {
      return new Promise((resolve, reject) => {
        // #ifdef MP-WEIXIN
        if (typeof uni.requirePrivacyAuthorize === 'function') {
          uni.requirePrivacyAuthorize({
            success: () => resolve(),
            fail: () => {
              uni.showToast({ title: '需要同意隐私协议才能使用此功能', icon: 'none' });
              reject(new Error('隐私授权被拒绝'));
            }
          });
        } else { resolve(); }
        // #endif
        // #ifndef MP-WEIXIN
        resolve();
        // #endif
      });
    },

    calculateScrollViewHeight() {
      this.$nextTick(() => {
        const systemInfo = uni.getSystemInfoSync();
        const windowHeight = systemInfo.windowHeight;
        const query = uni.createSelectorQuery().in(this);
        query.select('.chat-header').boundingClientRect((headerRect) => {
          const headerHeight = headerRect ? headerRect.height : 0;
          const query2 = uni.createSelectorQuery().in(this);
          query2.select('.chat-footer').boundingClientRect((footerRect) => {
            const footerHeight = footerRect ? footerRect.height : 0;
            const scrollHeight = windowHeight - headerHeight - footerHeight;
            this.scrollViewStyle = `height: ${scrollHeight}px;`;
          }).exec();
        }).exec();
      });
    },

    onScroll(e) { this.currentScrollPosition = e.detail.scrollTop; },
    getSenderIdWithoutPrefix(senderId) { return !senderId ? '' : String(senderId).replace(/^(user-|doctor-)/, ''); },
    getCurrentUserIdWithoutPrefix() { return !this.currentUserId ? '' : String(this.currentUserId).replace(/^(user-|doctor-)/, ''); },

    shouldShowTime(msg, index) {
      if (index === 0) return true;
      const prevMsg = this.messages[index - 1];
      const currTime = msg.created_at || msg.timestamp || 0;
      const prevTime = prevMsg.created_at || prevMsg.timestamp || 0;
      return currTime - prevTime > 300000;
    },

    loadRegisterCards() {
      let that = this;
      this.messages.forEach((msg, index) => {
        if (msg.message_type === 10) {
          const parsedContent = getParsedContent(msg.message_type, msg.message_content);
          if (parsedContent._loaded || !parsedContent.id) return;
          that.fetchRegisterCardInfo(msg, index, parsedContent.id);
        }
      });
    },

    fetchRegisterCardInfo(msg, index, registerId) {
      let that = this;
      const messageId = msg.id;
      getChatRegisterInfoApi({ id: registerId, message_id: messageId || '' }).then((res) => {
        if (res.data && res.data.result) {
          let targetIndex = index;
          if (messageId) {
            const foundIndex = that.messages.findIndex(m => m.id === messageId || String(m.id) === String(messageId));
            if (foundIndex !== -1) targetIndex = foundIndex;
          }
          const resultWithFlag = { ...res.data.result, _loaded: true };
          that.$set(that.messages, targetIndex, {
            ...that.messages[targetIndex],
            message_content: JSON.stringify(resultWithFlag)
          });
        }
      });
    },

    handNoMessageList() { this.isEmpty = true; this.hasMore = false; },
    handLoadMessageList(type = 0) {
      this.loading = false;
      if (typeof ChatManager !== 'undefined') this.messages = ChatManager.roomMessages[this.doctorUserInfo.room_id] || [];
      this.loadRegisterCards();
      const isHistoryLoad = this.isLoadHistory;
      this.isLoadHistory = false;
      if (type === 1 && !isHistoryLoad) this.scrollToBottom();
      else this.scrollToOldLastMessage();
    },

    getScrollHeight() {
      const query = uni.createSelectorQuery().in(this);
      query.select('.message-list-container').boundingClientRect(res => {
        if (res) {
          this.oldScrollViewHeight = res.height;
          this.scrollViewHeight = res.height;
        }
      }).exec();
    },

    handleSocketMessage(data) {
      if (data.room_id === this.doctorUserInfo.room_id) {
        this.addMessage(data);
        this.scrollToBottom();
      }
    },

    handleNewRoomMessage(message) {
      this.addMessage(message);
      this.scrollToBottom();
    },

    addMessage(message) {
      if (!message.message_content && message.content) message.message_content = message.content;
      if (message.message_type === undefined && message.type !== undefined) {
        const messageTypeMap = { text: 0, image: 1, audio: 2, video: 3, prescription: 4, file: 5, register: 10, 'patient-experience': 11, 'product-card': 12, 'end-consultation': 13 };
        message.message_type = messageTypeMap[message.type] || 0;
      }
      const existingIndexById = this.messages.findIndex(m => m.id === message.id);
      if (existingIndexById !== -1) {
        this.messages[existingIndexById] = message;
        return;
      }
      const normalizeContent = (content) => {
        if (!content) return '';
        if (typeof content === 'string') {
          try { return JSON.stringify(JSON.parse(content)); } catch (e) { return content; }
        } else if (typeof content === 'object') { return JSON.stringify(content); }
        return String(content);
      };
      if (!message.isTemporary) {
        const tempMessageIndex = this.messages.findIndex(m => {
          if (!m.isTemporary) return false;
          if ((m.sender_user_id || '') !== (message.sender_user_id || '')) return false;
          if (normalizeContent(m.message_content || m.content || '') !== normalizeContent(message.message_content || message.content || '')) return false;
          return Math.abs((m.created_at || m.timestamp || 0) - (message.created_at || message.timestamp || 0)) < 30000;
        });
        if (tempMessageIndex !== -1) {
          this.messages[tempMessageIndex] = message;
          return;
        }
      }
      this.messages.push(message);
      if (message.message_type === 10) {
        const parsedContent = getParsedContent(message.message_type, message.message_content);
        if (!parsedContent._loaded && parsedContent.id) this.fetchRegisterCardInfo(message, this.messages.length - 1, parsedContent.id);
      }
      if (message.message_type === 13) this.isConsultationEnded = true;
      if (this.doctorUserInfo.room_id) this.fetchRoomStatus(this.doctorUserInfo.room_id);
    },

    toggleDoctorDetail() { this.showDoctorDetail = !this.showDoctorDetail; },

    initRecorder() {
      this.recorderManager.onStop(res => {
        if (res.duration < 1000) {
          uni.showToast({ title: '录音时间太短', icon: 'none' });
          this.recording = false;
          this.showRecordingModal = false;
          clearInterval(this.recordingTimer);
          return;
        }
        this.uploadAudioFile(res.tempFilePath, Math.floor(res.duration / 1000));
        this.recording = false;
        this.showRecordingModal = false;
        clearInterval(this.recordingTimer);
      });
      this.recorderManager.onError((error) => {
        console.error('录音错误:', error);
        this.recording = false;
        this.showRecordingModal = false;
        clearInterval(this.recordingTimer);
      });
    },

    async uploadAudioFile(tempFilePath, duration) {
      uni.showLoading({ title: '上传中...', mask: true });
      try {
        uni.uploadFile({
          url: `${uploadBaseUrl}/chat-friends/upload-chat-file`,
          filePath: tempFilePath,
          name: 'file',
          header: { "authorization": uni.getStorageSync('token') },
          formData: {},
          success: (uploadFileRes) => {
            this.sendMessage({
              type: 'audio',
              content: JSON.parse(uploadFileRes.data).result.url,
              duration,
            });
          }
        });
      } catch (error) { console.error('音频上传失败:', error); } finally { uni.hideLoading(); }
    },

    sendMessage(message) {
      const now = new Date();
      const timeStr = this.formatTime(now);
      let receiverUserId = this.doctorId || '';
      if (receiverUserId.includes('-type-')) receiverUserId = receiverUserId.split('-type-')[0];
      if (receiverUserId && !receiverUserId.startsWith('doctor-')) receiverUserId = 'doctor-' + receiverUserId;
      const messageTypeMap = { text: 0, image: 1, audio: 2, video: 3, prescription: 4, file: 5, register: 10, 'patient-experience': 11, 'product-card': 12, 'end-consultation': 13 };
      const messageType = messageTypeMap[message.type] || 0;
      const fullMessage = {
        ...message,
        id: Date.now().toString(),
        sender_user_id: this.currentUserId,
        receiver_user_id: receiverUserId,
        room_id: this.doctorUserInfo.room_id,
        created_at_text: timeStr,
        created_at: now.getTime(),
        timestamp: now.getTime(),
        message_content: message.message_content || message.content || '',
        message_type: messageType,
        isTemporary: true
      };
      this.addMessage(fullMessage);
      this.scrollToBottom();
      let senderUserId = `user-${this.currentUserId}`;
      if (senderUserId.startsWith('user-user-')) {
        senderUserId = senderUserId.replace(/^user-user-/, 'user-');
      }
      const requestData = {
        room_id: this.doctorUserInfo.room_id,
        sender_user_id: senderUserId,
        receiver_user_id: receiverUserId,
        message_type: messageType,
        message_content: message.message_content || message.content || '',
        isFromHttp: true,
        duration: message.duration || 0
      };
      if (typeof sendToUserApi !== 'undefined') sendToUserApi(requestData);
    },

    formatTime(date) {
      const hours = date.getHours().toString().padStart(2, '0');
      const minutes = date.getMinutes().toString().padStart(2, '0');
      return `${hours}:${minutes}`;
    },

    sendTextMessage() {
      if (!this.newMessage.trim()) return;
      this.sendMessage({ type: 'text', content: this.newMessage });
      this.newMessage = '';
    },

    async startVoiceRecording() {
      if (this.recording) return;
      try { await this.checkPrivacyAuthorize(); } catch (e) { return; }
      uni.getSetting({
        success: (res) => {
          if (res.authSetting['scope.record']) {
            this.hasRecordPermission = true;
            this.startRecording();
          } else {
            uni.authorize({
              scope: 'scope.record',
              success: () => {
                this.hasRecordPermission = true;
                this.startRecording();
              },
              fail: () => {
                this.hasRecordPermission = false;
                this.voiceInputActive = false;
              }
            });
          }
        }
      });
    },

    startRecording() {
      this.recording = true;
      this.showRecordingModal = true;
      this.recordingTime = 0;
      this.recorderManager.start({ format: 'mp3', sampleRate: 44100, numberOfChannels: 1, encodeBitRate: 192000 });
      this.recordingTimer = setInterval(() => {
        this.recordingTime++;
        if (this.recordingTime >= 60) this.stopVoiceRecording();
      }, 1000);
    },

    stopVoiceRecording() {
      if (!this.recording) return;
      this.recorderManager.stop();
    },

    async openMediaPicker(type) {
      try { await this.checkPrivacyAuthorize(); } catch (e) { return; }
      if (type === 'image') {
        uni.chooseImage({
          count: 9, sourceType: ['album', 'camera'],
          success: res => { res.tempFilePaths.forEach(file => { this.uploadAndSendFile(file, 'image'); }); }
        });
      }
    },

    uploadAndSendFile(filePath, type) {
      uni.showLoading({ title: '上传中...', mask: true });
      uni.uploadFile({
        url: `${uploadBaseUrl}/chat-friends/upload-chat-file`,
        filePath: filePath,
        name: 'file',
        header: { "authorization": uni.getStorageSync('token') },
        formData: {},
        success: (uploadFileRes) => {
          uni.hideLoading();
          try {
            const result = JSON.parse(uploadFileRes.data);
            if (result.code === 0 && result.result && result.result.url) {
              this.sendMessage({ type: type, content: result.result.url });
            } else { uni.showToast({ title: '上传失败', icon: 'none' }); }
          } catch (e) { uni.showToast({ title: '上传失败', icon: 'none' }); }
        },
        fail: () => { uni.hideLoading(); uni.showToast({ title: '上传失败', icon: 'none' }); }
      });
    },

    previewImage(url) { uni.previewImage({ urls: [url], current: url }); },

    async toggleVoiceInput() {
      if (!this.voiceInputActive) {
        try { await this.checkPrivacyAuthorize(); } catch (e) { return; }
        uni.getSetting({
          success: (res) => {
            if (res.authSetting['scope.record']) {
              this.hasRecordPermission = true;
              this.voiceInputActive = true;
            } else {
              uni.authorize({
                scope: 'scope.record',
                success: () => {
                  this.hasRecordPermission = true;
                  this.voiceInputActive = true;
                },
                fail: () => {
                  uni.showModal({
                    title: '录音权限', content: '需要录音权限才能使用语音输入',
                    showCancel: true, confirmText: '去设置',
                    success: (res) => { if (res.confirm) uni.openSetting(); }
                  });
                }
              });
            }
          }
        });
      } else { this.voiceInputActive = false; }
    },

    scrollToBottom() {
      this.scrollIntoView = '';
      this.$nextTick(() => { setTimeout(() => { this.scrollIntoView = 'chat-bottom-anchor'; setTimeout(() => { if (this.scrollIntoView !== 'chat-bottom-anchor') this.scrollIntoView = 'chat-bottom-anchor'; }, 100); }, 300); });
    },

    scrollToOldLastMessage() {
      this.scrollIntoView = '';
      this.$nextTick(() => {
        const query = uni.createSelectorQuery().in(this);
        query.select('.message-list-container').boundingClientRect((rect) => {
          if (rect) {
            const heightDiff = rect.height - this.oldScrollViewHeight;
            if (heightDiff > 0) {
              this.scrollTop = heightDiff;
              this.oldScrollViewHeight = rect.height;
            }
          }
        }).exec();
      });
    },

    async loadHistory() {
      if (!this.hasMore || this.loading) return;
      this.getScrollHeight();
      this.isLoadHistory = true;
      this.loading = true;
      if (typeof ChatManager !== 'undefined') ChatManager.loadHistory(this.doctorUserInfo.room_id);
      setTimeout(() => {
        this.loading = false;
      }, 3000);
    },

    getStatusText(status) { const map = { 0: '待审核', 1: '已审核', 2: '未通过' }; return map[status] || '未知状态'; },
    getRegisterStatusText(status) { const map = { 0: '待就诊', 1: '已缴费', 2: '已就诊', 3: '已取消', 4: '已退费' }; return map[status] || '未知状态'; },
    viewPrescription(id, orderNo) { uni.navigateTo({ url: "/subPackages/my/myrecord-detail?id=" + id + '&no=' + orderNo }); },
    goToOrderMedicine(id, orderNo) { uni.navigateTo({ url: "/subPackages/my/my-drug/drug-info?id=" + id + '&order_type=prescription' }); },
    viewRegister(id, orderNo) { uni.navigateTo({ url: "/subPackages/register/register-detail?id=" + id + '&no=' + orderNo }); },
    viewOrder(orderId, orderNo) { uni.navigateTo({ url: "/subPackages/my/my-drug/drug-info?id=" + orderId }); }
  }
};
</script>

<style lang="scss" scoped>
// ================= 变量定义 =================
$primary-blue: #0A84FF;
$bg-page: #F4F6F9;
$bg-white: #ffffff;

// ================= 基础容器 =================
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: $bg-page;
}

// ================= 顶部导航栏 =================
.chat-header {
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  z-index: 100;
  position: relative;
  box-shadow: 0 1rpx 2rpx rgba(0,0,0,0.05);

  .header-main {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 24rpx 32rpx;

    .doctor-info-group {
      display: flex;
      flex-direction: column;

      .doctor-name { font-size: 34rpx; font-weight: 600; color: #333; margin-bottom: 4rpx; }
      .doctor-badges {
        display: flex;
        align-items: center;
        .status-dot { width: 12rpx; height: 12rpx; background-color: #52c41a; border-radius: 50%; margin-right: 8rpx; }
        .sub-text { font-size: 24rpx; color: #999; }
      }
    }

    .header-action {
      display: flex;
      align-items: center;
      padding: 10rpx 20rpx;
      background: #F0F5FF;
      border-radius: 32rpx;
      .expand-tip { font-size: 24rpx; color: $primary-blue; margin-right: 6rpx; }
    }
  }
}

.doctor-detail-panel {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
  background: $bg-white;

  &.panel-show { max-height: 300rpx; border-bottom: 1rpx solid #eee; }

  .detail-grid {
    padding: 24rpx 32rpx;
    display: flex;
    flex-wrap: wrap;
    gap: 24rpx;
    .detail-row {
      width: 45%;
      display: flex;
      flex-direction: column;
      &.full-width { width: 100%; }
      .label { font-size: 22rpx; color: #999; margin-bottom: 8rpx; }
      .value { font-size: 26rpx; color: #333; line-height: 1.4; }
      .tag-value { color: $primary-blue; background: #e6f2ff; padding: 2rpx 8rpx; border-radius: 4rpx; display: inline-block; width: fit-content;}
      .desc-value { color: #666; }
    }
  }
}

// ================= 消息滚动区域 =================
.chat-messages {
  flex: 1;
  background-color: $bg-page;
  box-sizing: border-box;
}

.message-list-container {
  padding: 30rpx 24rpx;
}

.empty-state { text-align: center; padding: 40rpx 0; .empty-text { font-size: 24rpx; color: #ccc; } }
.loading-spinner { display: flex; justify-content: center; align-items: center; padding: 20rpx; .spinner { width: 30rpx; height: 30rpx; border: 2rpx solid #ddd; border-top-color: #999; border-radius: 50%; animation: spin 0.8s linear infinite; } .spinner-text { font-size: 24rpx; color: #999; margin-left: 10rpx;} }
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }

.time-divider { text-align: center; margin: 30rpx 0; .time-text { font-size: 22rpx; color: #aaa; background: rgba(0,0,0,0.03); padding: 4rpx 16rpx; border-radius: 8rpx; } }

// ================= 底部输入 =================
.chat-footer {
  background-color: #F7F7F7; // 微信风格浅灰背景
  border-top: 1rpx solid rgba(0,0,0,0.05);
  padding: 16rpx 24rpx 40rpx 24rpx;
  position: fixed;
  bottom: 0; left: 0; right: 0; z-index: 99;
  transition: bottom 0.2s ease-out;

  .consultation-ended-notice { display: flex; align-items: center; justify-content: center; padding: 30rpx; color: #999; font-size: 28rpx; gap: 12rpx; }

  .input-bar {
    display: flex; align-items: flex-end; gap: 16rpx;

    // 图标按钮
    .icon-btn {
      width: 72rpx; height: 72rpx;
      display: flex; align-items: center; justify-content: center;
      flex-shrink: 0;
      &:active { opacity: 0.6; }
    }

    // 输入框容器
    .input-field-wrapper {
      flex: 1;
      min-height: 72rpx;
      display: flex; align-items: center;

      .main-input {
        width: 100%; height: 72rpx;
        padding: 0 20rpx;
        font-size: 30rpx; color: #333;
        background: #fff;
        border-radius: 12rpx;
      }

      .voice-btn {
        width: 100%; height: 72rpx;
        background: #fff; border-radius: 12rpx;
        display: flex; align-items: center; justify-content: center;
        font-size: 30rpx; color: #333; font-weight: 500;
        border: 1rpx solid rgba(0,0,0,0.05);
        &.recording { background: #f0f0f0; color: #666; }
      }
    }

    // 右侧发送/加号
    .right-action {
      height: 72rpx; display: flex; align-items: center; justify-content: center;
      .send-btn {
        background: $primary-blue; color: #fff;
        font-size: 26rpx; padding: 0 24rpx; height: 60rpx; line-height: 60rpx;
        border-radius: 8rpx;
      }
    }
  }
}

.recording-overlay {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.6); z-index: 999; display: flex; align-items: center; justify-content: center;
  .recording-box {
    width: 300rpx; height: 300rpx; background: rgba(0,0,0,0.8); border-radius: 32rpx; display: flex; flex-direction: column; align-items: center; justify-content: center; color: #fff; gap: 20rpx;
    .wave-animation { width: 100rpx; height: 4rpx; background: $primary-blue; border-radius: 20rpx; }
    .timer { font-size: 32rpx; font-weight: 600; }
    .tip { font-size: 24rpx; color: #ccc; }
  }
}
</style>