#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
外部任务记录服务模块
提供外部任务记录相关的服务方法
"""

import json
import uuid
from typing import Dict, List, Any, Optional
from sqlalchemy import select, and_, or_
import datetime

from data.models.external_task_record import VWEDExternalTaskRecord, ExternalTaskTypeEnum, ExternalTaskStatusEnum
from data.session import get_async_session
from utils.logger import get_logger

# 设置日志
logger = get_logger("service.external_task_record_service")

class ExternalTaskRecordService:
    """
    外部任务记录服务类
    提供与外部任务记录相关的方法
    """
    
    @staticmethod
    async def create_new_task_record(
        req_code: str,
        source_id: str,
        target_id: str,
        business_task_type: str,
        template_id: str,
        request_params: Dict[str, Any],
        client_ip: str = None,
        client_info: str = None
    ) -> VWEDExternalTaskRecord:
        """
        创建newTask任务记录
        
        Args:
            req_code: 请求标识码
            source_id: 来源ID
            target_id: 目标ID
            business_task_type: 业务任务类型
            template_id: 任务模板ID
            request_params: 请求参数
            client_ip: 客户端IP
            client_info: 客户端信息
            
        Returns:
            VWEDExternalTaskRecord: 创建的外部任务记录
        """
        try:
            async with get_async_session() as session:
                # 生成唯一ID
                record_id = str(uuid.uuid4())
                
                # 创建外部任务记录
                external_record = VWEDExternalTaskRecord(
                    id=record_id,
                    req_code=req_code,
                    task_type=ExternalTaskTypeEnum.NEW_TASK,
                    task_status=ExternalTaskStatusEnum.PENDING,
                    source_id=source_id,
                    target_id=target_id,
                    business_task_type=business_task_type,
                    template_id=template_id,
                    request_params=json.dumps(request_params, ensure_ascii=False),
                    client_ip=client_ip,
                    client_info=client_info,
                    start_time=datetime.datetime.now()
                )
                
                session.add(external_record)
                await session.commit()
                await session.refresh(external_record)
                
                logger.info(f"创建newTask任务记录成功: record_id={record_id}, req_code={req_code}")
                return external_record
                
        except Exception as e:
            logger.error(f"创建newTask任务记录失败: {str(e)}, req_code={req_code}")
            raise
    
    @staticmethod
    async def create_agv_scheduling_task_record(
        req_code: str,
        task_code: str,
        business_task_type: str,
        security_key: str,
        type_field: str,
        sub_type: str,
        area_position_code: str,
        area_position_name: str,
        position_code_path: List[Dict[str, Any]],
        template_id: str,
        request_params: Dict[str, Any],
        client_code: str = None,
        token_code: str = None,
        client_ip: str = None,
        client_info: str = None,
        related_req_code: str = None
    ) -> VWEDExternalTaskRecord:
        """
        创建GenAgvSchedulingTask任务记录
        
        Args:
            req_code: 请求标识码
            task_code: 任务代码
            business_task_type: 业务任务类型
            security_key: 安全密钥
            type_field: 类型字段
            sub_type: 子类型
            area_position_code: 区域位置代码
            area_position_name: 区域位置名称
            position_code_path: 位置代码路径
            template_id: 任务模板ID
            request_params: 请求参数
            client_code: 客户端代码
            token_code: 令牌代码
            client_ip: 客户端IP
            client_info: 客户端信息
            related_req_code: 关联的ReqCode
            
        Returns:
            VWEDExternalTaskRecord: 创建的外部任务记录
        """
        try:
            async with get_async_session() as session:
                # 生成唯一ID
                record_id = str(uuid.uuid4())
                
                # 创建外部任务记录
                external_record = VWEDExternalTaskRecord(
                    id=record_id,
                    req_code=req_code,
                    task_type=ExternalTaskTypeEnum.GEN_AGV_SCHEDULING_TASK,
                    task_status=ExternalTaskStatusEnum.PENDING,
                    task_code=task_code,
                    business_task_type=business_task_type,
                    security_key=security_key,
                    type_field=type_field,
                    sub_type=sub_type,
                    area_position_code=area_position_code,
                    area_position_name=area_position_name,
                    position_code_path=json.dumps(position_code_path, ensure_ascii=False),
                    client_code=client_code,
                    token_code=token_code,
                    template_id=template_id,
                    request_params=json.dumps(request_params, ensure_ascii=False),
                    client_ip=client_ip,
                    client_info=client_info,
                    related_req_code=related_req_code,
                    start_time=datetime.datetime.now()
                )
                
                session.add(external_record)
                await session.commit()
                await session.refresh(external_record)
                
                logger.info(f"创建GenAgvSchedulingTask任务记录成功: record_id={record_id}, req_code={req_code}, task_code={task_code}")
                return external_record
                
        except Exception as e:
            logger.error(f"创建GenAgvSchedulingTask任务记录失败: {str(e)}, req_code={req_code}")
            raise
    
    @staticmethod
    async def update_task_record_status(
        req_code: str,
        task_status: ExternalTaskStatusEnum,
        task_record_id: str = None,
        response_code: int = None,
        response_message: str = None,
        response_row_count: int = None,
        response_data: Dict[str, Any] = None,
        error_message: str = None,
        error_stack: str = None
    ) -> bool:
        """
        更新外部任务记录状态
        
        Args:
            req_code: 请求标识码
            task_status: 任务状态
            task_record_id: 内部任务记录ID
            response_code: 响应状态码
            response_message: 响应消息
            response_row_count: 响应行数
            response_data: 响应数据
            error_message: 错误信息
            error_stack: 错误堆栈
            
        Returns:
            bool: 更新是否成功
        """
        try:
            async with get_async_session() as session:
                # 查询外部任务记录
                query = select(VWEDExternalTaskRecord).where(
                    VWEDExternalTaskRecord.id == req_code
                )
                result = await session.execute(query)
                external_record = result.scalar_one_or_none()
                
                if not external_record:
                    logger.error(f"外部任务记录不存在: req_code={req_code}")
                    return False
                # 更新状态和相关信息
                response_data_json = None
                if response_data:
                    try:
                        response_data_json = json.dumps(response_data, ensure_ascii=False, default=str)
                    except Exception as e:
                        # logger.warning(f"序列化response_data失败: {str(e)}")
                        response_data_json = str(response_data)
                external_record.update_status(task_status, error_message, response_data_json)
                
                if task_record_id:
                    external_record.task_record_id = task_record_id
                if response_code is not None:
                    external_record.response_code = response_code
                if response_message:
                    external_record.response_message = json.dumps(response_message, ensure_ascii=False)
                if response_row_count is not None:
                    external_record.response_row_count = response_row_count
                if error_stack:
                    external_record.error_stack = error_stack
                
                await session.commit()
                
                logger.info(f"更新外部任务记录状态成功: req_code={req_code}, status={task_status}")
                return True
                
        except Exception as e:
            logger.error(f"更新外部任务记录状态失败: {str(e)}, req_code={req_code}")
            return False
    
    @staticmethod
    async def get_external_task_record(req_code: str) -> Optional[VWEDExternalTaskRecord]:
        """
        根据ReqCode获取外部任务记录
        
        Args:
            req_code: 请求标识码
            
        Returns:
            Optional[VWEDExternalTaskRecord]: 外部任务记录或None
        """
        try:
            async with get_async_session() as session:
                query = select(VWEDExternalTaskRecord).where(
                    VWEDExternalTaskRecord.req_code == req_code
                ).order_by(VWEDExternalTaskRecord.created_at.desc()).limit(1)
                result = await session.execute(query)
                return result.scalar_one_or_none()
                
        except Exception as e:
            logger.error(f"获取外部任务记录失败: {str(e)}, req_code={req_code}")
            return None
    
    @staticmethod
    async def get_related_tasks(req_code: str) -> List[VWEDExternalTaskRecord]:
        """
        获取关联的任务记录（通过req_code和related_req_code关联）
        
        Args:
            req_code: 请求标识码
            
        Returns:
            List[VWEDExternalTaskRecord]: 关联的任务记录列表
        """
        try:
            async with get_async_session() as session:
                query = select(VWEDExternalTaskRecord).where(
                    or_(
                        VWEDExternalTaskRecord.req_code == req_code,
                        VWEDExternalTaskRecord.related_req_code == req_code
                    )
                )
                result = await session.execute(query)
                return result.scalars().all()
                
        except Exception as e:
            logger.error(f"获取关联任务记录失败: {str(e)}, req_code={req_code}")
            return []
    
    @staticmethod
    async def get_task_records_by_task_code(task_code: str) -> List[VWEDExternalTaskRecord]:
        """
        根据TaskCode获取任务记录
        
        Args:
            task_code: 任务代码
            
        Returns:
            List[VWEDExternalTaskRecord]: 任务记录列表
        """
        try:
            async with get_async_session() as session:
                query = select(VWEDExternalTaskRecord).where(
                    VWEDExternalTaskRecord.req_code == task_code
                )
                result = await session.execute(query)
                return result.scalars().all()
                
        except Exception as e:
            logger.error(f"根据TaskCode获取任务记录失败: {str(e)}, task_code={task_code}")
            return []
    
    @staticmethod
    async def check_task_completion_status(task_record_id: str) -> Optional[Dict[str, Any]]:
        """
        检查任务是否完成（通过内部任务记录ID查询）
        
        Args:
            task_record_id: 内部任务记录ID
            
        Returns:
            Optional[Dict[str, Any]]: 任务状态信息或None
        """
        try:
            # 这里需要查询内部任务记录表来获取任务状态
            # 可以根据实际需求实现具体的查询逻辑
            from data.models.taskrecord import VWEDTaskRecord
            
            async with get_async_session() as session:
                query = select(VWEDTaskRecord).where(
                    VWEDTaskRecord.id == task_record_id
                )
                result = await session.execute(query)
                task_record = result.scalar_one_or_none()
                
                if not task_record:
                    return None
                
                return {
                    "task_record_id": task_record_id,
                    "status": task_record.status,
                    "ended_on": task_record.ended_on,
                    "ended_reason": task_record.ended_reason,
                    "state_description": task_record.state_description
                }
                
        except Exception as e:
            logger.error(f"检查任务完成状态失败: {str(e)}, task_record_id={task_record_id}")
            return None