from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, DateTime, func, String
from datetime import datetime
import uuid
from sqlalchemy.orm import Mapped, mapped_column

Base = declarative_base()


class BaseModelWihoutId(Base):
    __abstract__ = True
    created_at = Column(DateTime, server_default=func.now(), nullable=False)
    updated_at = Column(
        DateTime, server_default=func.now(), onupdate=func.now(), nullable=False
    )

    def to_dict(self):
        result = {}

        for c in self.__table__.columns:
            if c.name == "password":
                continue
            value = getattr(self, c.name)

            if isinstance(value, datetime):
                result[c.name] = value.isoformat()
            else:
                result[c.name] = value

        return result


class BaseModel(Base):
    __abstract__ = True
    id: Mapped[str] = mapped_column(
        String(36),
        primary_key=True,
        default=lambda: str(uuid.uuid4()),
    )
    created_at = Column(DateTime, server_default=func.now(), nullable=False)
    updated_at = Column(
        DateTime, server_default=func.now(), onupdate=func.now(), nullable=False
    )

    def to_dict(self):
        result = {}

        for c in self.__table__.columns:
            if c.name == "password":
                continue
            value = getattr(self, c.name)

            if isinstance(value, datetime):
                result[c.name] = value.isoformat()
            else:
                result[c.name] = value

        return result
