"""
HTTP请求组件类
提供 GET请求组件和POST请求组件
"""
import logging
from typing import Dict, Any
from services.execution.task_context import TaskContext
from .base import BlockHandler, register_handler
from utils.logger import get_logger
from .model.block_name import HttpRequestBlockName
# 获取日志记录器
logger = get_logger("services.execution.handlers.htttp_request")


@register_handler(HttpRequestBlockName.GET)
class HttpGetBlockHandler(BlockHandler):
    """HTTP GET请求处理器"""

    async def execute(
            self,
            block: Dict[str, Any],
            input_params: Dict[str, Any],
            context: TaskContext
    ) -> Dict[str, Any]:
        """执行HTTP GET请求"""
        import aiohttp
        import asyncio
        import json

        try:
            # 获取请求参数
            url = input_params.get("url")

            # 处理headers参数
            headers = {}
            header_param = input_params.get("header", {})

            # 如果header是字符串，尝试解析JSON
            if isinstance(header_param, str):
                try:
                    header_data = json.loads(header_param)
                    # 检查解析后的数据是否为列表格式 [{"key0":"value0", "value0":"value"}, ...]
                    if isinstance(header_data, list):
                        for item in header_data:
                            # 寻找以key开头的键，如key0, key1等
                            for key in [k for k in item if k.startswith('key')]:
                                if key in item and item[key]:
                                    # 对应的value键应该是value0, value1等
                                    value_key = 'value' + key[3:]
                                    if value_key in item and item[value_key]:
                                        headers[item[key]] = item[value_key]
                    # 如果是字典格式，直接使用
                    elif isinstance(header_data, dict):
                        headers = header_data
                except json.JSONDecodeError:
                    # logger.warning(f"无法解析headers JSON: {header_param}")\
                    pass
            elif isinstance(header_param, dict):
                headers = header_param

            retry = input_params.get("retry", False)

            # 获取重试次数，如果没有指定则无限重试
            retry_times_param = input_params.get("retryTimes")
            if retry_times_param is not None:
                # 指定了重试次数，使用指定值
                if isinstance(retry_times_param, str):
                    try:
                        retry_times = int(retry_times_param)
                    except ValueError:
                        retry_times = None  # 无限重试
                else:
                    retry_times = retry_times_param
            else:
                # 没有指定重试次数，默认无限重试
                retry_times = None

            # 确保retry_interval为整数
            retry_interval = input_params.get("retryInterval", 1000)
            if isinstance(retry_interval, str):
                try:
                    retry_interval = int(retry_interval)
                except ValueError:
                    retry_interval = 1000

            if not url:
                result = {
                    "success": False,
                    "message": "缺少请求URL"
                }
                # 记录执行结果
                await self._record_task_log(block, result, context)
                return result

            # 执行HTTP请求
            attempt = 0
            if not retry:
                max_attempts = 1
            elif retry_times is not None:
                max_attempts = retry_times + 1
            else:
                max_attempts = float('inf')  # 无限重试

            while attempt < max_attempts:
                try:
                    async with aiohttp.ClientSession() as session:
                        async with session.get(url, headers=headers) as response:
                            # 读取响应内容
                            response_text = await response.text()
                            logger.debug(f"HTTP GET 响应内容: {response_text}")

                            # 尝试解析JSON
                            try:
                                response_json = await response.json()
                                context.set_variable("response", response_json)
                            except:
                                # 不是有效的JSON，保存为文本
                                context.set_variable("response", response_text)

                            result = {
                                "success": True,
                                "message": f"HTTP GET请求成功，状态码: {response.status}",
                            }
                            # 记录执行结果
                            await self._record_task_log(block, result, context)
                            return result
                except Exception as e:
                    attempt += 1
                    if attempt >= max_attempts:
                        raise

                    # 重试间隔
                    await asyncio.sleep(retry_interval / 1000)

        except Exception as e:
            result = {
                "success": False,
                "message": f"HTTP GET请求失败: {str(e)}"
            }
            # 记录异常
            await self._record_task_log(block, result, context)
            return result

