"""Jail response mappers.

Convert domain models (from jail_service) to response models (for HTTP API).

This is the mapping layer at the router boundary, ensuring the service layer
remains independent of HTTP response shapes.
"""

from __future__ import annotations

from app.models.ban import ActiveBan, JailBannedIpsResponse
from app.models.ban_domain import DomainActiveBan
from app.models.jail import (
    Jail,
    JailDetailResponse,
    JailListResponse,
    JailStatus,
    JailSummary,
)
from app.models.jail_domain import (
    DomainJailBannedIps,
    DomainBantimeEscalation,
    DomainJail,
    DomainJailDetail,
    DomainJailList,
    DomainJailStatus,
    DomainJailSummary,
)
from app.utils.pagination import create_pagination_metadata


def _map_domain_jail_status(domain: DomainJailStatus) -> JailStatus:
    """Convert domain jail status to response model."""
    return JailStatus(
        currently_banned=domain.currently_banned,
        total_banned=domain.total_banned,
        currently_failed=domain.currently_failed,
        total_failed=domain.total_failed,
    )


def _map_domain_bantime_escalation(domain: DomainBantimeEscalation) -> object:
    """Convert domain bantime escalation to response model."""
    from app.models.config import BantimeEscalation

    return BantimeEscalation(
        increment=domain.increment,
        factor=domain.factor,
        formula=domain.formula,
        multipliers=domain.multipliers,
        max_time=domain.max_time,
        rnd_time=domain.rnd_time,
        overall_jails=domain.overall_jails,
    )


def map_domain_jail_summary_to_response(domain: DomainJailSummary) -> JailSummary:
    """Convert domain jail summary to response model."""
    return JailSummary(
        name=domain.name,
        enabled=domain.enabled,
        running=domain.running,
        idle=domain.idle,
        backend=domain.backend,
        find_time=domain.find_time,
        ban_time=domain.ban_time,
        max_retry=domain.max_retry,
        status=_map_domain_jail_status(domain.status) if domain.status else None,
    )


def map_domain_jail_list_to_response(domain_list: DomainJailList) -> JailListResponse:
    """Convert domain jail list to response model."""
    return JailListResponse(
        items=[map_domain_jail_summary_to_response(j) for j in domain_list.items],
        total=domain_list.total,
    )


def map_domain_jail_to_response(domain: DomainJail) -> Jail:
    """Convert domain jail to response model."""
    return Jail(
        name=domain.name,
        enabled=domain.enabled,
        running=domain.running,
        idle=domain.idle,
        backend=domain.backend,
        log_paths=domain.log_paths,
        fail_regex=domain.fail_regex,
        ignore_regex=domain.ignore_regex,
        ignore_ips=domain.ignore_ips,
        date_pattern=domain.date_pattern,
        log_encoding=domain.log_encoding,
        find_time=domain.find_time,
        ban_time=domain.ban_time,
        max_retry=domain.max_retry,
        actions=domain.actions,
        bantime_escalation=(
            _map_domain_bantime_escalation(domain.bantime_escalation)
            if domain.bantime_escalation
            else None
        ),
        status=_map_domain_jail_status(domain.status) if domain.status else None,
    )


def map_domain_jail_detail_to_response(domain: DomainJailDetail) -> JailDetailResponse:
    """Convert domain jail detail to response model."""
    return JailDetailResponse(
        jail=map_domain_jail_to_response(domain.jail),
        ignore_list=domain.ignore_list,
        ignore_self=domain.ignore_self,
    )


def map_domain_jail_banned_ips_to_response(
    domain: DomainJailBannedIps,
) -> JailBannedIpsResponse:
    """Convert domain jail banned IPs to response model."""
    return JailBannedIpsResponse(
        items=[
            ActiveBan(
                ip=ban.ip,
                jail=ban.jail,
                banned_at=ban.banned_at,
                expires_at=ban.expires_at,
                ban_count=ban.ban_count,
                country=ban.country,
            )
            for ban in domain.items
        ],
        pagination=create_pagination_metadata(domain.total, domain.page, domain.page_size),
    )
