from enum import Enum
from typing import Any, Dict, List, Optional, Union

from .report_conditions import CustomReportConditions
from .report_serializable import ReportSerializable
from .utils import add_param


class CustomReportElement(ReportSerializable):
    """Base class for report renderers and preparers."""

    def __init__(
        self,
        name: str,
        params: Optional[Union[Dict, List]] = None,
        conditions: Optional[List[CustomReportConditions]] = None,
        spacing: Optional[int] = None,
    ):
        """Creates a report element with optional conditions and spacing.

        Args:
            name: Element type identifier sent to the report renderer.
            params: Element-specific parameters.
            conditions: Export-format conditions that control when this element is applied.
            spacing: Vertical spacing before this element.
        """
        self.name = name
        self.params = params
        self.conditions = conditions
        self.spacing = spacing

    def build_content(self) -> Dict:
        """Serializes the element into a dict suitable for report payload.

        Returns:
            Dict with ``name``, and optionally ``conditions``, ``params`` and ``spacing``.
        """
        result = {"name": self.name}
        if len(self.conditions or []) > 0:
            result["conditions"] = [c.value if isinstance(c, Enum) else c for c in self.conditions]
        if len(self.params or {}) > 0:
            result["params"] = self.params
        if self.spacing or 0 > 0:
            result["spacing"] = self.spacing
        return result

    def add_param(self, key: str, value: Any):
        """Adds or updates a parameter on this element.

        Args:
            key: Parameter name.
            value: Parameter value. ``ReportSerializable`` instances are automatically serialized.
        """
        if self.params is None:
            self.params = {}
        add_param(self.params, key, value)
