"""
任务视图模块

提供任务列表和任务详情页面的视图
"""

from flask import Blueprint, render_template, request, redirect, url_for, jsonify, g
from app.services.auth.decorators import login_required
from .tasks import tasks_status, get_user_tasks, get_task, update_task
from .utils import get_generation_status
import datetime

bp_tasks = Blueprint('generate_tasks', __name__)


@bp_tasks.route('/tasks', methods=['GET'])
@login_required
def tasks():
    """任务列表页面"""
    user_id = g.user.id if hasattr(g, 'user') and g.user else None
    if not user_id:
        return redirect(url_for('auth.login'))
    
    # 获取用户的任务（从内存中的任务状态）
    user_tasks = get_user_tasks(str(user_id))
    
    # 同步运行中任务的最新状态（从 generation_statuses）
    for task_id, task in list(user_tasks.items()):  # 使用 list() 避免在迭代时修改字典
        if task.get('status') == 'running':
            task_status = get_generation_status(task_id)
            # 只有当获取到的状态确实是该任务的状态时才同步
            if task_status and task_status.get('task_id') == task_id and task_status.get('generation_started'):
                # 同步最新消息到任务状态（用于显示）
                task['message'] = task_status.get('message', task.get('message', ''))
                # 同时同步回 tasks_status（用于持久化）
                update_task(task_id, 
                           message=task_status.get('message', ''))
    
    # 从数据库读取已完成题目（补充内存中可能丢失的任务）
    try:
        from app.models.database.operations import get_challenges_by_user, get_challenge_record
        db_challenges = get_challenges_by_user(user_id)
        
        # 收集数据库中存在的 challenge_id
        existing_challenge_ids = {challenge.get('id') for challenge in db_challenges if challenge.get('id')}
        
        # 过滤掉那些 challenge_id 在数据库中不存在的任务（题目已被删除）
        user_tasks_to_remove = []
        for task_id, task in user_tasks.items():
            challenge_id = task.get('challenge_id')
            if challenge_id and challenge_id not in existing_challenge_ids:
                # 题目已被删除，从任务列表中移除
                user_tasks_to_remove.append(task_id)
        
        # 移除已删除题目的任务
        for task_id in user_tasks_to_remove:
            user_tasks.pop(task_id, None)
            # 同时从内存中的 tasks_status 删除（可选，但建议保留以备后续可能需要）
            # delete_task(task_id)  # 如果确定要删除，可以取消注释
        
        # 收集内存中已有 challenge_id 的任务
        existing_task_challenge_ids = {
            task.get('challenge_id') 
            for task in user_tasks.values() 
            if task.get('challenge_id')
        }
        
        # 为每个数据库中的题目创建虚拟任务（如果内存中没有）
        for challenge in db_challenges:
            challenge_id = challenge.get('id')
            if challenge_id and challenge_id not in existing_task_challenge_ids:
                # 创建虚拟任务ID（使用 challenge_id 作为标识）
                virtual_task_id = f"challenge-{challenge_id}"
                
                # 如果内存中没有对应的任务，创建虚拟任务
                if virtual_task_id not in user_tasks:
                    # 转换 challenge_type 为 category_id
                    challenge_type = challenge.get('challenge_type', 'web')
                    category_id = challenge_type if challenge_type else 'web'
                    
                    # 解析创建时间
                    created_at = challenge.get('created_at')
                    if isinstance(created_at, str):
                        try:
                            created_at = datetime.datetime.fromisoformat(created_at.replace('Z', '+00:00'))
                        except:
                            created_at = datetime.datetime.now()
                    elif created_at is None:
                        created_at = datetime.datetime.now()
                    
                    # 创建虚拟任务
                    user_tasks[virtual_task_id] = {
                        'user_id': str(user_id),
                        'category_id': category_id,
                        'name': challenge.get('name', '未命名题目'),
                        'status': 'completed',
                        'created_at': created_at,
                        'updated_at': challenge.get('updated_at', created_at),
                        'challenge_id': challenge_id,
                        'output_dir': challenge.get('output_dir'),
                        'log_file': challenge.get('log_file')
                    }
    except Exception as e:
        print(f"从数据库读取题目失败: {str(e)}")
        import traceback
        traceback.print_exc()
    
    # 获取所有方向配置（包括已启用和未启用的，因为可能任务属于未启用方向）
    try:
        from app.models.database.models import CategoryConfig
        all_categories = CategoryConfig.get_all_categories()
        categories_dict = {cat.id: {'name': cat.name, 'icon': cat.icon, 'enabled': cat.enabled, 'sort_order': cat.sort_order} 
                          for cat in all_categories}
    except Exception as e:
        print(f"获取方向配置失败: {str(e)}")
        categories_dict = {}
    
    # 按方向分组任务
    tasks_by_category = {}
    for task_id, task in user_tasks.items():
        category_id = task.get('category_id', 'web')
        if category_id not in tasks_by_category:
            tasks_by_category[category_id] = []
        
        # 按创建时间倒序排列
        tasks_by_category[category_id].append((task_id, task))
    
    # 对每个方向的任务按创建时间排序
    for category_id in tasks_by_category:
        tasks_by_category[category_id].sort(
            key=lambda x: x[1].get('created_at', datetime.datetime.min),
            reverse=True
        )
    
    # 获取所有方向ID，包括有任务的方向和已配置的方向
    all_category_ids = set(tasks_by_category.keys()) | set(categories_dict.keys())
    
    # 按 sort_order 排序方向（有任务的优先显示）
    def get_category_sort_key(cat_id):
        # 优先显示有任务的方向
        has_tasks = cat_id in tasks_by_category and len(tasks_by_category[cat_id]) > 0
        category_info = categories_dict.get(cat_id, {})
        sort_order = category_info.get('sort_order', 999)
        return (not has_tasks, sort_order)  # 有任务的排在前面
    
    sorted_category_ids = sorted(all_category_ids, key=get_category_sort_key)
    
    return render_template('pages/generate/tasks/list.html', 
                         tasks_by_category=tasks_by_category,
                         categories_dict=categories_dict,
                         sorted_category_ids=sorted_category_ids)


