<template>
  <view class="chat-container">
    <!-- 聊天内容区域 -->
    <scroll-view 
      class="chat-content" 
      scroll-y 
      :scroll-top="scrollTop"
      :scroll-with-animation="true"
      @scrolltoupper="loadMoreMessages"
      :refresher-enabled="false"
      ref="scrollView"
    >
      <view class="message-wrapper-box" >
      	<view v-for="(message, index) in messages" :key="index" class="message-wrapper">
      	  <!-- 系统消息或AI消息 -->
      	  <block v-if="message.role === 'system' || message.role === 'assistant'">
      	    <view class="message-container ai-message-container">
      	      <view class="message ai-message">
      	        <!-- 使用渲染后的Markdown内容 -->
      	        <rich-text class="message-content markdown-body" :nodes="message.renderedContent"></rich-text>
      	      </view>
      	      <text class="message-time">{{ message.time }}</text>
      	    </view>
      	    <!-- 在每条AI消息后显示确认按钮（除了系统消息） -->
      	    <view v-if="message.role === 'assistant' && message.endStatus" class="accept-button-container">
      	      <u-button
      	        type="success"
      	        size="mini"
      	        @click="acceptScript(message.content)"
      	        :custom-style="{marginTop: '10px'}"
      	      >
      	        <u-icon name="checkmark" size="14" class="button-icon"></u-icon>
      	        确认使用此剧本
      	      </u-button>
      	    </view>
      	  </block>

      	  <!-- 用户消息 -->
      	  <block v-else-if="message.role === 'user'">
      	    <view class="message-container user-message-container">
      	      <view class="message user-message">
      	        <text class="message-content">{{ message.content }}</text>
      	      </view>
      	      <text class="message-time">{{ message.time }}</text>
      	    </view>
      	  </block>
      	</view>

      	<!-- 加载中提示 -->
      	<view v-if="loading" class="loading-container">
      	  <u-loading mode="circle" size="24"></u-loading>
      	  <text class="loading-text">正在生成剧本...</text>
      	</view>

      	<!-- 用于滚动到底部的空白元素 -->
      	<view id="scroll-bottom-anchor" style="height: 1px;"></view>

      	<!-- 底部占位，确保内容不被输入框遮挡 -->
      	<view class="bottom-placeholder"></view>
      </view>
    </scroll-view>

    <!-- 输入区域 - 固定在底部 -->
    <view class="chat-input-container">
      <view class="chat-input">
        <u-input
          v-model="inputMessage"
          placeholder="请输入剧本相关描述，AI将为您生成专业剧本..."
          :disabled="loading"
					type='textarea'
          :auto-height="true"
          :custom-style="{flex: 1, minHeight: '80rpx', maxHeight: '200rpx'}"
          @confirm="sendMessage"
        ></u-input>
        <u-button 
          type="primary" 
          :disabled="loading || !inputMessage.trim()" 
          @click="sendMessage"
          :custom-style="{marginLeft: '10px'}"
        >
          发送
        </u-button>
      </view>
    </view>
  </view>
</template>

<script>
import { renderMarkdown } from './markdown.js';
import config from "@/common/api/config.js"

