from __future__ import annotations

import uuid
from typing import TYPE_CHECKING

from kele.syntax.base_classes import FACT_TYPE, Assertion, Concept, Constant, Rule

if TYPE_CHECKING:
    from collections.abc import Sequence


class ConflictRule(Rule):
    """Dedicated syntax for constraints whose head is left empty.

    The public API accepts only ``body`` and compiles the rule into an internal
    rule with a reserved uppercase violation head symbol.
    """

    _BOOL_CONCEPT = Concept("Bool")
    _TRUE_CONST = Constant("TrueConst", _BOOL_CONCEPT)
    _VIOLATION_PREFIX = "__KELE_CONFLICT_VIOLATION_SYMBOL__"

    def __init__(
        self,
        body: FACT_TYPE | Sequence[FACT_TYPE],
        *,
        name: str = "",
        priority: float = 0.0,
        description: str = "",
    ) -> None:
        violation_symbol = self._build_violation_symbol()
        self.violation_symbol = violation_symbol
        self.original_name = name

        violation_head = Assertion(
            Constant(violation_symbol, self._BOOL_CONCEPT),
            self._TRUE_CONST,
        )
        compiled_name = name or violation_symbol
        super().__init__(
            head=violation_head,
            body=body,
            priority=priority,
            name=compiled_name,
            description=description,
        )

    @classmethod
    def _build_violation_symbol(cls) -> str:
        return f"{cls._VIOLATION_PREFIX}{uuid.uuid4().hex.upper()}"

    def to_violation_rule(self) -> Rule:
        """Return the compiled internal rule used by conflict evaluation."""
        return Rule.from_parts(
            head=self.head,
            body=self.body,
            priority=self.priority,
            name=self.name,
            description=self.description,
        )

    def __str__(self) -> str:
        return f"{self.name}: :- {self.body}"
