"""IT-AUD-001 / IT-ALT-001 — audit and alert history pagination."""

from __future__ import annotations

import pytest
from fastapi import HTTPException

from server.api.settings import alert_stats, list_alert_history, list_audit_logs
from server.domain.models import AuditLog

pytestmark = pytest.mark.integration


@pytest.mark.asyncio
async def test_audit_logs_paginated(db_session, test_admin):
    db_session.add(
        AuditLog(
            admin_username=test_admin["admin"].username,
            action="test_action",
            target_type="test",
            target_id=1,
            detail="integration test",
        )
    )
    await db_session.commit()

    body = await list_audit_logs(
        action=None,
        admin_username=None,
        date_from=None,
        date_to=None,
        limit=10,
        offset=0,
        admin=test_admin["admin"],
        db=db_session,
    )
    assert body["total"] >= 1
    assert len(body["items"]) >= 1
    assert body["items"][0]["action"] == "test_action"


@pytest.mark.asyncio
async def test_audit_logs_server_target_name(db_session, test_admin):
    from server.domain.models import Server

    server = Server(name="audit-target-web", domain="at.example.com", port=22)
    db_session.add(server)
    await db_session.flush()
    db_session.add(
        AuditLog(
            admin_username=test_admin["admin"].username,
            action="watch_install_psutil",
            target_type="server",
            target_id=server.id,
            detail="SSH 安装 psutil",
        )
    )
    await db_session.commit()

    body = await list_audit_logs(
        action=None,
        admin_username=None,
        date_from=None,
        date_to=None,
        limit=10,
        offset=0,
        admin=test_admin["admin"],
        db=db_session,
    )
    row = next(i for i in body["items"] if i.get("action") == "watch_install_psutil")
    assert row["target_name"] == "audit-target-web"


@pytest.mark.asyncio
async def test_alert_history_list_200(db_session, test_admin):
    body = await list_alert_history(
        server_id=None,
        alert_type=None,
        is_recovery=None,
        status=None,
        date_from=None,
        date_to=None,
        page=1,
        per_page=10,
        limit=10,
        offset=0,
        admin=test_admin["admin"],
        db=db_session,
    )
    assert "items" in body
    assert "total" in body
    assert body["page"] == 1
    assert body["per_page"] == 10


@pytest.mark.asyncio
async def test_alert_history_status_filter_alias(db_session, test_admin):
    body = await list_alert_history(
        server_id=None,
        alert_type=None,
        is_recovery=None,
        status="active",
        date_from=None,
        date_to=None,
        page=None,
        per_page=None,
        limit=50,
        offset=0,
        admin=test_admin["admin"],
        db=db_session,
    )
    assert "items" in body
    for item in body["items"]:
        assert item["is_recovery"] is False


@pytest.mark.asyncio
async def test_audit_logs_invalid_date_from_422(db_session, test_admin):
    with pytest.raises(HTTPException) as exc:
        await list_audit_logs(
            action=None,
            admin_username=None,
            date_from="not-a-date",
            date_to=None,
            limit=10,
            offset=0,
            admin=test_admin["admin"],
            db=db_session,
        )
    assert exc.value.status_code == 422


@pytest.mark.asyncio
async def test_alert_history_invalid_date_to_422(db_session, test_admin):
    with pytest.raises(HTTPException) as exc:
        await list_alert_history(
            server_id=None,
            alert_type=None,
            is_recovery=None,
            status=None,
            date_from=None,
            date_to="2026-13-40",
            page=1,
            per_page=10,
            limit=10,
            offset=0,
            admin=test_admin["admin"],
            db=db_session,
        )
    assert exc.value.status_code == 422


@pytest.mark.asyncio
async def test_alert_stats_frontend_fields(db_session, test_admin):
    stats = await alert_stats(days=7, admin=test_admin["admin"], db=db_session)
    for key in ("today", "active", "recovered", "top_server", "top_types", "top_servers", "daily"):
        assert key in stats