export default {
  data() {
    return {
      // 聊天消息列表
      messages: [
        {
          role: 'system',
          content: '你好！我是你的AI剧本助手。请告诉我你想创作的剧本类型和主要情节，我会为你生成专业的剧本内容。',
          renderedContent: '',
          time: this.formatTime(new Date()),
          endStatus: true
        }
      ],
      // 输入框内容
      inputMessage: '',
      // 加载状态
      loading: false,
      // 滚动位置
      scrollTop: 0,
      // URL参数
      orderId: '',
      // API密钥
      apiKey: 'sk-uobtjwyzastkxcnrrbllxpftqxdumkafnitdqqhoermmioru',
      // 当前AI消息索引
      currentAiMessageIndex: -1,
      // 是否是H5环境
      isH5: false,
      // 是否需要滚动到底部
      needScrollToBottom: true,
      // 滚动计时器
      scrollTimer: null,
			token:''
    };
  },
  onLoad(options) {
    // 从URL获取参数
    this.orderId = options.orderId || '';
    this.token = uni.getStorageSync('userToken');
    // 检测是否是H5环境
    // #ifdef H5
    this.isH5 = true;
    // #endif
    
    // 初始化
    this.initPage();
    
    // 渲染初始消息的Markdown内容
    this.renderAllMarkdown();
  },
  onReady() {
    // 页面加载完成后滚动到底部
    this.throttledScrollToBottom();
  },
  onUnload() {
    // 清除滚动计时器
    if (this.scrollTimer) {
      clearTimeout(this.scrollTimer);
      this.scrollTimer = null;
    }
  },
  watch: {
    // 监听消息变化，自动滚动到底部
    messages: {
      deep: true,
      handler() {
        if (this.needScrollToBottom) {
          this.throttledScrollToBottom();
        }
      }
    }
  },
  methods: {
    // 初始化页面
    initPage() {
      // 设置导航栏标题
      uni.setNavigationBarTitle({
        title: 'AI 剧本助手'
      });
    },
    
    // 渲染所有消息的Markdown内容
    renderAllMarkdown() {
      this.messages.forEach((message, index) => {
        if (message.role === 'system' || message.role === 'assistant') {
          this.messages[index].renderedContent = renderMarkdown(message.content);
        }
      });
    },
    
    // 格式化时间为 HH:MM 格式
    formatTime(date) {
      const hours = date.getHours().toString().padStart(2, '0');
      const minutes = date.getMinutes().toString().padStart(2, '0');
      return `${hours}:${minutes}`;
    },
    
    // 发送消息
    async sendMessage() {
      if (!this.inputMessage.trim() || this.loading) return;
      
      // 添加用户消息
      const userMessage = {
        role: 'user',
        content: this.inputMessage,
        time: this.formatTime(new Date())
      };
      this.messages.push(userMessage);
      
      // 清空输入框
      const userInput = this.inputMessage;
      this.inputMessage = '';
      
      // 设置加载状态
      this.loading = true;
      
      // 滚动到底部
      this.throttledScrollToBottom();
      
      try {
        // 准备发送给API的消息
        const apiMessages = [
          {
            role: 'system',
            content: '你好！我是你的AI剧本助手。请告诉我你想创作的剧本类型和主要情节，我会为你生成专业的剧本内容。请使用Markdown格式来组织你的回答，可以使用标题、列表、粗体、斜体等Markdown语法来增强可读性。'
          },
          ...this.messages
            .filter(msg => msg.role !== 'system')
            .map(msg => ({
              role: msg.role,
              content: msg.content
            }))
        ];
        
        // 在H5环境中使用fetch API进行流式请求
        if (this.isH5) {
          await this.fetchStreamResponse(apiMessages);
        } else {
          // 在非H5环境中使用普通请求
          await this.fetchNormalResponse(apiMessages);
        }
      } catch (error) {
        console.error('API请求失败:', error);
        uni.showToast({
          title: '生成剧本失败，请稍后重试',
          icon: 'none'
        });
      } finally {
        this.loading = false;
        // 滚动到底部
        this.throttledScrollToBottom();
      }
    },
    
    // 使用fetch API进行流式请求（仅H5环境）
    async fetchStreamResponse(apiMessages) {
      try {
        // 添加一个空的AI回复，用于流式更新
        this.currentAiMessageIndex = this.messages.length;
        this.messages.push({
          role: 'assistant',
          content: '',
          renderedContent: '',
          time: this.formatTime(new Date()),
          endStatus: false
        });
        
        const response = await fetch(`${config.baseUrl}/ai/generateStream`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${this.token}`,
            'clientid': config.clientId,
            'Content-Type': 'application/json'
          },
          redirect: 'follow',
          body: JSON.stringify(apiMessages)
        });
      
        if (!response.ok) {
          throw new Error(`API请求失败: ${response.status}`);
        }
      
        if (!response.body) {
          throw new Error('响应体为空');
        }
      
        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        let result = '';
        let buffer = ''; // 用于存储未完整的数据
      
        while (true) {
          const { done, value } = await reader.read();
          if (done) break;
          
          const chunk = decoder.decode(value, { stream: true }); // Use streaming mode
          buffer += chunk;
          
          //  将新的chunk添加到buffer中
          const lines = buffer.split('\n');
          // 按换行符分割,但保留buffer中可能不完整的最后一行
          buffer = lines.pop() || '';
          
          for (const line of lines) {
            if (!line.trim()) continue; // Skip empty lines
            
            let data = line;
            
            if (line.startsWith('data:')) {
              data = line.substring(5).trim();
            }
            
            if (data === '[DONE]') {
              // 设置消息已完成状态
              if (this.currentAiMessageIndex >= 0 && this.currentAiMessageIndex < this.messages.length) {
                this.messages[this.currentAiMessageIndex].endStatus = true;
                this.throttledScrollToBottom();
              }
              continue;
            }
            
            try {
              // For JSON data (if your API returns JSON)
              if (data.startsWith('{') && data.endsWith('}')) {
                const parsed = JSON.parse(data);
                const content = parsed.choices?.[0]?.delta?.content || '';
                if (content) {
                  result += content;
                }
              } else {
                // For plain text data
                result += data;
              }
              
              // Update message content
              if (this.currentAiMessageIndex >= 0 && this.currentAiMessageIndex < this.messages.length) {
                this.messages[this.currentAiMessageIndex].content = result;
                this.messages[this.currentAiMessageIndex].renderedContent = renderMarkdown(result);
                this.throttledScrollToBottom();
              }
            } catch (e) {
              console.error('解析流数据失败:', e, line);
            }
          }
        }
        
        // Process any remaining data in buffer
        if (buffer.trim()) {
          try {
            let data = buffer;
            if (buffer.startsWith('data:')) {
              data = buffer.substring(5).trim();
            }
            if (data && data !== '[DONE]') {
              // For JSON data
              if (data.startsWith('{') && data.endsWith('}')) {
                try {
                  const parsed = JSON.parse(data);
                  const content = parsed.choices?.[0]?.delta?.content || '';
                  if (content) {
                    result += content;
                  }
                } catch (e) {
                  // If not valid JSON, treat as plain text
                  result += data;
                }
              } else {
                // For plain text data
                result += data;
              }
              
              this.messages[this.currentAiMessageIndex].content = result;
              this.messages[this.currentAiMessageIndex].renderedContent = renderMarkdown(result);
              this.throttledScrollToBottom();
            }
          } catch (e) {
            console.error('处理剩余数据失败:', e, buffer);
          }
        }
        
        // Ensure message is marked as complete
        if (this.currentAiMessageIndex >= 0 && this.currentAiMessageIndex < this.messages.length) {
          this.messages[this.currentAiMessageIndex].endStatus = true;
        }
        
        return result;
      } catch (error) {
        console.error('调用流式API失败:', error);
        // If error occurs, ensure empty AI message is removed
        if (this.messages.length > 0 && this.messages[this.messages.length - 1].content === '') {
          this.messages.pop();
          this.currentAiMessageIndex = -1;
        }
        throw error;
      }
    },
    
    // Use normal request (non-H5 environment)
    async fetchNormalResponse(apiMessages) {
      try {
        // Add an empty AI reply
        this.currentAiMessageIndex = this.messages.length;
        this.messages.push({
          role: 'assistant',
          content: '',
          renderedContent: '',
          time: this.formatTime(new Date()),
          endStatus: false
        });
        
        const response = await uni.request({
          url: `${config.baseUrl}/ai/generate`,
          method: 'POST',
          header: {
            'Authorization': `Bearer ${this.token}`,
            'clientid': config.clientId,
            'Content-Type': 'application/json'
          },
          data: apiMessages,
          dataType: 'json'
        });
        
        // Check response status
        if (response.statusCode !== 200) {
          throw new Error(`API请求失败: ${response.statusCode}`);
        }
        
        // Get response content
        const result = response.data.content || '';
        
        // Update message content
        this.messages[this.currentAiMessageIndex].content = result;
        this.messages[this.currentAiMessageIndex].renderedContent = renderMarkdown(result);
        this.messages[this.currentAiMessageIndex].endStatus = true;
        
        // Scroll to bottom
        this.throttledScrollToBottom();
        
        return result;
      } catch (error) {
        console.error('调用API失败:', error);
        // If error occurs, ensure empty AI message is removed
        if (this.messages.length > 0 && this.messages[this.messages.length - 1].content === '') {
          this.messages.pop();
          this.currentAiMessageIndex = -1;
        }
        throw error;
      }
    },
    
    // Accept script
    acceptScript(scriptContent) {
      uni.showToast({
        title: '已确认使用此剧本',
        icon: 'success'
      });
      
      // Return to previous page
      uni.navigateBack({
        delta: 1, // Number of pages to go back, 1 means return to previous page
        success: function() {
          // Get page stack
          const pages = getCurrentPages();
          // Previous page instance
          const prevPage = pages[pages.length - 1];
          // Call method on previous page
          if (prevPage && typeof prevPage.getAiDramaTxt === 'function') {
            prevPage.getAiDramaTxt(scriptContent);
          }
        }
      });
    },
    
    // Throttled scroll to bottom function to avoid frequent scrolling
    throttledScrollToBottom() {
      this.$u.throttle(this.scrollToBottom, 300);
    },
    
    // Scroll to bottom
    scrollToBottom() {
      this.$nextTick(() => {
        setTimeout(() => {
          const query = uni.createSelectorQuery().in(this);
          query.select('#scroll-bottom-anchor').boundingClientRect(data => {
            if (data) {
              // Scroll to anchor element position
              uni.pageScrollTo({
                selector: '#scroll-bottom-anchor',
                duration: 100
              });
            }
          }).exec();
        }, 100);
      });
    },
    
    // Load more messages (pull-up loading)
    loadMoreMessages() {
      // Logic for loading history messages can be implemented here
      // Currently not needed, keeping the interface
      this.needScrollToBottom = false; // Disable auto-scrolling when pulling up
      
      // Restore auto-scrolling after loading
      setTimeout(() => {
        this.needScrollToBottom = true;
      }, 1000);
    }
  }
}
</script>

<style lang="scss">
.chat-container {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--window-top));
  position: relative;
}

.chat-content {
  flex: 1;
  background-color: #f5f7fa;
}

.message-wrapper-box{
  padding: 20rpx;
}

.message-wrapper {
  margin-bottom: 40rpx;
}

.message-container {
  display: flex;
  flex-direction: column;
}

.ai-message-container {
  align-items: flex-start;
}

.user-message-container {
  align-items: flex-end;
}

.message {
  max-width: calc(80% - 40rpx);
  padding: 24rpx 30rpx;
  border-radius: 16rpx;
  position: relative;
}

.ai-message {
  background-color: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.user-message {
  background-color: #4e6ef2;
  color: white;
  box-shadow: 0 2px 8px rgba(78, 110, 242, 0.2);
}

.message-content {
  line-height: 1.5;
  word-break: break-word;
}

/* Markdown styles */
.markdown-body {
  color: #333;
}

.message-time {
  font-size: 24rpx;
  color: #909399;
  margin-top: 10rpx;
  padding: 0 10rpx;
}

.user-message-container .message-time {
  color: #909399;
}

/* Input area fixed at the bottom */
.chat-input-container {
  background-color: #fff;
  border-top: 1px solid #ebeef5;
  padding: 20rpx 30rpx;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
  z-index: 100;
  margin-top: auto;
  position: sticky;
  bottom: 0;
}

.chat-input {
  display: flex;
  align-items: flex-end;
}

.bottom-placeholder {
  height: 40rpx; /* Ensure content is not hidden by input box */
}

.accept-button-container {
  margin-bottom: 40rpx;
}

.loading-container {
  display: flex;
  align-items: center;
  justify-content: center;
  color: #909399;
  font-size: 28rpx;
  margin: 20rpx 0;
}

.loading-text {
  margin-left: 16rpx;
}

.button-icon {
  margin-right: 8rpx;
}
</style>

