import re
from enum import Enum
from random import Random

from pydantic import BaseModel, field_validator

RE_WHITESPACE = re.compile(
    pattern=r"\s+",
    flags=re.UNICODE | re.IGNORECASE,
)
RE_SPECIAL_CHARS = re.compile(
    pattern=r"[^a-zA-Z0-9\s]+",
    flags=re.UNICODE | re.IGNORECASE,
)


class TransformedString(BaseModel):
    class __Whitespace(str, Enum):
        # unverändert
        KEEP = "KEEP"

        # Leerzeichen an Anfang und Ende entfernen
        STRIP = "STRIP"

        # whitespace durch Leerzeichen ersetzen
        SPACE = "SPACE"

        # whitespace entfernen
        REMOVE = "REMOVE"

    class __SpecialChars(str, Enum):
        # unverändert
        KEEP = "KEEP"

        # Sonderzeichen entfernen
        REMOVE = "REMOVE"

    class __Case(str, Enum):
        # unverändert
        KEEP = "KEEP"

        # GROSSBUCHSTABEN
        UPPER = "UPPER"

        # kleinbuchstaben
        LOWER = "LOWER"

        # ZuFÄllIg
        RANDOM = "RANDOM"

    value: str

    whitespace: __Whitespace = __Whitespace.REMOVE
    special_chars: __SpecialChars = __SpecialChars.REMOVE
    case: __Case = __Case.UPPER

    @field_validator("whitespace", "case", mode="before")
    def transform_from_str(cls, v) -> str:
        return str(v).upper()

    @property
    def clean(self) -> str:
        result = self.value

        # Whitespace verarbeiten
        if self.whitespace is TransformedString.__Whitespace.STRIP:
            result = result.strip()

        elif self.whitespace is TransformedString.__Whitespace.SPACE:
            result = RE_WHITESPACE.sub(string=result, repl=" ")

        elif self.whitespace is TransformedString.__Whitespace.REMOVE:
            result = RE_WHITESPACE.sub(string=result, repl="")

        # Sonderzeichen verarbeiten
        if self.special_chars is TransformedString.__SpecialChars.REMOVE:
            result = RE_SPECIAL_CHARS.sub(string=result, repl="")

        # Groß-/Kleinschreibung verarbeiten
        if self.case is TransformedString.__Case.UPPER:
            result = result.upper()

        elif self.case is TransformedString.__Case.LOWER:
            result = result.lower()

        elif self.case is TransformedString.__Case.RANDOM:
            rnd = Random(self.value)

            def randomcase(c: str) -> str:
                if rnd.choice((True, False)):
                    return c.upper()
                return c.lower()

            result = "".join(randomcase(c) for c in result)

        return result
