# 搜索和 Inquire 蓝图
# 处理搜索、Inquire 会话、语义搜索、聊天等相关功能

from flask import Blueprint, request, jsonify, render_template, redirect, flash, Response, current_app
from flask_login import login_required, current_user
import os
import json
import re
from datetime import datetime, timedelta

from src.clients import db
from src.models import (
    User, Tag, RecordingTag, Recording, TranscriptChunk, InquireSession,
    SystemSetting
)
from src.services import (
    call_llm_completion,
    process_streaming_with_thinking,
    semantic_search_chunks,
    auto_login,
)

# 创建搜索蓝图
search_bp = Blueprint('search', __name__)

# 全局变量（从 app.py 导入）
limiter = None
csrf = None
ENABLE_INQUIRE_MODE = None
USE_ASR_ENDPOINT = None

def init_search_bp(limiter_instance, csrf_instance, enable_inquire, use_asr_endpoint):
    """初始化蓝图所需的全局变量"""
    global limiter, csrf, ENABLE_INQUIRE_MODE, USE_ASR_ENDPOINT
    limiter = limiter_instance
    csrf = csrf_instance
    ENABLE_INQUIRE_MODE = enable_inquire
    USE_ASR_ENDPOINT = use_asr_endpoint
    
    # 应用路由级限流（在 init 中应用，避免模块导入时 limiter 为 None）
    # 收件箱查询限流：每分钟最多30次
    search_bp.view_functions['get_inbox_recordings'] = limiter.limit("30 per minute")(get_inbox_recordings)


@search_bp.route('/inquire')
def inquire():
    """Inquire 页面路由"""
    # 如果尚未认证，自动登录
    if not current_user.is_authenticated:
        auto_login()
    
    # 检查询问模式是否启用
    if not ENABLE_INQUIRE_MODE:
        flash('询问模式未在此服务器上启用。', 'warning')
        return redirect('/tool/speakr')
    # 使用用户上下文渲染询问页面以支持主题
    return render_template('inquire.html', use_asr_endpoint=USE_ASR_ENDPOINT, current_user=current_user)


@search_bp.route('/api/inbox_recordings', methods=['GET'])
@login_required
def get_inbox_recordings():
    """获取收件箱中正在处理的录音"""
    try:
        stmt = db.select(Recording).where(
            Recording.user_id == current_user.id,
            Recording.is_inbox == True,
            Recording.status.in_(['PENDING', 'PROCESSING', 'SUMMARIZING'])
        ).order_by(Recording.created_at.desc())
        
        recordings = db.session.execute(stmt).scalars().all()
        return jsonify([recording.to_dict() for recording in recordings])
    except Exception as e:
        current_app.logger.error(f"获取收件箱录音时出错: {e}")
        return jsonify({'error': str(e)}), 500


@search_bp.route('/api/inquire/sessions', methods=['GET'])
@login_required
def get_inquire_sessions():
    """获取当前用户的所有 Inquire 会话"""
    if not ENABLE_INQUIRE_MODE:
        return jsonify({'error': 'Inquire 模式未启用'}), 403
    try:
        sessions = InquireSession.query.filter_by(user_id=current_user.id).order_by(InquireSession.last_used.desc()).all()
        return jsonify([session.to_dict() for session in sessions])
    except Exception as e:
        current_app.logger.error(f"获取 Inquire 会话时出错: {e}")
        return jsonify({'error': str(e)}), 500


@search_bp.route('/api/inquire/sessions', methods=['POST'])
@login_required
def create_inquire_session():
    """创建新的 Inquire 会话并附带筛选条件"""
    if not ENABLE_INQUIRE_MODE:
        return jsonify({'error': 'Inquire 模式未启用'}), 403
    try:
        data = request.json
        if not data:
            return jsonify({'error': '未提供数据'}), 400
        
        session = InquireSession(
            user_id=current_user.id,
            session_name=data.get('session_name'),
            filter_tags=json.dumps(data.get('filter_tags', [])),
            filter_speakers=json.dumps(data.get('filter_speakers', [])),
            filter_date_from=datetime.fromisoformat(data['filter_date_from']).date() if data.get('filter_date_from') else None,
            filter_date_to=datetime.fromisoformat(data['filter_date_to']).date() if data.get('filter_date_to') else None,
            filter_recording_ids=json.dumps(data.get('filter_recording_ids', []))
        )
        
        db.session.add(session)
        db.session.commit()
        
        return jsonify(session.to_dict()), 201
        
    except Exception as e:
        current_app.logger.error(f"创建 Inquire 会话时出错: {e}")
        return jsonify({'error': str(e)}), 500


