from typing import Optional
from dataclasses import dataclass, field
from .Attribute import Attribute

@dataclass
class numAttribute(Attribute):
    """Base class for numeric attributes (int and float)."""
    min_val: Optional[float] = None
    max_val: Optional[float] = None
    step: float = 1.0

    def __post_init__(self):
        """Post-initialization to set the HTML input type."""
        self.html_input_type = "number"

    def validate(self) -> Optional[str]:
        """Validate numeric-specific attributes."""
        error = super().validate()
        if error:
            return error

        # Validate min_val and max_val
        if self.min_val is not None and not isinstance(self.min_val, (int, float)):
            return f"min_val must be a number for attribute '{self.attrib_name}'."
        if self.max_val is not None and not isinstance(self.max_val, (int, float)):
            return f"max_val must be a number for attribute '{self.attrib_name}'."
        if self.min_val is not None and self.max_val is not None and self.min_val > self.max_val:
            return f"min_val cannot be greater than max_val for attribute '{self.attrib_name}'."

        # Validate step
        if self.step is not None:
            if not isinstance(self.step, (int, float)):
                return f"Step must be a number for attribute '{self.attrib_name}'."
            if self.step <= 0:
                return f"Step must be a positive number for attribute '{self.attrib_name}'."
            if self.min_val is not None and self.max_val is not None:
                range_val = self.max_val - self.min_val
                if self.step > range_val:
                    return f"Step value is too large for attribute '{self.attrib_name}'."

        # Validate default_val
        if self.default_val is not None:
            if not isinstance(self.default_val, (int, float)):
                return f"default_val must be a number for attribute '{self.attrib_name}'."
            if self.min_val is not None and self.default_val < self.min_val:
                return f"default_val cannot be less than min_val for attribute '{self.attrib_name}'."
            if self.max_val is not None and self.default_val > self.max_val:
                return f"default_val cannot be greater than max_val for attribute '{self.attrib_name}'."

        return None

@dataclass
class intAttribute(numAttribute):
    """Class for integer attributes."""

    def validate(self) -> Optional[str]:
        """Validate integer-specific attributes."""
        error = super().validate()
        if error:
            return error

        # Ensure default_val is an integer
        if self.default_val is not None and not isinstance(self.default_val, int):
            return f"default_val must be an integer for attribute '{self.attrib_name}'."

        return None

@dataclass
class floatAttribute(numAttribute):
    """Class for float attributes."""

    def validate(self) -> Optional[str]:
        """Validate float-specific attributes."""
        error = super().validate()
        if error:
            return error

        # Ensure default_val is a float
        if self.default_val is not None and not isinstance(self.default_val, float):
            return f"default_val must be a float for attribute '{self.attrib_name}'."

        return None