"""
生成结果视图

提供题目结果页面的渲染
"""
from flask import Blueprint, render_template, redirect, url_for, request, flash, g
from app.services.auth.decorators import login_required
from app.routes.common import get_challenge_and_output_dir
from pathlib import Path
import traceback

bp_result_views = Blueprint('generate_result', __name__)


def _extract_info_from_writeup(writeup):
    """从 writeup 中提取基本信息"""
    info = {
        'name': '未命名题目',
        'description': '',
        'difficulty': '中等',
        'flag_format': '',
        'estimated_time': '1-2小时'
    }

    if not writeup:
        return info

    import re
    lines = writeup.split('\n')

    # 提取题目名称（第一个 # 标题）
    for line in lines:
        if line.startswith('# '):
            title = line[2:].strip()
            # 移除常见后缀
            title = re.sub(r'\s*-\s*[Ww]riteup\s*$', '', title)
            title = re.sub(r'\s*的?解题思路\s*$', '', title)
            if title:
                info['name'] = title
                break

    # 查找题目信息表格
    for i, line in enumerate(lines):
        if '题目名' in line and '题目描述' in line and '|' in line:
            if i + 2 < len(lines):
                data_line = lines[i + 2]
                parts = [p.strip() for p in data_line.split('|')]
                parts = [p for p in parts if p]

                if len(parts) >= 4:
                    if parts[0] and not parts[0].startswith(':'):
                        info['name'] = parts[0]
                    if parts[1] and not parts[1].startswith(':'):
                        info['description'] = parts[1]
                    if len(parts) > 3 and parts[3] and not parts[3].startswith(':'):
                        info['estimated_time'] = parts[3]
                    if len(parts) > 4 and parts[4] and not parts[4].startswith(':'):
                        info['difficulty'] = parts[4]
            break

    # 如果表格中没有难度字段，根据知识点数量推测
    if info['difficulty'] == '中等':
        knowledge_count = 0
        in_knowledge_section = False
        for line in lines:
            if line.strip().startswith('## 知识点'):
                in_knowledge_section = True
                continue
            if in_knowledge_section and line.strip().startswith('##'):
                in_knowledge_section = False
            if in_knowledge_section and line.strip().startswith(('1.', '2.', '3.', '4.', '5.', '6.', '7.', '8.', '9.')):
                knowledge_count += 1

        if knowledge_count <= 2:
            info['difficulty'] = '简单'
        elif knowledge_count <= 4:
            info['difficulty'] = '中等'
        else:
            info['difficulty'] = '困难'

    # 查找 FLAG 类型
    for line in lines:
        if 'flag' in line.lower() or 'FLAG' in line:
            if '动态' in line:
                info['flag_format'] = 'DASCTF{dynamic_flag}'
            elif '静态' in line:
                info['flag_format'] = 'DASCTF{static_flag}'

    return info