@search_bp.route('/api/inquire/search', methods=['POST'])
@login_required
def inquire_search():
    """在筛选后的转录内容中执行语义搜索"""
    if not ENABLE_INQUIRE_MODE:
        return jsonify({'error': 'Inquire 模式未启用'}), 403
    try:
        data = request.json
        if not data:
            return jsonify({'error': '未提供数据'}), 400
        
        query = data.get('query')
        if not query:
            return jsonify({'error': '未提供查询'}), 400
        
        # 从请求中构建筛选条件
        filters = {}
        if data.get('filter_tags'):
            filters['tag_ids'] = data['filter_tags']
        if data.get('filter_speakers'):
            filters['speaker_names'] = data['filter_speakers']
        if data.get('filter_recording_ids'):
            filters['recording_ids'] = data['filter_recording_ids']
        if data.get('filter_date_from'):
            filters['date_from'] = datetime.fromisoformat(data['filter_date_from']).date()
        if data.get('filter_date_to'):
            filters['date_to'] = datetime.fromisoformat(data['filter_date_to']).date()
        
        # 执行语义搜索
        top_k = data.get('top_k', 5)
        chunk_results = semantic_search_chunks(current_user.id, query, filters, top_k)
        
        # 格式化结果
        results = []
        for chunk, similarity in chunk_results:
            result = chunk.to_dict()
            result['similarity'] = similarity
            result['recording_title'] = chunk.recording.title
            result['recording_meeting_date'] = f"{chunk.recording.meeting_date.isoformat()}T00:00:00" if chunk.recording.meeting_date else None
            results.append(result)
        
        return jsonify({'results': results})
        
    except Exception as e:
        current_app.logger.error(f"Inquire 搜索时出错: {e}")
        return jsonify({'error': str(e)}), 500


