# 主页蓝图
# 处理主页、用户配置、文本总结、聊天等杂项路由

from flask import Blueprint, render_template, request, jsonify, current_app, flash, Response, stream_with_context
from flask_login import login_required, current_user, login_user
from src.clients import db
from src.models import User, SystemSetting
from src.services import call_llm_completion, clean_llm_response, format_transcription_for_llm, auto_login
from src.config import SCREEN_PUSH_IP
import os
import requests

# 创建蓝图
main_bp = Blueprint('main', __name__)

# 全局变量
limiter = None
csrf = None
bcrypt = None
USE_ASR_ENDPOINT = None
ASR_DIARIZE = None
ENABLE_INQUIRE_MODE = None
VALID_TOKEN = None


def _chinese_to_pinyin(chinese_text):
    """将汉字转换为拼音"""
    if not chinese_text:
        return ""
    try:
        import pypinyin
        pinyin_list = pypinyin.lazy_pinyin(chinese_text)
        return "".join(pinyin_list)
    except ImportError:
        # 如果 pypinyin 未安装，返回原文本
        return chinese_text


def _screen_push_url(path):
    base = (SCREEN_PUSH_IP or '').strip().rstrip('/')
    if not base:
        raise RuntimeError('SCREEN_PUSH_IP is not configured')
    if not base.startswith(('http://', 'https://')):
        base = f'https://{base}'
    return f"{base}/external/{path.lstrip('/')}"


def _proxy_screen_push(path, stream=False):
    try:
        upstream = _screen_push_url(path)
    except RuntimeError as exc:
        return jsonify({'error': str(exc)}), 503

    try:
        if stream:
            upstream_response = requests.post(
                upstream,
                json=request.get_json(silent=True) or {},
                timeout=(10, 300),
                stream=True,
            )

            def generate():
                with upstream_response:
                    for chunk in upstream_response.iter_content(chunk_size=None):
                        if chunk:
                            yield chunk

            return Response(
                stream_with_context(generate()),
                status=upstream_response.status_code,
                content_type=upstream_response.headers.get('content-type', 'text/plain; charset=utf-8'),
            )

        upstream_response = requests.post(
            upstream,
            json=request.get_json(silent=True) or {},
            timeout=(10, 120),
        )
        return Response(
            upstream_response.content,
            status=upstream_response.status_code,
            content_type=upstream_response.headers.get('content-type', 'application/json'),
        )
    except requests.RequestException as exc:
        current_app.logger.error('投屏推送代理失败 [%s]：%s', path, exc)
        return jsonify({'error': '外部服务不可用'}), 502

def init_main_bp(limiter_instance, csrf_instance, bcrypt_instance, use_asr_endpoint, asr_diarize, enable_inquire_mode=None, valid_token=None):
    """初始化蓝图所需的全局变量"""
    global limiter, csrf, bcrypt, USE_ASR_ENDPOINT, ASR_DIARIZE, ENABLE_INQUIRE_MODE, VALID_TOKEN
    limiter = limiter_instance
    csrf = csrf_instance
    bcrypt = bcrypt_instance
    USE_ASR_ENDPOINT = use_asr_endpoint
    ASR_DIARIZE = asr_diarize
    ENABLE_INQUIRE_MODE = enable_inquire_mode or False
    VALID_TOKEN = valid_token or ''
    
    # 应用路由级限流（在 init 中应用，避免模块导入时 limiter 为 None）
    # 摘要生成限流：每分钟最多10次，防止LLM资源耗尽
    main_bp.view_functions['summarize_text'] = limiter.limit("10 per minute")(summarize_text)
    # 对话限流：每分钟最多10次
    main_bp.view_functions['chat_with_transcription'] = limiter.limit("10 per minute")(chat_with_transcription)

