#!/usr/bin/env python3
"""
SWITCH 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 SwitchExecutor(AUniversalOperationExecutor):
    """
    SWITCH operation executor - Multi-branch conditional (like MongoDB $switch).

    For each item, compares the field value against each branch's `case` value
    and returns the corresponding `then` result. Falls back to `default` when
    no branch matches.

    params:
        field:    field name whose value is matched against branches
        branches: list of {case: value, then: result}
        default:  fallback result when no branch matches (default: None)
        output:   output field name for the result (default: '_switch')

    Time Complexity: O(n*b) where n=items, b=branches
    Capability: Universal
    Operation Type: ADVANCED (conditional)
    """
    OPERATION_NAME = "SWITCH"
    OPERATION_TYPE = OperationType.ADVANCED
    SUPPORTED_NODE_TYPES = []

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

    def _execute_op(self, node: Any, params: dict, context: ExecutionContext) -> dict:
        items = extract_items(node)
        field = params.get('field', '')
        branches = params.get('branches', [])
        default = params.get('default', None)
        output_field = params.get('output', '_switch')

        result_items = []
        branch_hit_counts: dict[int, int] = {}
        default_count = 0

        for item in items:
            item_copy = item.copy() if isinstance(item, dict) else {'value': item}
            actual = extract_field_value(item, field) if field else item

            resolved = default
            matched = False
            for idx, branch in enumerate(branches):
                case_val = branch.get('case')
                if actual == case_val:
                    resolved = branch.get('then')
                    branch_hit_counts[idx] = branch_hit_counts.get(idx, 0) + 1
                    matched = True
                    break

            if not matched:
                default_count += 1

            item_copy[output_field] = resolved
            result_items.append(item_copy)

        return {
            'items': result_items,
            'count': len(result_items),
            'total_items': len(items),
            'default_count': default_count,
            'branch_hit_counts': branch_hit_counts,
        }

__all__ = ['SwitchExecutor']
