import logging

LOGGER = logging.getLogger(__name__)


class BaseModel:
    def __init__(self, **kwargs):
        self.update_from_dict(kwargs)

    def update_from_dict(self, payload):
        if not payload:
            return self
        for key, value in payload.items():
            setattr(self, key, value)
        return self

    @classmethod
    def from_dict(cls, payload):
        return cls(**(payload or {}))

    def to_dict(self, exclude_none=False):
        data = {}
        for key, value in self.__dict__.items():
            if key.startswith("_"):
                continue
            if exclude_none and value is None:
                continue
            data[key] = value
        return data

    def validate_required(self, *fields, source=None):
        source_map = source if source is not None else self.to_dict(exclude_none=False)
        missing_fields = []

        for name in fields:
            if isinstance(source_map, dict):
                value = source_map.get(name)
            else:
                value = getattr(source_map, name, None)
            if value is None or (isinstance(value, str) and value.strip() == ""):
                missing_fields.append(name)

        if missing_fields:
            joined = ", ".join(missing_fields)
            raise ValueError(f"Field wajib belum terisi: {joined}")
        return True

    def _log(self, level, message):
        name = self.__class__.__name__
        safe_level = str(level or "INFO").upper()
        level_num = getattr(logging, safe_level, logging.INFO)
        LOGGER.log(level_num, "[%s] %s", name, message)

    def log_debug(self, message):
        self._log("DEBUG", message)

    def log_info(self, message):
        self._log("INFO", message)

    def log_warning(self, message):
        self._log("WARN", message)

    def log_error(self, message):
        self._log("ERROR", message)