@main_bp.route('/')
def index():
    """主页 - 支持自动登录和 token 验证"""
    # 获取 URL 参数
    uid = request.args.get('uid')
    uname = request.args.get('uname')
    role = request.args.get('role')
    token = request.args.get('token')
    
    # 定义强制登录条件：参数都不为空，且 Token 正确
    should_force_login = uid and uname and role and token and token == VALID_TOKEN
    
    # 如果用户已经登录，直接渲染首页，不进行自动登录
    if current_user.is_authenticated and not should_force_login:
        user_language = current_user.ui_language if current_user.ui_language else 'en'
        return render_template('index.html', 
                             use_asr_endpoint=USE_ASR_ENDPOINT, 
                             inquire_mode_enabled=ENABLE_INQUIRE_MODE,
                             user_language=user_language)

    # Token 无效
    if token and token != VALID_TOKEN:
        flash('无效的访问令牌', 'danger')
        return '''
        <!DOCTYPE html>
        <html>
        <head>
            <title>登录方式不合法</title>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <style>
                body {
                    font-family: Arial, sans-serif;
                    text-align: center;
                    padding: 50px;
                    background-color: #f5f5f5;
                }
                .container {
                    background: white;
                    padding: 40px;
                    border-radius: 10px;
                    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
                    max-width: 500px;
                    margin: 0 auto;
                }
                h1 {
                    color: #ff4444;
                }
                .warning-icon {
                    font-size: 48px;
                    color: #ff4444;
                    margin-bottom: 20px;
                }
                .message {
                    margin: 20px 0;
                    font-size: 18px;
                    color: #333;
                }
                .hint {
                    color: #666;
                    font-size: 14px;
                    margin-top: 20px;
                }
            </style>
        </head>
        <body>
            <div class="container">
                <div class="warning-icon">⚠</div>
                <h1>登录方式不合法</h1>
                <div class="message">请从参谋助手登录</div>
                <div class="hint">请通过正确的入口访问系统</div>
            </div>
        </body>
        </html>
        '''
    
    # 如果有 uid 参数，则进行自动登录/注册
    if uid:
        # 检查用户是否已存在
        user = User.query.filter_by(id=uid).first()
        
        if not user:
            # 用户不存在，注册新用户
            # 生成用户名（将汉字 uname 转换为拼音）
            username = _chinese_to_pinyin(uname) if uname else f"user_{uid[:8]}"
            
            # 确保用户名唯一
            base_username = username
            counter = 1
            while User.query.filter_by(username=username).first():
                username = f"{base_username}_{counter}"
                counter += 1
            
            # 生成密码
            password = "11223344"
            
            # 检查 role 是否包含环境变量中配置的执勤指挥员
            is_admin = False
            if role:
                # 从环境变量读取执勤指挥员配置，支持多个角色用逗号分隔
                duty_commanders = os.environ.get('DUTY_COMMANDER', '执勤指挥员').split(',')
                for duty_commander in duty_commanders:
                    duty_commander = duty_commander.strip()
                    if duty_commander and duty_commander in role:
                        is_admin = True
                        break
            
            # 创建新用户
            user = User(
                id=uid,
                username=username,
                email=f"{username}@auto.local",
                password=bcrypt.generate_password_hash(password).decode('utf-8'),
                is_admin=is_admin,
                name=uname,
                job_title=role,
                transcription_language='zh',
                ui_language='zh',
                output_language='Chinese'
            )
            
            db.session.add(user)
            db.session.commit()
            current_app.logger.info(f"自动注册新用户: {username}, ID: {uid}, 管理员: {is_admin}")
        
        # 登录用户
        login_user(user)
        current_app.logger.info(f"自动登录用户: {user.username}")
    
    # 如果尚未认证，使用原来的自动登录
    elif not current_user.is_authenticated:
        auto_login()
    
    # 将 ASR 配置、询问模式配置和用户语言偏好传递给模板
    user_language = current_user.ui_language if current_user.is_authenticated and current_user.ui_language else 'en'
    return render_template('index.html', 
                         use_asr_endpoint=USE_ASR_ENDPOINT, 
                         inquire_mode_enabled=ENABLE_INQUIRE_MODE,
                         user_language=user_language)

@main_bp.route('/getUserConfig', methods=['GET'])
@login_required
def get_user_config():
    """获取用户配置"""
    return jsonify({
        'username': current_user.username,
        'email': current_user.email,
        'name': current_user.name,
        'job_title': current_user.job_title,
        'company': current_user.company,
        'ui_language': current_user.ui_language,
        'transcription_language': current_user.transcription_language,
        'output_language': current_user.output_language,
        'diarize': current_user.diarize,
        'extract_events': current_user.extract_events,
        'summary_prompt': current_user.summary_prompt,
        'use_asr_endpoint': USE_ASR_ENDPOINT,
        'asr_diarize': ASR_DIARIZE
    })


@main_bp.route('/api/external/summarize_text', methods=['POST'])
@login_required
def proxy_external_summarize_text():
    return _proxy_screen_push('summarize_text')


@main_bp.route('/api/external/submit', methods=['POST'])
@login_required
def proxy_external_submit():
    return _proxy_screen_push('submit')


@main_bp.route('/api/external/prompts/list', methods=['POST'])
@login_required
def proxy_external_prompts_list():
    return _proxy_screen_push('prompts/list')


@main_bp.route('/api/external/recommend_prompts', methods=['POST'])
@login_required
def proxy_external_recommend_prompts():
    return _proxy_screen_push('recommend_prompts')


@main_bp.route('/api/external/summarize_text_stream', methods=['POST'])
@login_required
def proxy_external_summarize_text_stream():
    return _proxy_screen_push('summarize_text_stream', stream=True)

