from typing import Optional, Union
from analogai.foundation.core.value_objects.modifier import Modifier
from analogai.foundation.core.value_objects.relation import Relation


def pluralize_noun(noun: str, quantity: float) -> str:
    if quantity == 1.0 or quantity == 1:
        return noun
    
    noun_lower = noun.lower()
    
    if noun_lower.endswith('s') or noun_lower.endswith('x') or noun_lower.endswith('z') or noun_lower.endswith('ch') or noun_lower.endswith('sh'):
        return f"{noun}es"
    elif noun_lower.endswith('y') and len(noun) > 1 and noun[-2] not in 'aeiou':
        return f"{noun[:-1]}ies"
    elif noun_lower.endswith('f'):
        return f"{noun[:-1]}ves"
    elif noun_lower.endswith('fe'):
        return f"{noun[:-2]}ves"
    else:
        return f"{noun}s"


def format_quantity(quantity: Union[int, float]) -> str:
    if isinstance(quantity, int) or quantity.is_integer():
        return str(int(quantity))
    return str(quantity)


def format_statement_repr(
    subject_caption: str,
    relation: Union[Relation, str],
    object_caption: str,
    quantity: Optional[float] = None,
    modifier: Optional[Modifier] = None,
) -> str:
    relation_str = relation.value if isinstance(relation, Relation) else str(relation)
    if quantity is None and modifier is not None:
        quantity = modifier.quantity
    
    if quantity is not None and quantity > 0:
        formatted_quantity = format_quantity(quantity)
        pluralized_object = pluralize_noun(object_caption, quantity)
        object_part = f"{formatted_quantity} {pluralized_object}"
    else:
        object_part = object_caption
    
    parts = [subject_caption, relation_str, object_part]
    
    if modifier:
        modifier_parts = []
        if modifier.location:
            modifier_parts.append(f"at {modifier.location}")
        if modifier.from_time or modifier.to_time:
            if modifier.from_time and modifier.to_time:
                modifier_parts.append(f"from {modifier.from_time} to {modifier.to_time}")
            elif modifier.from_time:
                modifier_parts.append(f"from {modifier.from_time}")
            elif modifier.to_time:
                modifier_parts.append(f"until {modifier.to_time}")
        if modifier.deontic_modality:
            modifier_parts.append(f"[{modifier.deontic_modality.value}]")
        if modifier.attributes:
            for attribute in modifier.attributes:
                unit_str = f" {attribute.unit}" if attribute.unit else ""
                modifier_parts.append(f"with {attribute.tag} {attribute.value}{unit_str}")
        
        if modifier_parts:
            parts.append(f"({', '.join(modifier_parts)})")
    
    return " ".join(parts)