@bp_tasks.route('/tasks/<task_id>', methods=['GET'])
@login_required
def task_detail(task_id):
    """任务详情页面"""
    user_id = g.user.id if hasattr(g, 'user') and g.user else None
    if not user_id:
        return redirect(url_for('auth.login'))
    
    # 获取任务信息
    task = get_task(task_id)
    
    # 如果是虚拟任务（从数据库创建的），需要从数据库读取
    if not task and task_id.startswith('challenge-'):
        try:
            challenge_id = int(task_id.replace('challenge-', ''))
            from app.models.database.operations import get_challenge_record
            challenge_data = get_challenge_record(challenge_id)
            
            if challenge_data:
                # 检查权限：题目必须属于当前用户（除非是管理员）
                challenge_user_id = challenge_data.get('user_id')
                if str(challenge_user_id) != str(user_id):
                    if not (hasattr(g, 'user') and g.user and g.user.role in ['admin', 'moderator']):
                        return redirect(url_for('generate_tasks.tasks'))
                
                # 创建虚拟任务对象
                challenge_type = challenge_data.get('challenge_type', 'web')
                category_id = challenge_type if challenge_type else 'web'
                
                created_at = challenge_data.get('created_at')
                if isinstance(created_at, str):
                    try:
                        created_at = datetime.datetime.fromisoformat(created_at.replace('Z', '+00:00'))
                    except:
                        created_at = datetime.datetime.now()
                elif created_at is None:
                    created_at = datetime.datetime.now()
                
                task = {
                    'user_id': str(user_id),
                    'category_id': category_id,
                    'name': challenge_data.get('name', '未命名题目'),
                    'status': 'completed',
                    'created_at': created_at,
                    'updated_at': challenge_data.get('updated_at', created_at),
                    'challenge_id': challenge_id,
                    'output_dir': challenge_data.get('output_dir'),
                    'log_file': challenge_data.get('log_file')
                }
        except Exception as e:
            print(f"从数据库读取题目失败: {str(e)}")
            import traceback
            traceback.print_exc()
    
    if not task:
        return redirect(url_for('generate_tasks.tasks'))
    
    # 检查任务是否属于当前用户（除非是管理员）
    if str(task.get('user_id')) != str(user_id):
        if not (hasattr(g, 'user') and g.user and g.user.role in ['admin', 'moderator']):
            return redirect(url_for('generate_tasks.tasks'))
    
    # 如果任务正在运行，同步最新状态（从 generation_statuses）
    if task.get('status') == 'running':
        task_status = get_generation_status(task_id)
        if task_status and task_status.get('task_id') == task_id:
            # 同步最新消息到任务状态（用于显示）
            task['message'] = task_status.get('message', task.get('message', ''))
            # 同时同步回 tasks_status（用于持久化）
            update_task(task_id, 
                       message=task_status.get('message', ''))
    
    return render_template('pages/generate/tasks/detail.html', task_id=task_id, task=task)

