#!/usr/bin/env python3
"""
GROUP_CONCAT 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 GroupConcatExecutor(AUniversalOperationExecutor):
    """GROUP_CONCAT operation executor."""

    OPERATION_NAME = "GROUP_CONCAT"
    OPERATION_TYPE = OperationType.AGGREGATION
    SUPPORTED_NODE_TYPES = []

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

    def _execute_group_concat(self, node: Any, params: dict[str, Any]) -> dict[str, Any]:
        items = extract_items(node)
        field: Optional[str] = params.get("field")
        separator = str(params.get("separator", ","))
        distinct = bool(params.get("distinct", False))
        order = params.get("order")
        as_field = params.get("as_field", "group_concat")

        values: list[str] = []
        for item in items:
            raw = extract_field_value(item, field) if field else item
            if raw is not None:
                values.append(str(raw))

        if distinct:
            seen: set[str] = set()
            deduped: list[str] = []
            for value in values:
                if value not in seen:
                    seen.add(value)
                    deduped.append(value)
            values = deduped

        if order == "asc":
            values.sort()
        elif order == "desc":
            values.sort(reverse=True)

        return {
            as_field: separator.join(values),
            "count": len(values),
            "field": field,
            "distinct": distinct,
            "order": order,
            "separator": separator,
        }


__all__ = ["GroupConcatExecutor"]
