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

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 IntersectExecutor(AUniversalOperationExecutor):
    """INTERSECT - Set intersection of two datasets."""
    OPERATION_NAME = "INTERSECT"
    OPERATION_TYPE = OperationType.ADVANCED
    SUPPORTED_NODE_TYPES = []

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

    def _build_key(self, item: Any, key_fields: Optional[list[str]]) -> Any:
        if key_fields:
            return tuple(extract_field_value(item, field) for field in key_fields)
        return str(item)

    def _execute_intersect(self, node: Any, params: dict, context: ExecutionContext) -> dict:
        primary_items = extract_items(node)
        source = params.get("source", [])
        source_items = extract_items(source)
        key_fields = params.get("key_fields")
        if key_fields and not isinstance(key_fields, list):
            key_fields = [key_fields]

        source_keys = {self._build_key(item, key_fields) for item in source_items}
        output_items = [item for item in primary_items if self._build_key(item, key_fields) in source_keys]

        return {
            "items": output_items,
            "count": len(output_items),
            "left_count": len(primary_items),
            "right_count": len(source_items),
            "key_fields": key_fields or [],
        }
