import re
from datetime import datetime, timedelta
from typing import Annotated

from django.utils import timezone
from pydantic import BeforeValidator, Field

SlugStr = Annotated[str, Field(pattern=r"^[-a-zA-Z0-9_]+$", max_length=50)]

# RELATIVE_TIME_REGEX = re.compile(r"now[+-]\d+[mhd]")
RELATIVE_TIME_REGEX = re.compile(r"now\s*\-\s*\d+\s*(m|h|d)\s*$")


def parse_relative_datetime(value: str) -> datetime:
    """
    Allow relative terms like now or now-1h. Only 0 or 1 math operation is permitted.

    Accepts
    - now
    - + (addition)
    - - (subtraction)
    - m (minutes)
    - h (hours)
    - d (days)
    """
    if value == "now":
        return timezone.now()

    match = RELATIVE_TIME_REGEX.match(value)
    if match:
        now = timezone.now()
        stripped_value = value.replace(" ", "")
        sign = 1 if "+" in stripped_value else -1
        number = int(re.findall(r"\d+", stripped_value)[0])

        if "m" in stripped_value:
            return now + sign * timedelta(minutes=number)
        elif "h" in stripped_value:
            return now + sign * timedelta(hours=number)
        elif "d" in stripped_value:
            return now + sign * timedelta(days=number)

    return value


RelativeDateTime = Annotated[datetime, BeforeValidator(parse_relative_datetime)]