#!/usr/bin/env python3
"""
SUBQUERY Executor
Company: eXonware.com
Author: eXonware Backend Team
Email: connect@exonware.com
Version: 0.0.1.8
"""

from typing import Any, Optional
from ..base import AUniversalOperationExecutor
from ....contracts import QueryAction, ExecutionContext, ExecutionResult
from ....defs import OperationType
from ..utils import extract_items, extract_field_value


class SubqueryExecutor(AUniversalOperationExecutor):
    """SUBQUERY - Execute nested child query actions."""
    OPERATION_NAME = "SUBQUERY"
    OPERATION_TYPE = OperationType.ADVANCED
    SUPPORTED_NODE_TYPES = []

    def _do_execute(self, action: QueryAction, context: ExecutionContext) -> ExecutionResult:
        params = action.params
        result_data = self._execute_subquery(context.node, params, context)
        return ExecutionResult(
            success=True,
            data=result_data,
            action_type=self.OPERATION_NAME,
            metadata={"operation": self.OPERATION_NAME},
        )

    def _normalize_action(self, action_data: Any) -> Optional[QueryAction]:
        if isinstance(action_data, QueryAction):
            return action_data
        if isinstance(action_data, dict):
            action_type = action_data.get("type", action_data.get("operation", ""))
            if action_type:
                return QueryAction(type=action_type, params=action_data.get("params", {}))
        return None

    def _execute_subquery(self, node: Any, params: dict, context: ExecutionContext) -> dict:
        items = extract_items(node)
        query_actions = params.get("query_actions", [])
        as_field = params.get("as_field", "_subquery")
        engine = context.metadata.get("engine") if isinstance(context.metadata, dict) else None

        normalized_actions = []
        for child in query_actions:
            child_action = self._normalize_action(child)
            if child_action is not None:
                normalized_actions.append(child_action)

        subquery_output: Any = []
        if engine is not None and normalized_actions:
            current_node: Any = items
            for child_action in normalized_actions:
                child_context = ExecutionContext(
                    node=current_node,
                    variables=dict(context.variables),
                    options=dict(context.options),
                    parent_context=context,
                    metadata=dict(context.metadata),
                    engine_type=context.engine_type,
                )
                child_result = engine.execute_tree(child_action, child_context)
                if not child_result.success:
                    break
                current_node = child_result.data
            subquery_output = current_node

        enriched_items = []
        for item in items:
            record = dict(item) if isinstance(item, dict) else {"value": item}
            record[as_field] = subquery_output
            enriched_items.append(record)

        return {
            "items": enriched_items,
            "count": len(enriched_items),
            "as_field": as_field,
            "actions_executed": len(normalized_actions),
            "subquery_result": subquery_output,
            "first_item_key_sample": extract_field_value(enriched_items[0], as_field) if enriched_items else None,
        }