@search_bp.route('/api/inquire/chat', methods=['POST'])
@login_required
def inquire_chat():
    """使用 RAG 与筛选后的转录内容进行聊天"""
    if not ENABLE_INQUIRE_MODE:
        return jsonify({'error': 'Inquire 模式未启用'}), 403
    try:
        data = request.json
        if not data:
            return jsonify({'error': '未提供数据'}), 400
        
        user_message = data.get('message')
        message_history = data.get('message_history', [])
        
        if not user_message:
            return jsonify({'error': '未提供消息'}), 400
        
        # 检查 OpenRouter 客户端是否可用
        from src.clients import client
        if client is None:
            return jsonify({'error': '聊天服务不可用（OpenRouter 客户端未配置）'}), 503
        
        # 从请求中构建筛选条件
        filters = {}
        if data.get('filter_tags'):
            filters['tag_ids'] = data['filter_tags']
        if data.get('filter_speakers'):
            filters['speaker_names'] = data['filter_speakers']
        if data.get('filter_recording_ids'):
            filters['recording_ids'] = data['filter_recording_ids']
        if data.get('filter_date_from'):
            filters['date_from'] = datetime.fromisoformat(data['filter_date_from']).date()
        if data.get('filter_date_to'):
            filters['date_to'] = datetime.fromisoformat(data['filter_date_to']).date()
        
        # 调试日志
        current_app.logger.info(f"Inquire 聊天 - 用户: {current_user.username}, 查询: '{user_message}', 筛选条件: {filters}")
        
        # 在生成器之前捕获用户上下文，避免 current_user 为 None
        user_id = current_user.id
        user_name = current_user.name if current_user.name else "用户"
        user_title = current_user.job_title if current_user.job_title else "专业人士"
        user_company = current_user.company if current_user.company else "其组织"
        user_output_language = current_user.output_language if current_user.output_language else None
        
        # 增强的查询处理与丰富化和调试
        def create_status_response(status, message):
            """辅助函数，用于创建 SSE 状态更新"""
            return f"data: {json.dumps({'status': status, 'message': message})}\n\n"
        
        def generate_enhanced_chat():
            # 显式引用外部作用域变量
            nonlocal user_id, user_name, user_title, user_company, user_output_language, data, filters
            
            try:
                # 发送初始状态
                yield create_status_response('processing', '正在分析您的查询...')
                
                # 步骤 1：路由 - 判断是否需要 RAG 查找
                router_prompt = f"""分析此用户查询，判断是否需要搜索转录内容，还是简单的格式化/澄清请求。

用户查询: "{user_message}"

如果查询需要搜索转录内容（询问对话、录音中的特定信息），仅回复 "RAG"。
如果是格式化请求、关于之前回复的澄清，或不需要搜索转录内容，仅回复 "DIRECT"。

示例:
- "Beth 对预算有什么看法？" → RAG
- "你能用不同的标题格式化吗？" → DIRECT  
- "谁提到了时间表？" → RAG
- "让它更有条理一些" → DIRECT"""

                try:
                    router_response = call_llm_completion(
                        messages=[
                            {"role": "system", "content": "你是查询路由器。仅回复 'RAG' 或 'DIRECT'。"},
                            {"role": "user", "content": router_prompt}
                        ],
                        temperature=0.1,
                        max_tokens=10
                    )
                    
                    route_decision = router_response.choices[0].message.content.strip().upper()
                    current_app.logger.info(f"路由决策: {route_decision}")
                    
                    if route_decision == "DIRECT":
                        # 直接回复，无需 RAG 查找
                        yield create_status_response('responding', '正在生成直接回复...')
                        
                        direct_prompt = f"""你正在协助 {user_name}。使用适当的 markdown 格式回复他们的请求。

用户请求: "{user_message}"

之前的对话上下文（如果相关）:
{json.dumps(message_history[-2:] if message_history else [])}

使用适当的 markdown 格式，包括标题 (##)、粗体 (**文本**)、列表 (-) 等。"""

                        stream = call_llm_completion(
                            messages=[
                                {"role": "system", "content": direct_prompt},
                                {"role": "user", "content": user_message}
                            ],
                            temperature=0.7,
                            max_tokens=int(os.environ.get("CHAT_MAX_TOKENS", "2000")),
                            stream=True
                        )
                        
                        # 使用辅助函数处理流式输出，支持思考标签
                        for response in process_streaming_with_thinking(stream):
                            yield response
                        return
                        
                except Exception as e:
                    current_app.logger.warning(f"路由失败，默认使用 RAG: {e}")
                
                # 步骤 2：查询丰富化 - 根据用户意图生成更好的搜索词
                yield create_status_response('enriching', '正在丰富化搜索查询...')
                
                # 使用捕获的用户上下文生成个性化搜索词
                enrichment_prompt = f"""你是查询增强助手。根据用户关于转录会议/录音的问题，生成 3-5 个替代搜索词或短语，以帮助在语义搜索系统中找到相关内容。

用户上下文:
- 姓名: {user_name}
- 职位: {user_title}  
- 公司: {user_company}

用户问题: "{user_message}"
可用上下文: 转录的会议和录音，说话人: {', '.join(data.get('filter_speakers', []))}。

生成能够找到相关内容的搜索词。重点关注:
1. 使用用户实际姓名的关键概念和主题，而不是"我"等通用词
2. 其专业上下文中可能使用的特定术语
3. 使用正确姓名的问题替代措辞
4. 可能出现在其会议转录中的相关术语

示例:
- 不使用"Beth 告诉我什么"，而是使用"Beth 告诉 {user_name} 什么"
- 不使用"我上次对话"，而是使用"{user_name} 的对话"
- 在相关时使用其职位和公司上下文

仅回复 JSON 数组字符串: ["term1", "term2", "term3", ...]"""
                
                try:
                    enrichment_response = call_llm_completion(
                        messages=[
                            {"role": "system", "content": "你是查询增强助手。仅回复有效的 JSON 字符串数组。"},
                            {"role": "user", "content": enrichment_prompt}
                        ],
                        temperature=0.3,
                        max_tokens=200
                    )
                    
                    enriched_terms = json.loads(enrichment_response.choices[0].message.content.strip())
                    current_app.logger.info(f"丰富化的搜索词: {enriched_terms}")
                    
                    # 将原始查询与丰富化词结合用于搜索
                    search_queries = [user_message] + enriched_terms[:3]  # 使用原始 + 前 3 个丰富化词
                    
                except Exception as e:
                    current_app.logger.warning(f"查询丰富化失败，使用原始查询: {e}")
                    search_queries = [user_message]
                
                # 步骤 2：使用多个查询进行语义搜索
                yield create_status_response('searching', '正在搜索转录内容...')
                
                all_chunks = []
                seen_chunk_ids = set()
                
                for query in search_queries:
                    with current_app.app_context():
                        chunk_results = semantic_search_chunks(user_id, query, filters, 8)
                        current_app.logger.info(f"搜索查询 '{query}' 返回 {len(chunk_results)} 个片段")
                    
                    for chunk, similarity in chunk_results:
                        if chunk and chunk.id not in seen_chunk_ids:
                            all_chunks.append((chunk, similarity))
                            seen_chunk_ids.add(chunk.id)
                
                # 按相似度排序并取前 N 个结果
                all_chunks.sort(key=lambda x: x[1], reverse=True)
                chunk_results = all_chunks[:data.get('context_chunks', 8)]
                
                current_app.logger.info(f"最终片段结果: {len(chunk_results)} 个片段，相似度: {[f'{s:.3f}' for _, s in chunk_results]}")
                
                # 步骤 2.5：自动检测提及的说话人并应用筛选条件（如需要）
                with current_app.app_context():
                    # 获取可用说话人
                    recordings_with_participants = Recording.query.filter_by(user_id=user_id).filter(
                        Recording.participants.isnot(None),
                        Recording.participants != ''
                    ).all()
                    
                    available_speakers = set()
                    for recording in recordings_with_participants:
                        if recording.participants:
                            participants = [p.strip() for p in recording.participants.split(',') if p.strip()]
                            available_speakers.update(participants)
                    
                    # 检查是否有说话人在用户查询中被提及但未出现在结果中
                    mentioned_speakers = []
                    for speaker in available_speakers:
                        if speaker.lower() in user_message.lower():
                            # 检查此说话人是否出现在当前片段结果中
                            speaker_in_results = False
                            for chunk, _ in chunk_results:
                                if chunk and (
                                    (chunk.speaker_name and speaker.lower() in chunk.speaker_name.lower()) or
                                    (chunk.recording and chunk.recording.participants and speaker.lower() in chunk.recording.participants.lower())
                                ):
                                    speaker_in_results = True
                                    break
                            
                            if not speaker_in_results:
                                mentioned_speakers.append(speaker)
                    
                    # 如果发现提及的说话人不在结果中，自动应用说话人筛选条件
                    if mentioned_speakers and not data.get('filter_speakers'):  # 仅在未应用说话人筛选条件时
                        current_app.logger.info(f"自动检测到提及的说话人不在结果中: {mentioned_speakers}")
                        yield create_status_response('filtering', f'检测到提及 {", ".join(mentioned_speakers)}，正在应用说话人筛选条件...')
                        
                        # 应用自动说话人筛选条件
                        auto_filters = filters.copy()
                        auto_filters['speaker_names'] = mentioned_speakers
                        
                        # 使用说话人筛选条件重新运行语义搜索
                        auto_filtered_chunks = []
                        auto_filtered_seen_ids = set()
                        
                        for query in search_queries:
                            with current_app.app_context():
                                auto_filtered_results = semantic_search_chunks(user_id, query, auto_filters, data.get('context_chunks', 8))
                                current_app.logger.info(f"使用说话人 {mentioned_speakers} 的自动筛选搜索 '{query}' 返回 {len(auto_filtered_results)} 个片段")
                            
                            for chunk, similarity in auto_filtered_results:
                                if chunk and chunk.id not in auto_filtered_seen_ids:
                                    auto_filtered_chunks.append((chunk, similarity))
                                    auto_filtered_seen_ids.add(chunk.id)
                        
                        # 如果自动筛选找到更好的结果，使用它们
                        if len(auto_filtered_chunks) > 0:
                            auto_filtered_chunks.sort(key=lambda x: x[1], reverse=True)
                            chunk_results = auto_filtered_chunks[:data.get('context_chunks', 8)]
                            current_app.logger.info(f"自动说话人筛选找到 {len(chunk_results)} 个相关片段，使用筛选结果")
                            filters = auto_filters  # 更新上下文筛选条件
                
                # 步骤 3：评估结果，如需要则重新查询
                if len(chunk_results) < 2:  # 如果结果很少，尝试更广泛的搜索
                    yield create_status_response('requerying', '正在扩大搜索范围...')
                    
                    # 如果应用了说话人筛选条件，尝试不使用
                    broader_filters = filters.copy()
                    if 'speaker_names' in broader_filters:
                        del broader_filters['speaker_names']
                        current_app.logger.info("正在重试搜索，不使用说话人筛选条件...")
                        
                        for query in search_queries:
                            with current_app.app_context():
                                chunk_results_broader = semantic_search_chunks(user_id, query, broader_filters, 6)
                            for chunk, similarity in chunk_results_broader:
                                if chunk and chunk.id not in seen_chunk_ids:
                                    all_chunks.append((chunk, similarity))
                                    seen_chunk_ids.add(chunk.id)
                        
                        # 重新排序并限制
                        all_chunks.sort(key=lambda x: x[1], reverse=True)
                        chunk_results = all_chunks[:data.get('context_chunks', 8)]
                        current_app.logger.info(f"更广泛的搜索返回 {len(chunk_results)} 个片段")
                
                # 从检索到的片段构建上下文
                yield create_status_response('contextualizing', '正在构建上下文...')
                
                # 按录音分组片段并合理组织
                recording_chunks = {}
                recording_ids_in_context = set()
                
                for chunk, similarity in chunk_results:
                    if not chunk or not chunk.recording:
                        continue
                    recording_id = chunk.recording.id
                    recording_ids_in_context.add(recording_id)
                    
                    if recording_id not in recording_chunks:
                        recording_chunks[recording_id] = {
                            'recording': chunk.recording,
                            'chunks': []
                        }
                    
                    recording_chunks[recording_id]['chunks'].append({
                        'chunk': chunk,
                        'similarity': similarity
                    })
                
                # 构建有组织的上下文片段
                context_pieces = []
                
                for recording_id, data in recording_chunks.items():
                    recording = data['recording']
                    chunks = data['chunks']
                    
                    # 按索引排序片段以保持时间顺序
                    chunks.sort(key=lambda x: x['chunk'].chunk_index)
                    
                    # 使用完整元数据构建录音标题
                    header = f"=== {recording.title} [录音 ID: {recording_id}] ==="
                    if recording.meeting_date:
                        header += f" ({recording.meeting_date})"
                    
                    # 添加参与者信息
                    if recording.participants:
                        participants_list = [p.strip() for p in recording.participants.split(',') if p.strip()]
                        header += f"\n参与者: {', '.join(participants_list)}"
                    
                    context_piece = header + "\n\n"
                    
                    # 处理片段并检测非连续性
                    prev_chunk_index = None
                    for chunk_data in chunks:
                        chunk = chunk_data['chunk']
                        similarity = chunk_data['similarity']
                        
                        # 检查非连续性
                        if prev_chunk_index is not None and chunk.chunk_index != prev_chunk_index + 1:
                            context_piece += "\n[... 转录中的间隔 - 非连续片段 ...]\n\n"
                        
                        # 如果可用，添加说话人信息
                        speaker_info = ""
                        if chunk.speaker_name:
                            speaker_info = f"{chunk.speaker_name}: "
                        elif chunk.start_time is not None:
                            speaker_info = f"[{chunk.start_time:.1f}s]: "
                        
                        # 如果可用，添加时间信息
                        timing_info = ""
                        if chunk.start_time is not None and chunk.end_time is not None:
                            timing_info = f" [{chunk.start_time:.1f}s-{chunk.end_time:.1f}s]"
                        
                        context_piece += f"{speaker_info}{chunk.content}{timing_info} (相似度: {similarity:.3f})\n\n"
                        prev_chunk_index = chunk.chunk_index
                    
                    context_pieces.append(context_piece)
                
                current_app.logger.info(f"从 {len(chunk_results)} 个片段（跨 {len(recording_chunks)} 个录音）构建上下文")
                
                # 生成回复
                yield create_status_response('responding', '正在生成回复...')
                
                # 准备系统提示
                language_instruction = f"请使用 {user_output_language} 提供所有回复。" if user_output_language else ""
                
                # 构建筛选条件描述以提供上下文
                filter_description = []
                with current_app.app_context():
                    if data.get('filter_tags'):
                        tag_names = [tag.name for tag in Tag.query.filter(Tag.id.in_(data['filter_tags'])).all()]
                        filter_description.append(f"标签: {', '.join(tag_names)}")
                if data.get('filter_speakers'):
                    filter_description.append(f"说话人: {', '.join(data['filter_speakers'])}")
                if data.get('filter_date_from') or data.get('filter_date_to'):
                    date_range = []
                    if data.get('filter_date_from'):
                        date_range.append(f"从 {data['filter_date_from']}")
                    if data.get('filter_date_to'):
                        date_range.append(f"到 {data['filter_date_to']}")
                    filter_description.append(f"日期: {' '.join(date_range)}")
                
                filter_text = f" (按 {'; '.join(filter_description)} 筛选)" if filter_description else ""
                
                context_text = "\n\n".join(context_pieces) if context_pieces else "未找到相关上下文。"
                
                # 获取转录长度限制设置和可用说话人
                with current_app.app_context():
                    transcript_limit = SystemSetting.get_setting('transcript_length_limit', 30000)
                    
                    # 获取此用户的所有可用说话人
                    recordings_with_participants = Recording.query.filter_by(user_id=user_id).filter(
                        Recording.participants.isnot(None),
                        Recording.participants != ''
                    ).all()
                    
                    available_speakers = set()
                    for recording in recordings_with_participants:
                        if recording.participants:
                            participants = [p.strip() for p in recording.participants.split(',') if p.strip()]
                            available_speakers.update(participants)
                    
                    available_speakers = sorted(list(available_speakers))
                
                system_prompt = f"""你是一名专业的会议和音频转录分析师，协助 {user_name}，他是 {user_company} 的 {user_title}。{language_instruction}

你正在分析来自多个录音的转录内容{filter_text}。以下上下文已根据与用户问题的语义相似性检索到:

<<start context>>
{context_text}
<<end context>>

系统已自动分析你的查询并从转录内容中检索到最相关的上下文。搜索从 {len(recording_ids_in_context)} 个录音返回了 {len(chunk_results)} 个片段。

**录音中的可用说话人**: {', '.join(available_speakers) if available_speakers else '无可用'}

**上下文中的录音 ID**: {list(recording_ids_in_context)}

重要格式说明:
你必须在回复中使用适当的 markdown 格式。按以下方式组织回复:

1. **始终使用 markdown 语法** - 使用 `#`、`##`、`###` 表示标题，`**粗体**`、`*斜体*`、`-` 表示列表等。
2. 以简短的摘要或前言开始（如果有帮助）
3. 使用清晰的 markdown 标题按来源转录组织信息
4. 使用格式: `## [录音标题] - [日期（如果可用）]` 
5. 在每个标题下，使用列表和格式提供来自该特定录音的相关信息
6. 在提及特定陈述时使用 **粗体** 格式包含说话人姓名
7. 使用列表 (`-`) 和子列表清晰地组织信息

**所需结构示例:**
带有 **关键点** 高亮的简短摘要...

## 项目实施会议讨论 - 2024-06-18
- **说话人 A** 提到"实施需要大量支持"
- **说话人 B** 确认了与技术团队的即将举行的会议
- 讨论的关键主题:
  - 预算规划注意事项
  - 时间表协调需求

## 预算规划会议 - 2024-05-30  
- **说话人 A** 审查了预算文档
- **说话人 C** 将批准提交的最终版本
- 重要细节:
  - 预算约占项目总额的 1/3
  - 需要协调即将发生的里程碑

按会议从最近到最早的顺序组织回复。始终使用适当的 markdown 格式，并按来源录音组织以获得最大清晰度和可读性。"""
        
                # 准备消息数组
                messages = [{"role": "system", "content": system_prompt}]
                if message_history:
                    messages.extend(message_history)
                messages.append({"role": "user", "content": user_message})

                # 启用流式输出
                stream = call_llm_completion(
                    messages=messages,
                    temperature=0.7,
                    max_tokens=int(os.environ.get("CHAT_MAX_TOKENS", "2000")),
                    stream=True
                )
                
                # 缓冲内容以检测完整转录请求
                response_buffer = ""
                content_buffer = ""
                in_thinking = False
                thinking_buffer = ""
                
                for chunk in stream:
                    content = chunk.choices[0].delta.content
                    if content:
                        response_buffer += content
                        content_buffer += content
                        
                        # 检查是否是完整转录请求
                        if response_buffer.strip().startswith("REQUEST_FULL_TRANSCRIPT:"):
                            lines = response_buffer.split('\n')
                            request_line = lines[0].strip()
                            
                            if ':' in request_line:
                                try:
                                    recording_id = int(request_line.split(':')[1])
                                    current_app.logger.info(f"代理请求录音 {recording_id} 的完整转录")
                                    
                                    # 获取完整转录
                                    yield create_status_response('fetching', f'正在获取录音 {recording_id} 的完整转录...')
                                    
                                    with current_app.app_context():
                                        recording = db.session.get(Recording, recording_id)
                                        if recording and recording.user_id == user_id and recording.transcription:
                                            # 应用转录长度限制
                                            if transcript_limit == -1:
                                                full_transcript = recording.transcription
                                            else:
                                                full_transcript = recording.transcription[:transcript_limit]
                                            
                                            # 将完整转录添加到上下文
                                            full_context = f"{context_text}\n\n<<完整转录 - {recording.title}>>\n{full_transcript}\n<<结束完整转录>>"
                                            
                                            # 使用完整转录更新系统提示
                                            updated_system_prompt = system_prompt.replace(
                                                f"<<start context>>\n{context_text}\n<<end context>>",
                                                f"<<start context>>\n{full_context}\n<<end context>>"
                                            )
                                            
                                            # 创建带有更新上下文的新消息数组
                                            updated_messages = [{"role": "system", "content": updated_system_prompt}]
                                            if message_history:
                                                updated_messages.extend(message_history)
                                            updated_messages.append({"role": "user", "content": user_message})
                                            
                                            # 使用完整上下文生成新回复
                                            yield create_status_response('responding', '正在分析完整转录...')
                                            
                                            new_stream = call_llm_completion(
                                                messages=updated_messages,
                                                temperature=0.7,
                                                max_tokens=int(os.environ.get("CHAT_MAX_TOKENS", "2000")),
                                                stream=True
                                            )
                                            
                                            # 使用辅助函数处理流式输出，支持思考标签
                                            for response in process_streaming_with_thinking(new_stream):
                                                yield response
                                            return
                                        else:
                                            # 录音未找到或无权限
                                            error_msg = f"\n\n错误: 无法访问录音 {recording_id} 的完整转录。录音可能不存在或你可能没有权限。"
                                            yield f"data: {json.dumps({'delta': error_msg})}\n\n"
                                            yield f"data: {json.dumps({'end_of_stream': True})}\n\n"
                                            return
                                            
                                except (ValueError, IndexError):
                                    current_app.logger.warning(f"无效的转录请求格式: {request_line}")
                                    # 继续正常流式输出
                                    pass
                        
                        # 处理缓冲以检测和处理思考标签
                        while True:
                            if not in_thinking:
                                # 寻找开始思考标签
                                think_start = re.search(r'<think(?:ing)?>', content_buffer, re.IGNORECASE)
                                if think_start:
                                    # 发送思考标签之前的任何内容
                                    before_thinking = content_buffer[:think_start.start()]
                                    if before_thinking:
                                        yield f"data: {json.dumps({'delta': before_thinking})}\n\n"
                                    
                                    # 开始捕获思考内容
                                    in_thinking = True
                                    content_buffer = content_buffer[think_start.end():]
                                    thinking_buffer = ""
                                else:
                                    # 未找到思考标签，发送累积内容
                                    if content_buffer:
                                        yield f"data: {json.dumps({'delta': content_buffer})}\n\n"
                                    content_buffer = ""
                                    break
                            else:
                                # 我们在思考标签内，寻找结束标签
                                think_end = re.search(r'</think(?:ing)?>', content_buffer, re.IGNORECASE)
                                if think_end:
                                    # 捕获思考内容直到结束标签
                                    thinking_buffer += content_buffer[:think_end.start()]
                                    
                                    # 将思考内容作为特殊类型发送
                                    if thinking_buffer.strip():
                                        yield f"data: {json.dumps({'thinking': thinking_buffer.strip()})}\n\n"
                                    
                                    # 在结束标签后继续处理
                                    in_thinking = False
                                    content_buffer = content_buffer[think_end.end():]
                                    thinking_buffer = ""
                                else:
                                    # 仍在思考标签内，累积内容
                                    thinking_buffer += content_buffer
                                    content_buffer = ""
                                    break
                
                # 处理任何剩余内容
                if in_thinking and thinking_buffer:
                    # 未关闭的思考标签 - 作为思考内容发送
                    yield f"data: {json.dumps({'thinking': thinking_buffer.strip()})}\n\n"
                elif content_buffer:
                    # 常规内容
                    yield f"data: {json.dumps({'delta': content_buffer})}\n\n"
                
                yield f"data: {json.dumps({'end_of_stream': True})}\n\n"
                
            except Exception as e:
                current_app.logger.error(f"增强聊天生成时出错: {e}")
                yield f"data: {json.dumps({'error': str(e)})}\n\n"
        
        return Response(generate_enhanced_chat(), mimetype='text/event-stream')
        
    except Exception as e:
        current_app.logger.error(f"Inquire 聊天端点出错: {str(e)}")
        return jsonify({'error': str(e)}), 500


