# Copyright (c) 2025, JINGROW and contributors
# For license information, please see license.txt

"""
钩子执行器 - 基于现有消息队列的钩子执行系统
"""

import json
import logging
import uuid
import dramatiq
from typing import Dict, Any
from jingrow.services.local_job_manager import local_job_manager
from jingrow.utils.jingrow_api import get_logged_user

logger = logging.getLogger(__name__)

@dramatiq.actor(max_retries=3, time_limit=30_000)
def execute_hook_task(hook_data: str) -> None:
    """执行钩子任务"""
    try:
        data = json.loads(hook_data)
        pagetype = data.get('pagetype')
        name = data.get('name')
        hook_name = data.get('hook_name')
        hook_args = data.get('data', {})
        
        if not all([pagetype, name, hook_name]):
            logger.error(f"钩子任务参数不完整: {data}")
            return
        
        logger.info(f"开始执行钩子任务: {pagetype}.{name}.{hook_name}")
        
        # 更新任务状态为执行中
        job_id = data.get('job_id', str(uuid.uuid4()))
        local_job_manager.update_job(job_id, {
            'status': 'started',
            'started_at': __import__('datetime').datetime.now().isoformat()
        })
        
        # 获取Page对象并执行钩子
        import jingrow
        pg = jingrow.get_pg(pagetype, name)
        
        if pg and hasattr(pg, hook_name):
            hook_func = getattr(pg, hook_name)
            if callable(hook_func):
                # 执行钩子函数
                result = hook_func(**hook_args)
                
                # 更新任务状态为完成
                local_job_manager.update_job(job_id, {
                    'status': 'finished',
                    'ended_at': __import__('datetime').datetime.now().isoformat(),
                    'result': str(result) if result is not None else 'None'
                })
                
                logger.info(f"钩子执行成功: {pagetype}.{name}.{hook_name}")
            else:
                logger.warning(f"钩子函数不可调用: {pagetype}.{name}.{hook_name}")
                local_job_manager.update_job(job_id, {
                    'status': 'failed',
                    'ended_at': __import__('datetime').datetime.now().isoformat(),
                    'exc_info': f"钩子函数不可调用: {hook_name}"
                })
        else:
            logger.warning(f"钩子函数不存在: {pagetype}.{name}.{hook_name}")
            local_job_manager.update_job(job_id, {
                'status': 'failed',
                'ended_at': __import__('datetime').datetime.now().isoformat(),
                'exc_info': f"钩子函数不存在: {hook_name}"
            })
            
    except Exception as e:
        logger.error(f"执行钩子任务失败: {e}")
        job_id = data.get('job_id', 'unknown')
        local_job_manager.update_job(job_id, {
            'status': 'failed',
            'ended_at': __import__('datetime').datetime.now().isoformat(),
            'exc_info': str(e)
        })

def create_hook_task(pagetype: str, name: str, hook_name: str, data: Dict[str, Any] = None, session_cookie: str = None) -> str:
    """创建钩子任务"""
    try:
        # 生成任务ID
        job_id = str(uuid.uuid4())
        
        # 构建任务数据
        task_data = {
            'job_id': job_id,
            'pagetype': pagetype,
            'name': name,
            'hook_name': hook_name,
            'data': data or {},
            'session_cookie': session_cookie
        }
        
        # 获取当前用户
        creator = get_logged_user(session_cookie) or 'system'
        
        # 创建本地任务记录
        local_job_manager.create_job({
            'job_id': job_id,
            'target_type': 'hook',
            'pagetype': pagetype,
            'name': name,
            'hook_name': hook_name,
            'status': 'queued',
            'queue': 'default',
            'job_name': f"Hook: {pagetype}.{name}.{hook_name}",
            'arguments': json.dumps(task_data, indent=2, ensure_ascii=False),
            'owner': creator,
            'modified_by': creator
        })
        
        # 发送到消息队列
        execute_hook_task.send(json.dumps(task_data))
        
        logger.info(f"钩子任务已创建: {job_id} - {pagetype}.{name}.{hook_name}")
        return job_id
        
    except Exception as e:
        logger.error(f"创建钩子任务失败: {e}")
        return None

def execute_hook_sync(pagetype: str, name: str, hook_name: str, data: Dict[str, Any] = None) -> bool:
    """同步执行钩子函数"""
    try:
        import jingrow
        
        # 对于新记录创建，记录可能还不存在，需要特殊处理
        if hook_name == "before_insert":
            logger.warning(f"跳过 before_insert 钩子，因为记录 {pagetype}.{name} 还不存在")
            return False
            
        pg = jingrow.get_pg(pagetype, name)
        
        if pg and hasattr(pg, hook_name):
            hook_func = getattr(pg, hook_name)
            if callable(hook_func):
                logger.info(f"同步执行钩子: {pagetype}.{name}.{hook_name}")
                hook_func(**(data or {}))
                return True
        
        logger.warning(f"钩子函数不存在或不可调用: {pagetype}.{name}.{hook_name}")
        return False
        
    except Exception as e:
        logger.error(f"同步执行钩子失败: {e}")
        return False
