<template>
  <view class="deepseek-chat-container">
    <scroll-view class="chat-messages" scroll-y :scroll-into-view="scrollIntoView" v-show="pestMessage">
      <view class="message-content">
        <view class="message-input" style="padding:0">{{ pestMessage }}</view>
        <view v-if="isloading" class="loading-hint">AI 正在分析中…</view>
        <rich-text class="message-text markdown-output" :nodes="outputHtml"></rich-text>
        <view class="message-input footer">内容由大模型生成，仅供参考，相关风险需自行承担。</view>
      </view>
      <view id="chatBottomAnchor"></view>
    </scroll-view>
    <view v-if="!pestMessage" style="height:100%">
      
    </view>
  </view>
</template>

<script>
import { createSSEConnection } from './sse.js';
import { renderMarkdown } from './markdownRenderer.js';

export default {
  name: 'DeepSeekChat',
  props: {
    pestMessage: {
      type: String,
      default: ''
    },
  },
  data() {
    return {
      text: '',
      sseConnection: null,
      result: '',
      thinking: false,
      activeNames: ['1'],
      thinkHtml: '',
      isloading: true,
      mdParser: null,
      mdRawText: '',   // 累积的原始 markdown 文本
      outputHtml: '',  // renderMarkdown 渲染后的 HTML，交给 rich-text 展示
      scrollIntoView: '', // scroll-view 滚动到底部锚点用
    };
  },
  watch: {
    text: {
      handler() {
        this.$nextTick(() => {
          this.scrollToBottom();
        });
      },
      deep: true
    },
    pestMessage(newVal) {
      if (newVal) {
        this.connectSSE(newVal);
      } else {
        this.isloading = false;
      }
    }
  },
  methods: {
    initParser() {
      this.mdRawText = '';
      this.outputHtml = '';
    },
    connectSSE(message) {
      this.initParser();
      this.text = '';
      this.thinkHtml = '';
      let thinkContent = '';
      let isCollecting = false;
      const sseUrl = `https://ai.nyzhwlw.com/analysis?message=${message}`;
      this.sseConnection = createSSEConnection(sseUrl);
      this.sseConnection.onMessage((data) => {
        this.isloading = false;
        if (data === 'yfkj@2025' || data === '[DONE]') {
          return;
        }
        // 处理 <think>...</think> 思考块：模板里不展示思考内容，
        // 且原代码用到的 mdParser 未初始化（为 null）会抛错，导致 isCollecting 一直为 true、
        // 后续正文也再不会渲染。这里整体丢弃思考块，只保留 </think> 之后可能跟着的正文。
        if (isCollecting || data.indexOf('<think>') > -1) {
          if (data.indexOf('<think>') > -1) {
            isCollecting = true;
            this.thinking = true;
          }
          thinkContent += data;
          const endIdx = thinkContent.indexOf('</think>');
          if (endIdx === -1) {
            return; // 仍在思考块内，等待结束标记
          }
          // 思考块结束，取出其后的正文继续走正常渲染
          data = thinkContent.slice(endIdx + '</think>'.length);
          thinkContent = '';
          isCollecting = false;
          this.thinking = false;
          if (!data) {
            return;
          }
        }
        // 累积正文并渲染为 markdown，用 rich-text 展示
        this.mdRawText += data;
        this.outputHtml = renderMarkdown(this.mdRawText);
        this.scrollToBottom();
      });

      this.sseConnection.onError((error) => {
        console.error('SSE Error:', error);
        this.disconnectSSE();
      });
    },
    collapseHtml() {
      let result = '';
      return result;
    },
    async renderHtml(result) {
      this.text = result;
      // 触发浏览器重绘
      await new Promise((resolve) => setTimeout(resolve, 20));
    },
    disconnectSSE() {
      if (this.sseConnection) {
        this.sseConnection.close();
        this.sseConnection = null;
        this.isloading = false;
      }
    },
    formatTime(date) {
      return date.toLocaleTimeString([], {
        hour: '2-digit',
        minute: '2-digit'
      });
    },
    scrollToBottom() {
      // 小程序没有 DOM，不能用 $refs.scrollTop；改用 scroll-view 的 scroll-into-view 滚到底部锚点
      this.scrollIntoView = '';
      this.$nextTick(() => {
        this.scrollIntoView = 'chatBottomAnchor';
      });
    }
  },
  mounted() {
    this.scrollToBottom();
    if (this.pestMessage) {
      this.connectSSE(this.pestMessage);
    } else {
      this.isloading = false;
    }
  },
  beforeDestroy() {
    // 组件卸载时断开连接（uni-app 默认 Vue2，用 beforeDestroy）
    this.disconnectSSE();
  }
};
</script>