# HTTP POST请求处理器
@register_handler(HttpRequestBlockName.POST)
class HttpPostBlockHandler(BlockHandler):
    """HTTP POST请求处理器"""

    async def execute(
            self,
            block: Dict[str, Any],
            input_params: Dict[str, Any],
            context: TaskContext
    ) -> Dict[str, Any]:
        """执行HTTP POST请求"""
        import aiohttp
        import asyncio
        import json

        try:
            # 获取请求参数
            url = input_params.get("url")
            params = input_params.get("param", "{}")
            # 处理headers参数
            headers = {}
            header_param = input_params.get("header", {})

            # 如果header是字符串，尝试解析JSON
            if isinstance(header_param, str):
                try:
                    header_data = json.loads(header_param)
                    # 检查解析后的数据是否为列表格式 [{"key0":"value0", "value0":"value"}, ...]
                    if isinstance(header_data, list):
                        for item in header_data:
                            # 寻找以key开头的键，如key0, key1等
                            for key in [k for k in item if k.startswith('key')]:
                                if key in item and item[key]:
                                    # 对应的value键应该是value0, value1等
                                    value_key = 'value' + key[3:]
                                    if value_key in item and item[value_key]:
                                        headers[item[key]] = item[value_key]
                    # 如果是字典格式，直接使用
                    elif isinstance(header_data, dict):
                        headers = header_data
                except json.JSONDecodeError:
                    pass
                    # logger.warning(f"无法解析headers JSON: {header_param}")
            elif isinstance(header_param, dict):
                headers = header_param

            media_type = input_params.get("mediaType", "JSON")
            retry = input_params.get("retry", True)

            # 获取重试次数，如果没有指定则无限重试
            retry_times_param = input_params.get("retryTimes")
            if retry_times_param is not None:
                # 指定了重试次数，使用指定值
                if isinstance(retry_times_param, str):
                    try:
                        retry_times = int(retry_times_param)
                    except ValueError:
                        retry_times = None  # 无限重试
                else:
                    retry_times = retry_times_param
            else:
                # 没有指定重试次数，默认无限重试
                retry_times = None

            # 确保retry_interval为整数
            retry_interval = input_params.get("retryInterval", 1000)
            if isinstance(retry_interval, str):
                try:
                    retry_interval = int(retry_interval)
                except ValueError:
                    retry_interval = 1000

            if not url:
                result = {
                    "success": False,
                    "message": "缺少请求URL"
                }
                # 记录执行结果
                await self._record_task_log(block, result, context)
                return result

            # 准备请求数据
            try:
                if isinstance(params, str):
                    data = json.loads(params)
                else:
                    data = params
            except:
                data = params  # 如果无法解析为JSON，使用原始字符串

            # 设置Content-Type
            content_type = "application/json"
            if media_type == "HTML":
                content_type = "text/html"
            elif media_type == "XML":
                content_type = "application/xml"
            elif media_type == "XWWWFORMURLENCODED":
                content_type = "application/x-www-form-urlencoded"
            elif media_type == "JAVASCRIPT":
                content_type = "application/javascript"

            if "Content-Type" not in headers:
                headers["Content-Type"] = content_type

            # 执行HTTP请求
            attempt = 0
            if not retry:
                max_attempts = 1
            elif retry_times is not None:
                max_attempts = retry_times + 1
            else:
                max_attempts = float('inf')  # 无限重试
                
            while attempt < max_attempts:
                try:
                    async with aiohttp.ClientSession() as session:
                        async with session.post(url, json=data, headers=headers) as response:
                            # 读取响应内容
                            response_text = await response.text()
                            logger.debug(f"HTTP POST响应内容: {response_text}")
                            # 尝试解析JSON
                            try:
                                response_json = await response.json()
                                context.set_variable("response", response_json)
                            except:
                                # 不是有效的JSON，保存为文本
                                context.set_variable("response", response_text)

                            result = {
                                "success": True,
                                "message": f"HTTP POST请求成功，状态码: {response.status}, 响应内容详情: {response_text}",

                            }
                            # 记录执行结果
                            await self._record_task_log(block, result, context)
                            return result
                except Exception as e:
                    attempt += 1
                    if attempt >= max_attempts:
                        raise

                    # 重试间隔
                    await asyncio.sleep(retry_interval / 1000)

        except Exception as e:
            result = {
                "success": False,
                "message": f"HTTP POST请求失败: {str(e)}"
            }
            # 记录异常
            await self._record_task_log(block, result, context)
            return result