@search_bp.route('/api/inquire/available_filters', methods=['GET'])
@login_required
def get_available_filters():
    """获取用户的可用筛选选项"""
    if not ENABLE_INQUIRE_MODE:
        return jsonify({'error': 'Inquire 模式未启用'}), 403
    try:
        # 获取用户的标签
        tags = Tag.query.filter_by(user_id=current_user.id).all()
        
        # 从用户的录音参与者字段获取唯一说话人
        recordings_with_participants = Recording.query.filter_by(user_id=current_user.id).filter(
            Recording.participants.isnot(None),
            Recording.participants != ''
        ).all()
        
        speaker_names = set()
        for recording in recordings_with_participants:
            if recording.participants:
                # 按逗号分割参与者并清理
                participants = [p.strip() for p in recording.participants.split(',') if p.strip()]
                speaker_names.update(participants)
        
        speaker_names = sorted(list(speaker_names))
        
        # 获取用户的录音用于录音特定筛选
        recordings = Recording.query.filter_by(user_id=current_user.id).filter(
            Recording.status == 'COMPLETED'
        ).order_by(Recording.created_at.desc()).all()
        
        return jsonify({
            'tags': [tag.to_dict() for tag in tags],
            'speakers': speaker_names,
            'recordings': [{'id': r.id, 'title': r.title, 'meeting_date': f"{r.meeting_date.isoformat()}T00:00:00" if r.meeting_date else None} for r in recordings]
        })
        
    except Exception as e:
        current_app.logger.error(f"获取可用筛选条件时出错: {e}")
        return jsonify({'error': str(e)}), 500
