<template>
  <div class="conversation-panel">
    <!-- 配置加载中 -->
    <div v-if="configLoading" class="loading-tip">
      <i class="el-icon-loading"></i>
      <p>正在加载配置...</p>
    </div>
    <!-- 配置加载失败 / 无配置 -->
    <div v-else-if="configError" class="empty-tip">
      <i class="el-icon-warning"></i>
      <p>{{ configErrorMsg || '企微未配置，请先配置企微应用' }}</p>
    </div>
    <!-- 未登录 -->
    <div v-else-if="!isLoggedIn" class="login-area">
      <div class="login-tip">请扫码登录企微</div>
      <div id="login-container" ref="loginContainer" class="login-container"></div>
    </div>
    <!-- 已登录但未选择员工 -->
    <div v-else-if="!staffUserId" class="empty-tip">
      <i class="el-icon-info"></i>
      <p>请在左侧选择一个企微员工</p>
    </div>
    <!-- 已登录但未选择客户 -->
    <div v-else-if="!customerId" class="empty-tip">
      <i class="el-icon-info"></i>
      <p>请在左侧选择一个客户查看会话</p>
    </div>
    <!-- 会话加载中 -->
    <div v-else-if="!isReady" class="loading-tip">
      <i class="el-icon-loading"></i>
      <p>正在加载会话记录...</p>
    </div>
    <!-- 会话为空 -->
    <div v-else-if="msgList.length === 0 && !searchMode" class="empty-tip">
      <i class="el-icon-info"></i>
      <p>暂无会话数据</p>
    </div>
    <!-- 搜索结果为空 -->
    <div v-else-if="searchMode && searchResultList.length === 0" class="empty-tip">
      <i class="el-icon-info"></i>
      <p>未找到相关消息</p>
    </div>
    <!-- 聊天窗口（正常会话或搜索结果） -->
    <template v-else>
      <div class="search-bar">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索聊天内容（文本、文件名称等）"
          size="small"
          clearable
          @keyup.enter.native="doSearch"
        >
          <el-button
            slot="append"
            icon="el-icon-search"
            :loading="searchLoading"
            @click="doSearch"
          >搜索</el-button>
        </el-input>
        <el-button
          v-if="searchMode"
          type="text"
          size="small"
          @click="clearSearch"
          style="margin-left: 8px;"
        >清除搜索</el-button>
      </div>
      <div id="chat-container" ref="chatContainer"></div>
    </template>
  </div>
</template>

<script>
import * as ww from '@wecom/jssdk';
import defaultStaffAvatar from '@/assets/images/user.png';
import { qwLogin, qwSignature, qwConversations, getQwSessionConfig, qwSearchMsg } from '@/api/qw/companySession';

// ========== 全局配置缓存 ==========
window._QW_CONFIG_CACHE = window._QW_CONFIG_CACHE || new Map();
window._QW_CONFIG_PENDING = window._QW_CONFIG_PENDING || new Map();
const CACHE_TTL = 5 * 60 * 1000;

function getCachedConfig(corpId) {
  if (!corpId) return null;
  const cached = window._QW_CONFIG_CACHE.get(corpId);
  if (cached && (Date.now() - cached.timestamp) < CACHE_TTL) {
    return cached.config;
  }
  window._QW_CONFIG_CACHE.delete(corpId);
  return null;
}

function setCachedConfig(corpId, config) {
  if (!corpId) return;
  window._QW_CONFIG_CACHE.set(corpId, { config, timestamp: Date.now() });
}

