# src\ArquitectureLayer\Model.py

from sqlalchemy import Column, DateTime, String, Integer, Text, func
from sqlalchemy.ext.declarative import declared_attr, as_declarative
from datetime import datetime

@as_declarative()
class Model_base:
    __abstract__ = True

    @declared_attr
    def sys_created_at(cls):
        return Column(DateTime(timezone=True), server_default=func.now(), nullable=False)

    @declared_attr
    def sys_created_by(cls):
        return Column(String, nullable=True)

    @declared_attr
    def sys_updated_at(cls):
        return Column(DateTime(timezone=True), onupdate=func.now(), nullable=True)

    @declared_attr
    def sys_updated_by(cls):
        return Column(String, nullable=True)

    @declared_attr
    def sys_version(cls):
        return Column(Integer, default=1, nullable=False)

    @declared_attr
    def sys_notes(cls):
        return Column(Text, nullable=True)

    @declared_attr
    def sys_deleted_at(cls):
        return Column(DateTime(timezone=True), nullable=True)

    def __repr__(self):
        id_val = getattr(self, "id", None)
        return f"<{self.__class__.__name__} id={id_val}>"

    def __str__(self):
        cls = self.__class__.__name__
        id_val = getattr(self, "id", None)
        return f"{cls}(id={id_val})"

    def __json__(self) -> dict:
        """Devuelve una representación JSON serializable (dict plano)."""
        out = {}

        # Prevención de error: solo ejecuta si __table__ existe
        if not hasattr(self, "__table__"):
            return out

        for attr in self.__table__.columns:
            val = getattr(self, attr.name, None)
            if isinstance(val, datetime):
                out[attr.name] = val.isoformat()
            else:
                out[attr.name] = val

        return out