@main_bp.route('/summarize_text', methods=['POST'])
@login_required
def summarize_text():
    """总结文本"""
    data = request.json
    text = data.get('text', '')
    prompt = data.get('prompt', '')
    
    if not text:
        return jsonify({'error': '缺少文本内容'}), 400
    
    # 构建提示词
    if prompt:
        system_prompt = prompt
    else:
        system_prompt = "请对以下内容进行总结，提取关键信息和要点。"
    
    try:
        result = call_llm_completion(
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": text}
            ],
            stream=False
        )
        
        raw_response = result.choices[0].message.content if result and result.choices else ""
        summary = clean_llm_response(raw_response) if raw_response else ""
        return jsonify({'summary': summary})
    except Exception as e:
        current_app.logger.error(f"总结失败: {str(e)}")
        return jsonify({'error': '总结失败，请稍后重试'}), 500

@main_bp.route('/chat', methods=['POST'])
@login_required
def chat_with_transcription():
    """与转录内容聊天"""
    data = request.json
    message = data.get('message', '')
    recording_id = data.get('recording_id')
    
    if not message:
        return jsonify({'error': '缺少消息'}), 400
    
    # 如果有录音ID，获取转录内容作为上下文
    context = ""
    if recording_id:
        from src.models import Recording
        recording = Recording.query.filter_by(id=recording_id, user_id=current_user.id).first()
        if recording and recording.transcription:
            context = recording.transcription
    
    # 构建消息
    messages = []
    if context:
        messages.append({
            "role": "system",
            "content": f"以下是录音转录内容，请基于此回答用户问题：\n\n{context}"
        })
    messages.append({"role": "user", "content": message})
    
    try:
        result = call_llm_completion(messages=messages, stream=False)
        raw_response = result.choices[0].message.content if result and result.choices else ""
        response = clean_llm_response(raw_response) if raw_response else ""
        return jsonify({'response': response})
    except Exception as e:
        current_app.logger.error(f"聊天失败: {str(e)}")
        return jsonify({'error': '聊天失败，请稍后重试'}), 500

@main_bp.route('/docs/transcript-templates-guide')
def transcript_templates_guide():
    """转录模板指南文档"""
    import os
    import markdown
    
    docs_path = os.path.join(current_app.root_path, '..', 'docs', 'transcript-templates-guide.md')
    
    if not os.path.exists(docs_path):
        return "文档不存在", 404
    
    with open(docs_path, 'r', encoding='utf-8') as f:
        content = f.read()
    
    # 转换 Markdown 为 HTML
    html_content = markdown.markdown(content, extensions=['tables', 'fenced_code', 'codehilite'])
    
    # 包装在 HTML 模板中
    html_template = f'''
    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>转录模板指南 - Speakr</title>
        <link rel="stylesheet" href="/static/css/output.css">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
        <style>
            .markdown-body {{
                max-width: 900px;
                margin: 0 auto;
                padding: 2rem;
                line-height: 1.6;
            }}
            .markdown-body h1 {{ font-size: 2.5rem; margin-bottom: 1rem; }}
            .markdown-body h2 {{ font-size: 2rem; margin-top: 2rem; margin-bottom: 1rem; }}
            .markdown-body h3 {{ font-size: 1.5rem; margin-top: 1.5rem; margin-bottom: 0.75rem; }}
            .markdown-body pre {{ background: #f4f4f4; padding: 1rem; border-radius: 0.5rem; overflow-x: auto; }}
            .markdown-body code {{ background: #f4f4f4; padding: 0.2rem 0.4rem; border-radius: 0.25rem; }}
            .markdown-body pre code {{ background: none; padding: 0; }}
            .markdown-body ul, .markdown-body ol {{ margin-left: 2rem; margin-bottom: 1rem; }}
            .markdown-body li {{ margin-bottom: 0.5rem; }}
            .markdown-body blockquote {{ border-left: 4px solid #ddd; padding-left: 1rem; margin: 1rem 0; }}
            .markdown-body table {{ border-collapse: collapse; width: 100%; margin: 1rem 0; }}
            .markdown-body th, .markdown-body td {{ border: 1px solid #ddd; padding: 0.5rem; }}
            .markdown-body th {{ background: #f4f4f4; }}
        </style>
    </head>
    <body class="bg-[var(--bg-primary)]">
        <div class="min-h-screen">
            <div class="bg-[var(--bg-secondary)] border-b border-[var(--border-primary)] p-4">
                <div class="max-w-6xl mx-auto flex items-center justify-between">
                    <a href="/" class="text-2xl font-bold text-[var(--text-primary)]">
                        <i class="fas fa-microphone-alt mr-2"></i>Speakr
                    </a>
                    <a href="/account" class="text-[var(--text-secondary)] hover:text-[var(--text-primary)]">
                        返回账户
                    </a>
                </div>
            </div>
            <div class="markdown-body text-[var(--text-primary)]">
                {html_content}
            </div>
        </div>
    </body>
    </html>
    '''
    
    return html_template