@bp_result_views.route('/', methods=['GET'])
@bp_result_views.route('/result', methods=['GET'])
@login_required
def index():
    """显示生成结果"""
    try:
        import logging
        logger = logging.getLogger(__name__)
        logger.info("显示生成结果")

        # 获取题目ID参数
        challenge_id = request.args.get('challenge_id')
        logger.debug(f"接收到的 challenge_id 参数: {challenge_id}")

        # 使用公共函数获取题目数据和输出目录
        challenge_data, output_dir, category_id = get_challenge_and_output_dir(challenge_id)
        if challenge_data is None:
            flash('未找到题目数据', 'error')
            return redirect(url_for('generate_tasks.tasks'))

        # 获取方向配置（用于UI定制）
        category_config = None
        try:
            from app.models.database.models import CategoryConfig
            category = CategoryConfig.query.get(category_id)
            if category:
                category_config = {
                    'id': category.id,
                    'name': category.name,
                    'icon': category.icon or 'folder'
                }
        except Exception as e:
            print(f"获取方向配置失败: {e}")

        # 从 writeup.md 中提取基本信息
        writeup = ''
        writeup_file = Path(output_dir) / 'writeup.md'
        if writeup_file.exists():
            try:
                with open(writeup_file, 'r', encoding='utf-8') as f:
                    writeup = f.read()
            except Exception as e:
                print(f"读取writeup失败: {e}")

        # 从文件夹名中提取题目名
        challenge_name = '未命名题目'
        import re
        output_path = Path(output_dir)
        folder_name = output_path.name
        name_match = re.match(r'^\d{8}_\d{6}_(.+)$', folder_name)
        if name_match:
            challenge_name = name_match.group(1)
        else:
            challenge_name = folder_name

        # 获取难度信息
        difficulty = '未设置'
        challenge_id_int = challenge_data.get('id')
        if challenge_id_int:
            try:
                from app.routes.generator.tasks import tasks_status, _tasks_lock
                with _tasks_lock:
                    for task_id, task in tasks_status.items():
                        if task.get('challenge_id') == challenge_id_int:
                            difficulty = task.get('difficulty', '未设置')
                            if difficulty and difficulty != '未设置':
                                break
            except ImportError:
                pass

        # 如果从任务记录中找不到，尝试从 writeup 中提取
        if difficulty == '未设置':
            challenge_info = _extract_info_from_writeup(writeup)
            difficulty = challenge_info.get('difficulty', '未设置')

        # 获取时间戳
        generation_time = challenge_data.get('timestamp')
        if not generation_time and challenge_data.get('created_at'):
            if isinstance(challenge_data.get('created_at'), str):
                generation_time = challenge_data.get('created_at')
            else:
                generation_time = challenge_data.get('created_at').isoformat() if hasattr(challenge_data.get('created_at'), 'isoformat') else str(challenge_data.get('created_at'))
        if not generation_time:
            generation_time = '未知时间'

        # 获取出题人信息
        author_info = None
        user_id = challenge_data.get('user_id')
        if user_id:
            try:
                from app.models.database.models import User
                author = User.query.get(user_id)
                if author:
                    author_info = {
                        'id': author.id,
                        'username': author.username
                    }
            except Exception as e:
                print(f"获取出题人信息失败: {e}")

        # 构建简化的 challenge_info
        challenge_info = {
            'name': challenge_name,
            'difficulty': difficulty,
            'description': challenge_data.get('description', ''),
            'estimated_time': challenge_data.get('estimated_time', '')
        }
        
        # 获取部署能力状态
        deployable = challenge_data.get('deployable')

        return render_template(
            'pages/generate/result/index.html',
            challenge_id=challenge_data.get('id'),
            challenge_info=challenge_info,
            generation_time=generation_time,
            author_info=author_info,
            category_id=category_id,
            category_config=category_config,
            core_functions=[],
            code_files={},
            deployable=deployable
        )

    except Exception as e:
        error_msg = f"显示结果页面时发生错误: {str(e)}"
        print(error_msg)
        traceback.print_exc()
        flash(error_msg, 'error')
        return redirect(url_for('generate_tasks.tasks'))


@bp_result_views.route('/view-log', methods=['GET'])
@login_required
def view_log():
    """查看题目生成日志"""
    try:
        print("\n=== 查看题目生成日志 ===")

        challenge_id = request.args.get('challenge_id')
        if not challenge_id:
            flash('缺少题目ID参数', 'error')
            return redirect(url_for('auth.profile'))

        import logging
        logger = logging.getLogger(__name__)
        logger.debug(f"接收到的 challenge_id 参数: {challenge_id}")

        # 使用公共函数获取题目数据
        challenge_data, output_dir, category_id = get_challenge_and_output_dir(challenge_id)
        if challenge_data is None:
            flash('未找到题目数据', 'error')
            return redirect(url_for('auth.profile'))

        # 获取日志文件路径
        log_file = challenge_data.get('log_file')
        if not log_file:
            flash('该题目没有生成日志', 'warning')
            return redirect(url_for('auth.profile'))

        print(f"日志文件路径: {log_file}")

        # 检查日志文件是否存在
        log_path = Path(log_file)
        if not log_path.exists():
            flash(f'日志文件不存在: {log_file}', 'error')
            return redirect(url_for('auth.profile'))

        # 读取日志内容
        try:
            with open(log_path, 'r', encoding='utf-8') as f:
                log_content = f.read()
        except Exception as e:
            print(f"读取日志文件失败: {e}")
            flash(f'读取日志文件失败: {str(e)}', 'error')
            return redirect(url_for('auth.profile'))

        # 获取题目名称和文件大小
        challenge_name = challenge_data.get('name', '未命名题目')
        file_size = log_path.stat().st_size

        # 格式化文件大小
        if file_size < 1024:
            file_size_str = f"{file_size} B"
        elif file_size < 1024 * 1024:
            file_size_str = f"{file_size / 1024:.2f} KB"
        else:
            file_size_str = f"{file_size / (1024 * 1024):.2f} MB"

        # 统计行数
        line_count = log_content.count('\n') + 1

        # 渲染日志查看页面
        return render_template('pages/generate/log/view.html',
                             challenge_id=challenge_id,
                             challenge_name=challenge_name,
                             log_content=log_content,
                             log_file=log_file,
                             file_size=file_size_str,
                             line_count=line_count)

    except Exception as e:
        print(f"查看日志时出错: {str(e)}")
        traceback.print_exc()
        flash(f'查看日志时出错: {str(e)}', 'error')
        return redirect(url_for('auth.profile'))
