# -*- coding: utf-8 -*-
from flask import Blueprint, render_template, request, redirect, url_for, jsonify, session, g, flash
from app.models.session import update_session_state

bp = Blueprint('wizard', __name__)

def get_category_config(category_id):
    """获取方向配置，如果不存在则返回 None"""
    try:
        from app.models.database.models import CategoryConfig
        return CategoryConfig.query.get(category_id)
    except:
        return None


def get_enabled_categories():
    """获取所有启用的方向"""
    try:
        from app.models.database.models import CategoryConfig
        return CategoryConfig.get_enabled_categories()
    except:
        return []

# ==================== 方向选择页面 ====================

@bp.route('/generate/select-category', methods=['GET'])
def select_category():
    """选择 CTF 方向页面"""
    if not hasattr(g, 'user') or g.user is None:
        flash('请先登录再生成题目', 'warning')
        return redirect(url_for('auth.login', next=url_for('wizard.select_category')))
    
    categories = get_enabled_categories()
    
    # 如果没有配置任何方向，显示默认的 Web 方向
    if not categories:
        # 返回一个默认的 Web 方向供选择
        default_categories = [{
            'id': 'web',
            'name': 'Web',
            'icon': 'globe',
            'description': 'Web 安全漏洞挑战'
        }]
        return render_template(
            'pages/generate/wizard/select_category.html',
            categories=default_categories
        )
    
    return render_template(
        'pages/generate/wizard/select_category.html',
        categories=[c.to_dict(include_config=False) for c in categories]
    )


@bp.route('/generate/wizard/<category_id>', methods=['GET', 'POST'])
def dynamic_wizard(category_id):
    """动态 Wizard 页面 - 根据方向配置渲染"""
    import logging
    logger = logging.getLogger(__name__)
    
    if not hasattr(g, 'user') or g.user is None:
        flash('请先登录再生成题目', 'warning')
        return redirect(url_for('auth.login', next=url_for('wizard.dynamic_wizard', category_id=category_id)))
    
    # 获取方向配置
    category = get_category_config(category_id)
    if not category or not category.enabled:
        flash('该方向未启用或不存在', 'warning')
        return redirect(url_for('wizard.select_category'))
    
    if request.method == 'GET':
        # 清除之前的选择
        session.pop('category_id', None)
        session.pop('form_data', None)
        logger.info(f"开始 {category.name} 方向的生成流程")
    
    if request.method == 'POST':
        # 收集表单数据
        form_data = {}
        form_fields = category.get_form_fields()
        
        logger.debug(f"收到的表单数据: {dict(request.form)}")
        
        for field in form_fields:
            field_id = field.get('id')
            field_type = field.get('type')
            
            if field_type in ['multi_select', 'multi_select_categorized']:
                form_data[field_id] = request.form.getlist(f'{field_id}[]')
            else:
                form_data[field_id] = request.form.get(field_id)
                logger.debug(f"字段 {field_id} ({field_type}): {form_data[field_id]}")
        
        # 获取用户选择的 AI 配置 ID
        ai_config_id = request.form.get('ai_config_id')
        logger.info(f"从表单获取的 ai_config_id: {ai_config_id} (类型: {type(ai_config_id)})")
        logger.info(f"request.form 中的所有键: {list(request.form.keys())}")
        if ai_config_id:
            form_data['ai_config_id'] = ai_config_id
            logger.info(f"用户选择的 AI 配置 ID: {ai_config_id}，已保存到 form_data")
        else:
            logger.warning("表单中未找到 ai_config_id，将使用默认配置")
        
        logger.info(f"收集到的 form_data 键: {list(form_data.keys())}")
        
        # 验证必填字段
        for field in form_fields:
            field_id = field.get('id')
            field_type = field.get('type')
            field_value = form_data.get(field_id)
            
            if field.get('required'):
                # 对于多选字段，检查是否为空列表
                if field_type in ['multi_select', 'multi_select_categorized']:
                    if not field_value or (isinstance(field_value, list) and len(field_value) == 0):
                        error_msg = f"请先完成题目配置：请选择 {field.get('label')}"
                        flash(error_msg, 'warning')
                        return redirect(request.url)
                else:
                    # 对于单选字段，检查是否为空值
                    if not field_value or field_value == '':
                        error_msg = f"请先完成题目配置：请填写 {field.get('label')}"
                        flash(error_msg, 'warning')
                        return redirect(request.url)
        
        # 保存到 session
        session['category_id'] = category_id
        session['form_data'] = form_data
        
        update_session_state('extra_selected')
        
        # 直接重定向到自动启动生成页面（会自动启动生成并跳转到任务详情）
        return redirect(url_for('generate.auto_start'))
    
    # 获取配置数据
    category_config = category.to_dict(include_config=True)
    
    # 清理数据中的控制字符，确保 JSON 序列化安全
    import json
    import re
    
    def clean_for_json(obj):
        """清理对象中的控制字符，确保可以安全序列化为 JSON
        
        移除所有控制字符（包括换行、回车、制表符等），替换为空格并合并
        """
        if isinstance(obj, dict):
            return {k: clean_for_json(v) for k, v in obj.items()}
        elif isinstance(obj, list):
            return [clean_for_json(item) for item in obj]
        elif isinstance(obj, str):
            # 移除所有控制字符（\x00-\x1F 和 \x7F），替换为空格
            # 这包括：NULL, 换行(\n=\x0A), 回车(\r=\x0D), 制表符(\t=\x09) 等
            cleaned = re.sub(r'[\x00-\x1F\x7F]', ' ', obj)
            # 合并多个连续空格为单个空格
            cleaned = re.sub(r' +', ' ', cleaned)
            # 移除首尾空格
            cleaned = cleaned.strip()
            return cleaned
        else:
            return obj
    
    # 清理数据中的控制字符
    form_fields_cleaned = clean_for_json(category_config.get('form_fields', []))
    difficulty_rules_cleaned = clean_for_json(category_config.get('difficulty_rules', []))
    
    # 预先序列化为 JSON 字符串，确保所有控制字符都被正确转义
    # 使用 ensure_ascii=False 保留中文字符，Python 的 json.dumps 会自动转义控制字符
    form_fields_json_str = json.dumps(form_fields_cleaned, ensure_ascii=False, separators=(',', ':'))
    difficulty_rules_json_str = json.dumps(difficulty_rules_cleaned, ensure_ascii=False, separators=(',', ':'))
    
    # 确保 JSON 字符串中不包含 </script> 标签，避免破坏 HTML 结构
    # 将 </script> 替换为转义版本
    form_fields_json_str = form_fields_json_str.replace('</script>', '<\\/script>')
    difficulty_rules_json_str = difficulty_rules_json_str.replace('</script>', '<\\/script>')
    
    return render_template(
        'pages/generate/wizard/dynamic.html',
        category=category_config,
        form_fields=form_fields_cleaned,  # 保留原始对象用于其他用途
        form_fields_json=form_fields_json_str,  # 传递已序列化的 JSON 字符串
        stages=category_config.get('stages', []),
        difficulty_rules=difficulty_rules_cleaned,  # 保留原始对象用于其他用途
        difficulty_rules_json=difficulty_rules_json_str,  # 传递已序列化的 JSON 字符串
        ui_config=category_config.get('ui_config', {})
    )