export default {
  name: 'ConversationPanel',
  props: {
    corpId: { type: String, default: null },
    customerId: { type: String, default: null },
    customerAvatar: { type: String, default: '' },
    staffUserId: { type: String, default: null }
  },
  data() {
    return {
      isLoggedIn: false,
      isReady: false,
      msgList: [],
      cursor: '',
      hasMore: true,
      loadingMore: false,
      chatInstance: null,
      _sdkInited: false,
      defaultStaffAvatar: defaultStaffAvatar,
      config: { corpid: '', agentid: '', domain: '' },
      configReady: false,
      configError: false,
      configLoading: false,
      configErrorMsg: '',
      tokenCheckTimer: null,
      lastLogoutTime: 0,
      _hasEmittedLogout: false,
      _loginPanelCreated: false,
      _loginPanelRetryCount: 0,
      _loginPanelTimer: null,
      // 搜索相关
      searchKeyword: '',
      searchLoading: false,
      searchMode: false,
      searchResultList: [],
      searchCursor: '',
      searchHasMore: false
    };
  },
  watch: {
    customerId(newId, oldId) {
      if (newId && newId !== oldId && this.isLoggedIn && this.staffUserId && this.configReady && !this.configError) {
        this.clearSearch();
        this.resetAndReload();
      }
    },
    staffUserId(newVal, oldVal) {
      if (newVal && newVal !== oldVal && this.customerId && this.isLoggedIn && this.configReady && !this.configError) {
        this.clearSearch();
        this.resetAndReload();
      }
    },
    corpId(newId, oldId) {
      if (newId !== oldId) {
        this.destroyChat();
        this.isReady = false;
        this._sdkInited = false;
        this._hasEmittedLogout = false;
        this._loginPanelCreated = false;
        this._loginPanelRetryCount = 0;
        if (this._loginPanelTimer) {
          clearTimeout(this._loginPanelTimer);
          this._loginPanelTimer = null;
        }
        this.searchMode = false;
        this.searchKeyword = '';
        this.searchResultList = [];
        this.msgList = [];
        this.cursor = '';
        this.hasMore = true;
        this.loadingMore = false;
        this.isLoggedIn = false;

        const cached = getCachedConfig(newId);
        if (cached) {
          this.config = cached;
          this.configReady = true;
          this.configError = false;
          this.configLoading = false;
          this.handleAuthAndLoad();
        } else {
          this.configReady = false;
          this.configError = false;
          this.configLoading = false;
          this.initConfig().then(() => {
            if (this.configReady && !this.configError) {
              this.handleAuthAndLoad();
            }
          });
        }
      }
    },
    customerAvatar(newAvatar) {
      if (this.chatInstance && newAvatar) {
        this.chatInstance.setData({ customerAvatar: newAvatar });
      }
    },
    isLoggedIn: {
      handler(newVal) {
        if (!newVal && this.configReady && !this.configError && this._sdkInited && !this._loginPanelCreated) {
          this.tryCreateLoginPanel();
        }
      },
      immediate: true
    }
  },
  async mounted() {
    this._hasEmittedLogout = false;
    this._loginPanelCreated = false;

    const cached = getCachedConfig(this.corpId);
    if (cached) {
      this.config = cached;
      this.configReady = true;
      this.configError = false;
      this.configLoading = false;
      await this.handleAuthAndLoad();
    } else {
      await this.initConfig();
      if (this.configReady && !this.configError) {
        await this.handleAuthAndLoad();
      }
    }

    this.tokenCheckTimer = setInterval(() => {
      if (this.isLoggedIn && this.configReady && !this.configError && this._sdkInited) {
        this.getAgentConfigSignature().catch(e => console.warn('签名刷新失败', e));
      }
    }, 90 * 60 * 1000);
  },
  beforeDestroy() {
    if (this.tokenCheckTimer) {
      clearInterval(this.tokenCheckTimer);
      this.tokenCheckTimer = null;
    }
    if (this._loginPanelTimer) {
      clearTimeout(this._loginPanelTimer);
      this._loginPanelTimer = null;
    }
    this.destroyChat();
  },
  methods: {
    // ========== Storage Key ==========
    getStorageKey(corpId, suffix = 'expire') {
      if (!corpId) return null;
      return `wecom_session_${corpId}_${suffix}`;
    },
    checkLoginState(corpId) {
      if (!corpId) return false;
      const expire = localStorage.getItem(this.getStorageKey(corpId, 'expire'));
      if (!expire) return false;
      return Date.now() < parseInt(expire, 10);
    },
    storeLoginState(corpId) {
      if (!corpId) return;
      localStorage.setItem(this.getStorageKey(corpId, 'expire'), String(Date.now() + 115 * 60 * 1000));
    },
    clearLoginState(corpId) {
      if (!corpId) return;
      localStorage.removeItem(this.getStorageKey(corpId, 'expire'));
    },

    // ========== 配置加载 ==========
    async initConfig() {
      if (!this.corpId || this.configReady || this.configError) return;

      const cached = getCachedConfig(this.corpId);
      if (cached) {
        this.config = cached;
        this.configReady = true;
        this.configError = false;
        this.configLoading = false;
        return;
      }

      if (window._QW_CONFIG_PENDING.has(this.corpId)) {
        return window._QW_CONFIG_PENDING.get(this.corpId);
      }

      this.configLoading = true;
      const promise = (async () => {
        try {
          const res = await getQwSessionConfig(this.corpId);
          let configData = null;
          if (res && res.code === 200 && res.data && res.data.corpid) {
            configData = res.data;
          } else if (res && res.data && res.data.corpid) {
            configData = res.data;
          } else if (res && res.corpid) {
            configData = res;
          }

          if (!configData || !configData.corpid || !configData.agentid) {
            throw new Error('配置数据不完整：缺少 corpid 或 agentid');
          }

          const cfg = {
            corpid: configData.corpid,
            agentid: String(configData.agentid),
            domain: configData.domain || ''
          };

          this.config = cfg;
          this.configReady = true;
          this.configError = false;
          this.configErrorMsg = '';
          setCachedConfig(this.corpId, cfg);
        } catch (e) {
          this.configReady = false;
          this.configError = true;
          this.configErrorMsg = e.message || '获取配置失败';
        } finally {
          this.configLoading = false;
          window._QW_CONFIG_PENDING.delete(this.corpId);
        }
      })();

      window._QW_CONFIG_PENDING.set(this.corpId, promise);
      return promise;
    },

    // ========== 认证与加载主流程 ==========
    async handleAuthAndLoad() {
      if (this.configError) return;
      if (!this.configReady) {
        await this.initConfig();
        if (this.configError) return;
      }

      const sdkOk = await this.initSDKOnce();
      if (!sdkOk) {
        console.error('[ConversationPanel] SDK 初始化失败');
        return;
      }

      const urlParams = new URLSearchParams(window.location.search);
      const code = urlParams.get('code');

      if (code) {
        const cleanUrl = window.location.origin + window.location.pathname;
        window.history.replaceState({}, '', cleanUrl);
        try {
          await this.handleLogin(code);
          this.storeLoginState(this.corpId);
          this.isLoggedIn = true;
          if (this.customerId && this.staffUserId) {
            await this.loadFirstPage();
          }
        } catch (err) {
          console.error('[ConversationPanel] 登录失败:', err);
          this.clearLoginState(this.corpId);
          this.isLoggedIn = false;
          this.safeEmitLogout();
        }
      } else {
        if (this.checkLoginState(this.corpId)) {
          this.isLoggedIn = true;
          if (this.customerId && this.staffUserId) {
            await this.loadFirstPage();
          }
        } else {
          this.isLoggedIn = false;
          this.safeEmitLogout();
          this.tryCreateLoginPanel();
        }
      }
    },

    tryCreateLoginPanel() {
      if (this._loginPanelCreated) return;
      if (!this.configReady || this.configError || !this._sdkInited) {
        return;
      }
      if (this.isLoggedIn) return;
      if (this._loginPanelTimer) {
        clearTimeout(this._loginPanelTimer);
        this._loginPanelTimer = null;
      }
      this.$nextTick(() => {
        this.createLoginPanel();
      });
    },

    // ========== 登录面板 ==========
    createLoginPanel() {
      if (this._loginPanelCreated) {
        return;
      }
      if (!this.configReady || this.configError || !this._sdkInited) {
        return;
      }
      if (this.isLoggedIn) return;

      let container = this.$refs.loginContainer;
      if (!container) {
        container = document.getElementById('login-container');
      }
      if (!container) {
        this._loginPanelTimer = setTimeout(() => {
          this._loginPanelTimer = null;
          this.createLoginPanel();
        }, 1000);
        return;
      }

      const rect = container.getBoundingClientRect();
      if (rect.width === 0 || rect.height === 0) {
        this._loginPanelTimer = setTimeout(() => {
          this._loginPanelTimer = null;
          this.createLoginPanel();
        }, 500);
        return;
      }

      container.innerHTML = '';
      this._loginPanelCreated = true;
      const redirectUri = window.location.origin + window.location.pathname;

      try {
        ww.createWWLoginPanel({
          el: container,
          params: {
            login_type: 'CorpApp',
            appid: this.config.corpid,
            agentid: this.config.agentid,
            redirect_uri: redirectUri,
            redirect_type: 'callback',
            state: 'state_' + Date.now()
          },
          onLoginSuccess: async ({ code }) => {
            try {
              await this.handleLogin(code);
              if (this.customerId && this.staffUserId) {
                await this.loadFirstPage();
              }
            } catch (e) {
              this.clearLoginState(this.corpId);
              this.isLoggedIn = false;
              this._loginPanelCreated = false;
              this.safeEmitLogout();
            }
          },
          onLoginError: (err) => {
            this._loginPanelCreated = false;
            this._loginPanelTimer = setTimeout(() => {
              this._loginPanelTimer = null;
              this.createLoginPanel();
            }, 3000);
          }
        });
      } catch (e) {
        this._loginPanelCreated = false;
        this._loginPanelTimer = setTimeout(() => {
          this._loginPanelTimer = null;
          this.createLoginPanel();
        }, 3000);
      }
    },

    safeEmitLogout() {
      if (this._hasEmittedLogout) return;
      this._hasEmittedLogout = true;
      this.$emit('logout');
    },

    async handleLogin(code) {
      const res = await qwLogin({ code, corpid: this.corpId });
      const data = this._extractResponse(res);
      if (data.errcode !== undefined && data.errcode !== 0) {
        throw new Error(data.errmsg || '登录失败');
      }
      this.storeLoginState(this.corpId);
      this.isLoggedIn = true;
      this.$emit('login-success');
    },

    // ========== SDK 签名 ==========
    async getAgentConfigSignature() {
      if (!this.configReady || this.configError) {
        throw new Error('配置未就绪');
      }
      const currentUrl = window.location.href.split('#')[0];
      const res = await qwSignature({ url: currentUrl, corpid: this.corpId });
      const data = this._extractResponse(res);

      if (data.errcode && data.errcode !== 0) {
        this.clearLoginState(this.corpId);
        this.isLoggedIn = false;
        this.isReady = false;
        this.destroyChat();
        this._loginPanelCreated = false;
        if (!this.configError) {
          this.safeEmitLogout();
        }
        throw new Error(`签名失败: ${data.errmsg}`);
      }

      return {
        timestamp: data.timestamp,
        nonceStr: data.nonceStr,
        signature: data.signature
      };
    },

    // ========== SDK 初始化 ==========
    async initSDKOnce() {
      if (this._sdkInited) return true;
      if (!this.configReady || this.configError) return false;

      try {
        await ww.register({
          corpId: this.config.corpid,
          agentId: this.config.agentid,
          jsApiList: ['selectExternalContact', 'shareAppMessage', 'wwapp.invokeJsApiByCallInfo'],
          getAgentConfigSignature: () => this.getAgentConfigSignature()
        });
        await ww.initOpenData();
        this._sdkInited = true;
        return true;
      } catch (e) {
        console.error('[ConversationPanel] SDK 初始化失败:', e);
        return false;
      }
    },

    // ========== 会话数据加载 ==========
    async loadFirstPage() {
      if (this.configError) return;
      try {
        const res = await qwConversations({
          customerId: this.customerId,
          staffUserId: this.staffUserId,
          limit: 100,
          cursor: this.cursor,
          corpid: this.corpId
        });
        const data = this._extractResponse(res);
        if (data.errcode !== undefined && data.errcode !== 0) {
          throw new Error(data.errmsg || '拉取失败');
        }
        this.msgList = data.data || [];
        this.cursor = data.next_cursor || '';
        this.hasMore = data.has_more === 1;
        this.isReady = true;

        await this.$nextTick();
        if (this.msgList.length > 0) {
          await this.renderOrUpdateChat();
        }
      } catch (e) {
        console.error('[ConversationPanel] 加载第一页失败', e);
        this.$message.error('加载会话失败：' + e.message);
        this.isReady = true;
        this.msgList = [];
      }
    },

    async loadMore() {
      if (!this.cursor || this.loadingMore || !this.hasMore || this.configError) return;
      this.loadingMore = true;
      try {
        const res = await qwConversations({
          customerId: this.customerId,
          staffUserId: this.staffUserId,
          limit: 50,
          cursor: this.cursor,
          corpid: this.corpId
        });
        const data = this._extractResponse(res);
        if (data.errcode !== undefined && data.errcode !== 0) {
          throw new Error(data.errmsg || '拉取更多失败');
        }
        const newMessages = data.data || [];
        if (newMessages.length > 0) {
          this.msgList = [...this.msgList, ...newMessages];
          this.cursor = data.next_cursor || '';
          this.hasMore = data.has_more === 1;
          if (this.chatInstance) {
            this.chatInstance.setData({ msgList: this.msgList });
          } else {
            await this.renderOrUpdateChat();
          }
        } else {
          this.hasMore = false;
        }
      } catch (e) {
        console.error('[ConversationPanel] 加载更多失败', e);
      } finally {
        this.loadingMore = false;
      }
    },

    // ========== 渲染聊天组件（原有，仅用于正常会话） ==========
    async renderOrUpdateChat() {
      if (this.msgList.length === 0 || this.configError) return;
      await this._renderChatWithData(this.msgList, this.hasMore);
    },

    // ========== 公共渲染方法 ==========
    async _renderChatWithData(msgList, hasMore = false) {
      const container = document.getElementById('chat-container');
      if (!container) return;

      if (this.chatInstance) {
        this.chatInstance.setData({ msgList, hasMore, loadingMore: this.loadingMore });
        return;
      }

      const ok = await this.initSDKOnce();
      if (!ok) return;

      const factory = ww.createOpenDataFrameFactory();
      if (!factory) return;

      this.chatInstance = factory.createOpenDataFrame({
        el: container,
        template: `
          <scroll-view scroll-y="{{true}}" bindscrolltolower="onScrollToLower" style="height: 100%;">
            <view wx:for="{{data.msgList}}" wx:for-item="msg" wx:key="msgid" style="margin-bottom: 15px;">
              <view style="text-align: center; margin-bottom: 8px;">
                <text style="background:#e9e9e9; color:#333; padding:4px 12px; border-radius:16px; font-size:12px;">
                  {{ msg.send_time_str }}
                </text>
              </view>
              <view
                style="display:flex; flex-direction:row; {{msg.sender.type == 1 ? 'justify-content:flex-end;' : 'justify-content:flex-start;'}}">
                <image wx:if="{{msg.sender.type == 2}}" src="{{data.customerAvatar}}"
                       style="width:36px;height:36px;border-radius:4px;margin-right:10px;background:#fff;"></image>
                <view
                  style="max-width:70%;padding:10px 14px;border-radius:8px;word-break:break-all;background:{{msg.sender.type == 1 ? '#95ec69' : '#ffffff'}};box-shadow:0 1px 3px rgba(0,0,0,0.1);display:flex;align-items:center;">
                  <ww-open-message message-id="{{msg.msgid}}" secret-key="{{msg.secretKey}}" open-type="viewMessage"/>
                </view>
                <image wx:if="{{msg.sender.type == 1}}" src="{{data.defaultStaffAvatar}}"
                       style="width:36px;height:36px;border-radius:4px;margin-left:10px;background:#fff;"></image>
              </view>
            </view>
            <view wx:if="{{data.hasMore && data.loadingMore}}" style="text-align:center;padding:10px;color:#999;">
              加载更多...
            </view>
          </scroll-view>
        `,
        data: {
          msgList: msgList,
          customerAvatar: this.customerAvatar,
          defaultStaffAvatar: this.defaultStaffAvatar,
          hasMore: hasMore,
          loadingMore: this.loadingMore
        },
        methods: {
          onScrollToLower: () => {
            if (this.searchMode) {
              if (this.searchHasMore && !this.searchLoading) this.loadMoreSearch();
            } else {
              if (this.hasMore && !this.loadingMore && !this.configError) this.loadMore();
            }
          }
        },
        error: (e) => {
          console.error('[企微组件] 错误', e);
          if (e && [42006, 42003, 40029].includes(e.errCode)) {
            if (!this.configError) {
              this.clearLoginState(this.corpId);
              this.isLoggedIn = false;
              this.isReady = false;
              this.destroyChat();
              this._loginPanelCreated = false;
              this.safeEmitLogout();
            }
          }
        },
        handleModal: ({ modalUrl, modalSize }) => {
          const mask = document.createElement('div');
          mask.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:9999;display:flex;align-items:center;justify-content:center;';
          const content = document.createElement('div');
          content.style.cssText = `position:relative;max-width:90vw;max-height:90vh;width:${modalSize?.width || 80}%;height:${modalSize?.height || 80}%;background:#fff;border-radius:8px;overflow:hidden;`;
          const closeBtn = document.createElement('button');
          closeBtn.innerText = '✕';
          closeBtn.style.cssText = 'position:absolute;top:10px;right:10px;z-index:10001;width:32px;height:32px;border-radius:50%;border:none;background:rgba(0,0,0,0.5);color:#fff;font-size:20px;cursor:pointer;display:flex;align-items:center;justify-content:center;';
          const iframe = document.createElement('iframe');
          iframe.src = modalUrl;
          iframe.style.cssText = 'width:100%;height:100%;border:none;';
          const cleanup = () => {
            mask.remove();
            document.removeEventListener('keydown', escHandler);
          };
          closeBtn.onclick = (e) => {
            e.stopPropagation();
            cleanup();
          };
          mask.onclick = (e) => {
            if (e.target === mask) cleanup();
          };
          const escHandler = (e) => {
            if (e.key === 'Escape') cleanup();
          };
          document.addEventListener('keydown', escHandler);
          content.appendChild(iframe);
          content.appendChild(closeBtn);
          mask.appendChild(content);
          document.body.appendChild(mask);
          return true;
        }
      });
    },

    async resetAndReload() {
      this.clearSearch();
      this.destroyChat();
      this.msgList = [];
      this.cursor = '';
      this.hasMore = true;
      this.loadingMore = false;
      this.isReady = false;
      await this.loadFirstPage();
    },

    destroyChat() {
      if (this.chatInstance) {
        this.chatInstance = null;
      }
      const container = document.getElementById('chat-container');
      if (container) container.innerHTML = '';
    },

    // ========== 关键词搜索 ==========
    async doSearch() {
      if (!this.searchKeyword || this.searchKeyword.length < 2) {
        this.$message.warning('关键词至少2个字符');
        return;
      }
      if (!this.staffUserId || !this.customerId) {
        this.$message.warning('请先选择员工和客户');
        return;
      }
      this.searchLoading = true;
      try {
        const res = await qwSearchMsg({
          corpId: this.corpId,
          queryWord: this.searchKeyword,
          chatType: 1,
          staffUserId: this.staffUserId,
          customerId: this.customerId,
          limit: 50
        });
        // 统一解包响应
        const result = this._extractResponse(res);
        if (result.code === 200 && result.data) {
          const searchData = result.data;
          this.searchMode = true;
          this.searchResultList = searchData.data || [];
          this.searchCursor = searchData.nextCursor || '';
          this.searchHasMore = searchData.hasMore === 1;
          await this.renderSearchResult();
          if (this.searchResultList.length === 0) {
            this.$message.info('未找到相关消息');
          }
        } else {
          this.$message.error(result.msg || '搜索失败');
        }
      } catch (e) {
        console.error('搜索异常', e);
        this.$message.error('搜索异常');
      } finally {
        this.searchLoading = false;
      }
    },

    async loadMoreSearch() {
      if (!this.searchCursor || this.searchLoading || !this.searchHasMore) return;
      this.searchLoading = true;
      try {
        const res = await qwSearchMsg({
          corpId: this.corpId,
          queryWord: this.searchKeyword,
          chatType: 1,
          staffUserId: this.staffUserId,
          customerId: this.customerId,
          limit: 50,
          cursor: this.searchCursor
        });
        const result = this._extractResponse(res);
        if (result.code === 200 && result.data) {
          const searchData = result.data;
          const newMessages = searchData.data || [];
          if (newMessages.length > 0) {
            this.searchResultList = [...this.searchResultList, ...newMessages];
            this.searchCursor = searchData.nextCursor || '';
            this.searchHasMore = searchData.hasMore === 1;
            if (this.chatInstance) {
              this.chatInstance.setData({ msgList: this.searchResultList, hasMore: this.searchHasMore });
            }
          } else {
            this.searchHasMore = false;
          }
        }
      } catch (e) {
        console.error('加载更多搜索结果失败', e);
      } finally {
        this.searchLoading = false;
      }
    },

    clearSearch() {
      if (!this.searchMode) return;
      this.searchMode = false;
      this.searchKeyword = '';
      this.searchResultList = [];
      this.searchCursor = '';
      this.searchHasMore = false;
      // 恢复原有聊天数据
      if (this.msgList.length > 0) {
        this.renderOrUpdateChat();
      } else if (this.isReady && this.customerId && this.staffUserId) {
        this.loadFirstPage();
      }
    },

    async renderSearchResult() {
      if (this.searchResultList.length === 0) return;
      await this._renderChatWithData(this.searchResultList, this.searchHasMore);
    },

    // 通用响应解包
    _extractResponse(res) {
      if (!res) return {};
      // 如果已经是标准 AjaxResult 格式 { code, msg, data }
      if (res.code !== undefined) return res;
      // 兼容直接返回数据的情况
      if (res.errcode !== undefined || res.timestamp || res.corpid || res.data) return res;
      if (res.data) {
        if (res.data.errcode !== undefined || res.data.timestamp || res.data.corpid || res.data.data) return res.data;
        if (res.data.data) return res.data.data;
      }
      return res;
    }
  }
};
</script>

<style scoped>
.conversation-panel {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #f5f6f7;
  position: relative;
}

.login-area,
.empty-tip,
.loading-tip {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  flex: 1;
}

.login-tip {
  font-size: 18px;
  color: #666;
  margin-bottom: 24px;
}

.empty-tip,
.loading-tip {
  color: #999;
  font-size: 16px;
}

.empty-tip i,
.loading-tip i {
  font-size: 48px;
  margin-bottom: 16px;
}

#chat-container {
  flex: 1;
  width: 100%;
  height: 100%;
  background: #f0f2f5;
}

.login-container {
  width: 320px;
  height: 380px;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>

<style>
/* 全局样式确保企微组件撑满 */
#chat-container,
#chat-container > div,
#chat-container iframe {
  width: 100% !important;
  height: 100% !important;
  min-width: 100% !important;
  min-height: 100% !important;
  overflow: hidden;
}

.search-bar {
  padding: 12px 16px;
  background: #fff;
  border-bottom: 1px solid #e8e8e8;
  display: flex;
  align-items: center;
}
.search-bar .el-input {
  flex: 1;
}
</style>
