"""Per-server CPU/mem time-series samples (server list expand trends)."""

from __future__ import annotations

from datetime import datetime, timedelta, timezone

from sqlalchemy import delete, select
from sqlalchemy.ext.asyncio import AsyncSession

from server.domain.models import ServerMetricSample
from server.infrastructure.database.fleet_metric_repo import (
    FLEET_METRIC_RETENTION_DAYS,
    FLUSH_INTERVAL_MINUTES,
)
from server.utils.display_time import to_naive_utc

__all__ = ["FLUSH_INTERVAL_MINUTES", "ServerMetricRepositoryImpl"]


class ServerMetricRepositoryImpl:
    def __init__(self, session: AsyncSession):
        self.session = session

    async def insert_sample(
        self,
        *,
        server_id: int,
        recorded_at: datetime,
        is_online: bool,
        cpu_pct: int | None,
        mem_pct: int | None,
    ) -> ServerMetricSample:
        row = ServerMetricSample(
            server_id=server_id,
            recorded_at=to_naive_utc(recorded_at),
            is_online=is_online,
            cpu_pct=cpu_pct,
            mem_pct=mem_pct,
        )
        self.session.add(row)
        await self.session.flush()
        return row

    async def list_since(self, server_id: int, since_utc: datetime) -> list[ServerMetricSample]:
        since_naive = to_naive_utc(since_utc)
        result = await self.session.execute(
            select(ServerMetricSample)
            .where(
                ServerMetricSample.server_id == server_id,
                ServerMetricSample.recorded_at >= since_naive,
            )
            .order_by(ServerMetricSample.recorded_at.asc())
        )
        return list(result.scalars().all())

    async def purge_older_than(self, days: int = FLEET_METRIC_RETENTION_DAYS) -> int:
        cutoff = datetime.now(timezone.utc) - timedelta(days=days)
        cutoff_naive = to_naive_utc(cutoff)
        result = await self.session.execute(
            delete(ServerMetricSample).where(ServerMetricSample.recorded_at < cutoff_naive)
        )
        return int(result.rowcount or 0)
