from ..extensions import db
from sqlalchemy.exc import ProgrammingError, OperationalError
from datetime import datetime
import json


class Setting(db.Model):
    __tablename__ = 'settings'

    id = db.Column(db.Integer, primary_key=True)
    key = db.Column(db.String(255), unique=True, nullable=False, index=True)
    value = db.Column(db.Text, nullable=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    def __repr__(self):
        return f"<Setting {self.key}>"

    @staticmethod
    def get_value(key: str, default=None):
        try:
            s = Setting.query.filter_by(key=key).first()
            return s.value if s is not None else default
        except (ProgrammingError, OperationalError):
            # Base de datos aún sin tabla 'settings' o sin migraciones aplicadas
            db.session.rollback()
            return default

    @staticmethod
    def set_value(key: str, value):
        s = Setting.query.filter_by(key=key).first()
        if s is None:
            s = Setting(key=key, value=value)
            db.session.add(s)
        else:
            s.value = value
        return s

    @staticmethod
    def get_json(key: str, default=None):
        try:
            raw = Setting.get_value(key)
            if raw is None:
                return default
            try:
                return json.loads(raw)
            except Exception:
                return default
        except (ProgrammingError, OperationalError):
            db.session.rollback()
            return default

    @staticmethod
    def set_json(key: str, obj):
        # Serializa exactamente el objeto proporcionado (incluidas listas vacías)
        # Evita convertir [] en {} por el uso de valores "falsy",
        # lo cual causaba incoherencias al leer configuraciones como la whitelist de IPs.
        return Setting.set_value(key, json.dumps(obj))
