# retoor <retoor@molodetz.nl>

from ._shared import SERVICE_ACTIONS, endpoint, field
from .negotiation import _classify


def _service_control_endpoints():
    endpoints = []
    for action, summary in SERVICE_ACTIONS:
        endpoints.append(
            endpoint(
                id=f"services-{action.replace('-', '')}",
                method="POST",
                path=f"/admin/services/{{name}}/{action}",
                title=f"Service: {action}",
                summary=summary + ".",
                auth="admin",
                interactive=True,
                destructive=True,
                params=[
                    field(
                        "name",
                        "path",
                        required=True,
                        example="news",
                        description="Registered service name.",
                    )
                ],
                sample_response={"ok": True},
            )
        )
    return endpoints


def _field_to_param(spec):
    description = spec["label"]
    if spec.get("help"):
        description = f"{spec['label']} - {spec['help']}"
    value = "" if spec.get("secret") else str(spec.get("value", ""))
    if spec.get("secret"):
        description += " Leave blank to keep the current value."
    if spec["type"] == "bool":
        return field(
            spec["key"], "form", "enum", False, value or "0", description, ["1", "0"]
        )
    if spec["type"] == "select":
        options = [option["value"] for option in spec.get("options") or []]
        return field(
            spec["key"],
            "form",
            "enum",
            False,
            value or (options[0] if options else ""),
            description,
            options,
        )
    if spec["type"] in ("int", "float"):
        return field(spec["key"], "form", "int", False, value, description)
    return field(spec["key"], "form", "string", False, value, description)


def _service_section(service):
    enabled = "yes" if service.get("enabled") else "no"
    groups = ", ".join(group["name"] for group in service.get("field_groups", []))
    lines = [
        f"## {service.get('title') or service['name']}",
        "",
        service.get("description", ""),
        "",
        f"- Service name: `{service['name']}`",
        f"- Enabled: {enabled}",
        f"- Run interval: {service.get('interval_seconds', 0)}s",
    ]
    if groups:
        lines.append(f"- Configuration groups: {groups}")
    return "\n".join(lines)


def build_services_group(services, base):
    intro_parts = [
        "# Background Services",
        "",
        "DevPlace runs background services supervised by a single manager. Each service has its "
        "own enable flag, run interval, live status, metrics, and a rolling log buffer. Manage "
        "them from the admin panel at `/admin/services` or with the endpoints below.",
        "",
        "Control a service by its `name` (shown per service): start or stop it, trigger a single "
        "run, clear its logs, or save its configuration. `GET /admin/services/data` returns the "
        "live status, metrics, and log tail for every service.",
        "",
        "See the [Admin API](/docs/admin.html) for the rest of administration; the Devii assistant "
        "is itself a service, configured in [Configuration and CLI](/docs/devii-config.html).",
    ]
    config_endpoints = []
    for service in services:
        intro_parts.append("")
        intro_parts.append(_service_section(service))
        params = [
            _field_to_param(spec)
            for spec in service.get("fields", [])
            if not spec["key"].endswith("_enabled")
        ]
        config_endpoints.append(
            endpoint(
                id=f"services-config-{service['name']}",
                method="POST",
                path=f"/admin/services/{service['name']}/config",
                title=f"Configure {service.get('title') or service['name']}",
                summary=f"Save configuration for the {service['name']} service. Empty values keep the current setting.",
                auth="admin",
                encoding="form",
                destructive=True,
                params=params,
                notes=[
                    "Use start/stop to enable or disable the service; this saves the remaining settings."
                ],
            )
        )
    control_endpoints = [
        endpoint(
            id="services-page",
            method="GET",
            path="/admin/services",
            title="Services dashboard",
            summary="Admin HTML index of every registered background service, its status, and controls.",
            auth="admin",
            interactive=False,
        ),
        endpoint(
            id="services-detail-page",
            method="GET",
            path="/admin/services/{name}",
            title="Service detail page",
            summary="Admin HTML detail page for a single service: overview, configuration form, and logs.",
            auth="admin",
            interactive=False,
            params=[field("name", "path", "string", True, "news", "Service name.")],
        ),
        endpoint(
            id="services-data",
            method="GET",
            path="/admin/services/data",
            title="Service status",
            summary="Live status, metrics, and log tail for every background service.",
            auth="admin",
            sample_response={
                "services": [{"name": "news", "status": "running", "enabled": True}]
            },
        ),
        endpoint(
            id="services-detail-data",
            method="GET",
            path="/admin/services/{name}/data",
            title="One service status",
            summary="Live status, metrics, and log tail for a single background service.",
            auth="admin",
            params=[field("name", "path", "string", True, "news", "Service name.")],
            sample_response={
                "service": {"name": "news", "status": "running", "enabled": True}
            },
        ),
        *_service_control_endpoints(),
    ]
    endpoints = control_endpoints + config_endpoints
    for ep in endpoints:
        ep["negotiation"] = _classify(ep)
    return {
        "slug": "services",
        "title": "Background Services",
        "admin": True,
        "intro": "\n".join(intro_parts),
        "endpoints": endpoints,
    }
