from typing import Optional, List
from pydantic import Field, field_validator, model_validator
from src.apps.base.schemas.common import BaseSchema


# Shared properties
class SiteMasterBase(BaseSchema):
    key: Optional[str] = Field(description="Key of SiteMaster. The primary identifier")
    value: Optional[str] = Field(
        description="Form Value, inclusive of alphabetical characters only"
    )
    label: Optional[str] = Field(
        description="Form label, inclusive of alphabetical characters only"
    )
    group: Optional[str] = Field(
        description="A valid string, can be used for categorizing settings."
    )
    display_order: Optional[int] = Field(
        description="Sort order of item, is 0 by default."
    )
    code: Optional[str] = Field(description="Computed code from label", default=None)


class SiteMasterSchema(SiteMasterBase):
    id: int = Field(description="Id of SiteMaster resource")
    children: Optional[List['SiteMasterBase']] = Field(
        description="Nested master data. Useful for categorizing items.",
        default=None
    )
    
    model_config = {"from_attributes": True}
    
    @model_validator(mode='before')
    @classmethod
    def extract_code_from_label(cls, data):
        """Extract code from label if code is not present"""
        if isinstance(data, dict):
            # Handle dictionary data
            if not data.get('code') and data.get('label'):
                try:
                    code_array = data['label'].split("-")
                    if len(code_array) > 1:
                        data['code'] = code_array[1]
                except:
                    pass
        else:
            # Handle SQLAlchemy model object
            if hasattr(data, 'label') and data.label:
                try:
                    code_array = data.label.split("-")
                    if len(code_array) > 1 and not hasattr(data, 'code'):
                        # Add code as a dynamic attribute
                        setattr(data, 'code', code_array[1])
                except:
                    pass
        return data
