from flask import Flask, request, Response, jsonify, stream_with_context
import requests
import json
import sseclient
import urllib3
import uuid
import time
from typing import List, Dict, Any

# 禁用 SSL 警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

app = Flask(__name__)

# 认证令牌
HIGHLIGHT_AUTH_TOKEN = "Bearer 此句替换为你的jwt"
HIGHLIGHT_API_URL = "https://chat-backend.highlightai.com/api/v1/chat"

# API 请求头
def get_highlight_headers():
    return {
        "accept": "*/*",
        "accept-encoding": "gzip, deflate, br, zstd",
        "accept-language": "zh-CN",
        "authorization": HIGHLIGHT_AUTH_TOKEN,
        "content-type": "application/json",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Highlight/1.0.22 Chrome/126.0.6478.234 Electron/31.7.3 Safari/537.36",
        "sec-ch-ua": "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"Windows\"",
    }

@app.route('/v1/models', methods=['GET'])
def list_models():
    """返回可用模型列表"""
    return jsonify({
        "object": "list",
        "data": [
            {
                "id": "claude-3-7-sonnet",
                "object": "model",
                "created": 1717027200, 
                "owned_by": "anthropic"
            }
        ]
    })

@app.route('/v1/chat/completions', methods=['POST'])
def chat_completions():
    """处理聊天完成请求"""
    data = request.json
    
    # 提取请求参数
    messages = data.get('messages', [])
    stream = data.get('stream', False)
    
    # 将 OpenAI 格式的消息转换为单个提示
    prompt = format_messages_to_prompt(messages)
    
    # 准备 Highlight 请求
    highlight_data = {
        "prompt": prompt,
        "attachedContext": [{"type": "aboutMe", "text": "[\"\\n\"]"}],
        "additionalTools": [],
        "backendPlugins": []
    }
    
    if stream:
        return stream_response(highlight_data)
    else:
        return non_stream_response(highlight_data)

def format_messages_to_prompt(messages: List[Dict[str, Any]]) -> str:
    """将 OpenAI 格式的消息列表转换为单个提示字符串,保留角色前缀"""
    formatted_messages = []
    
    for message in messages:
        role = message.get('role', '')
        content = message.get('content', '')
        
        if role and content:
            # 保留角色前缀
            formatted_messages.append(f"{role}: {content}")
    
    # 将所有消息连接起来
    return "\n\n".join(formatted_messages)

def stream_response(highlight_data: Dict[str, Any]):
    """处理流式响应"""
    def generate():
        try:
            response = requests.post(
                HIGHLIGHT_API_URL,
                headers=get_highlight_headers(),
                json=highlight_data,
                stream=True,
                verify=False
            )
            
            if response.status_code != 200:
                yield f"data: {json.dumps({'error': {'message': f'Highlight API returned status code {response.status_code}', 'type': 'api_error'}})}\n\n"
                return
            
            client = sseclient.SSEClient(response)
            
            # 为这个响应创建一个唯一ID
            response_id = f"chatcmpl-{str(uuid.uuid4())}"
            created = int(time.time())
            
            # 发送初始 SSE 消息
            yield f"data: {json.dumps({'id': response_id, 'object': 'chat.completion.chunk', 'created': created, 'model': 'claude-3-7-sonnet-20240620', 'choices': [{'index': 0, 'delta': {'role': 'assistant'}, 'finish_reason': None}]})}\n\n"
            
            # 处理 SSE 事件
            for event in client.events():
                event_data = json.loads(event.data)
                
                if event_data.get("type") == "text":
                    content = event_data.get("content", "")
                    if content:
                        chunk = {
                            'id': response_id,
                            'object': 'chat.completion.chunk',
                            'created': created,
                            'model': 'claude-3-7-sonnet',
                            'choices': [
                                {
                                    'index': 0,
                                    'delta': {'content': content},
                                    'finish_reason': None
                                }
                            ]
                        }
                        yield f"data: {json.dumps(chunk)}\n\n"
            
            # 发送完成信息
            yield f"data: {json.dumps({'id': response_id, 'object': 'chat.completion.chunk', 'created': created, 'model': 'claude-3-7-sonnet-20240620', 'choices': [{'index': 0, 'delta': {}, 'finish_reason': 'stop'}]})}\n\n"
            yield "data: [DONE]\n\n"
            
        except Exception as e:
            yield f"data: {json.dumps({'error': {'message': str(e), 'type': 'server_error'}})}\n\n"
    
    return Response(stream_with_context(generate()), mimetype='text/event-stream')

def non_stream_response(highlight_data: Dict[str, Any]):
    """处理非流式响应"""
    try:
        response = requests.post(
            HIGHLIGHT_API_URL,
            headers=get_highlight_headers(),
            json=highlight_data,
            stream=True,
            verify=False
        )
        
        if response.status_code != 200:
            return jsonify({
                'error': {
                    'message': f'Highlight API returned status code {response.status_code}',
                    'type': 'api_error'
                }
            }), response.status_code
        
        client = sseclient.SSEClient(response)
        
        # 收集完整响应
        full_response = ""
        for event in client.events():
            event_data = json.loads(event.data)
            if event_data.get("type") == "text":
                full_response += event_data.get("content", "")
        
        # 创建 OpenAI 格式的响应
        response_id = f"chatcmpl-{str(uuid.uuid4())}"
        created = int(time.time())
        
        return jsonify({
            'id': response_id,
            'object': 'chat.completion',
            'created': created,
            'model': 'claude-3-7-sonnet',
            'choices': [
                {
                    'index': 0,
                    'message': {
                        'role': 'assistant',
                        'content': full_response
                    },
                    'finish_reason': 'stop'
                }
            ],
            'usage': {
                'prompt_tokens': -1,  
                'completion_tokens': -1,  
                'total_tokens': -1  
            }
        })
        
    except Exception as e:
        return jsonify({
            'error': {
                'message': str(e),
                'type': 'server_error'
            }
        }), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080, debug=False)