from __future__ import annotations

from collections.abc import Mapping
from dataclasses import dataclass

from sqlalchemy.orm import Session

from govoplan_core.admin.models import SystemSettings
from govoplan_core.admin.settings import SYSTEM_SETTINGS_ID, get_system_settings

MAINTENANCE_SETTINGS_KEY = "maintenance_mode"
MAINTENANCE_ACCESS_SCOPE = "system:maintenance:access"
DEFAULT_MAINTENANCE_MESSAGE = "GovOPlaN is currently in maintenance mode."


@dataclass(frozen=True, slots=True)
class MaintenanceMode:
    enabled: bool = False
    message: str | None = None

    def as_dict(self) -> dict[str, object]:
        return {
            "enabled": self.enabled,
            "message": self.message,
        }


def maintenance_mode_from_settings(settings: Mapping[str, object]) -> MaintenanceMode:
    raw = settings.get(MAINTENANCE_SETTINGS_KEY)
    if not isinstance(raw, Mapping):
        return MaintenanceMode()
    return MaintenanceMode(
        enabled=bool(raw.get("enabled")),
        message=_clean_message(raw.get("message")),
    )


def saved_maintenance_mode(session: Session) -> MaintenanceMode:
    item = session.get(SystemSettings, SYSTEM_SETTINGS_ID)
    if item is None:
        return MaintenanceMode()
    return maintenance_mode_from_settings(item.settings or {})


def save_maintenance_mode(session: Session, mode: MaintenanceMode) -> MaintenanceMode:
    item = get_system_settings(session)
    settings = dict(item.settings or {})
    settings[MAINTENANCE_SETTINGS_KEY] = mode.as_dict()
    item.settings = settings
    session.add(item)
    session.flush()
    return mode


def maintenance_response_detail(mode: MaintenanceMode) -> dict[str, object]:
    return {
        "code": "maintenance_mode",
        "message": mode.message or DEFAULT_MAINTENANCE_MESSAGE,
        "required_scope": MAINTENANCE_ACCESS_SCOPE,
    }


def _clean_message(value: object) -> str | None:
    if value is None:
        return None
    cleaned = str(value).strip()
    return cleaned or None