<style scoped lang="less">
.el-collapse {
  background: #f6f6f6;
  color: #a4aab2;
  border-radius: 8rpx;
}
::v-deep .el-collapse-item__header {
  padding: 0 16rpx;
  height: 72rpx;
  background: #f6f6f6 !important;
  border-radius: 8rpx;
}
::v-deep .el-collapse-item__wrap {
  background: #f6f6f6 !important;
  color: #a4aab2 !important;
  border-radius: 8rpx;
}
::v-deep .el-collapse-item__content {
  color: #a4aab2 !important;
  border-radius: 8rpx;
}
.deep-thinking {
  padding: 0 52rpx;
  border-radius: 8rpx;
}
.deepseek-chat-container {
  position: relative;
  display: flex;
  flex-direction: column;
  height: calc(100vh - 640rpx);
  // max-width: 1086px;
  margin: 0 auto;
  border-radius: 8rpx;
  // box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  font-family: 'Segoe UI', Arial, sans-serif;
  // background-color: #f9f9f9;
}
.chat-messages {
  flex: 1;
  overflow-y: auto;
  height: 100%;
  // background-color: #ffffff;
}

.message {
  display: flex;
  margin-bottom: 24rpx;
}

.message-content {
  max-width: 100%;
}
.loading-hint {
  padding: 16rpx;
  color: #999;
  font-size: 26rpx;
}

.message-text {
  padding: 16rpx;
  border-radius: 18rpx;
  line-height: 1.4;
  word-wrap: break-word;
  padding-bottom: 60rpx;
}

.message.bot .message-text {
  background-color: #fff;
  border-top-left-radius: 8rpx;
  color: #5c5c5c;
}

.message.user .message-text {
  color: white;
  border-top-right-radius: 8rpx;
}

.message-time {
  font-size: 22rpx;
  color: #777;
  margin-top: 8rpx;
  text-align: right;
}

.message.user .message-time {
  text-align: left;
}

.typing-indicator {
  display: flex;
  padding: 12rpx 30rpx;
  background-color: #f6f6f6;
  border-radius: 18rpx;
  border-top-left-radius: 8rpx;
}

.typing-indicator span {
  width: 16rpx;
  height: 16rpx;
  margin: 0 2rpx;
  background-color: #999;
  border-radius: 50%;
  display: inline-block;
  animation: bounce 1.4s infinite ease-in-out both;
}

.typing-indicator span:nth-child(1) {
  animation-delay: -0.32s;
}

.typing-indicator span:nth-child(2) {
  animation-delay: -0.16s;
}
@keyframes bounce {
  0%,
  80%,
  100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}

/* Markdown样式 - 使用深度选择器 */
::v-deep .markdown-output {
  /* 标题样式 */
  h1, h2, h3, h4, h5, h6 {
    margin-top: 32rpx;
    margin-bottom: 16rpx;
    font-weight: 600;
    line-height: 1.25;
  }
  h1 { font-size: 2em; }
  h2 { font-size: 1.5em; }
  h3 { font-size: 1.25em; }
  h4 { font-size: 1em; }
  h5 { font-size: 0.875em; }
  h6 { font-size: 0.85em; }

  /* 列表样式 */
  ul, ol {
    padding-left: 2em;
    margin: 16rpx 0;
    list-style-type: disc;
  }
  ol {
    list-style-type: decimal;
  }
  li {
    margin: 8rpx 0;
    line-height: 1.5;
  }

  /* 粗体斜体 */
  strong {
    font-weight: 600;
  }
  em {
    font-style: italic;
  }

  /* 代码块 */
  pre {
    background-color: #f6f8fa;
    padding: 32rex;
    border-radius: 12rpx;
    overflow-x: auto;
    margin: 16rpx 0;
  }
  code {
    background-color: #f6f8fa;
    padding: 4rpx 8rpx;
    border-radius: 6rpx;
    font-family: monospace;
  }

  /* 段落 */
  p {
    margin: 16rpx 0;
    line-height: 1.5;
  }
}

.message-input {
  padding: 20rpx 30rpx;
  border-radius: 8rpx;
  background-color: #f6f6f6;

  &.footer {
    position: fixed;
    bottom: 20rpx;
    left: 0;
    right: 0rpx;
    margin-top: 40rpx;
    font-size: 24rpx;
    color: #999;
    text-align: center;
  }
}
</style>
