"""
TLD pricing snapshot (open-data via internal DB).

Uses our own collected TLD price history (no external API calls here).
"""

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime
from typing import Optional

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

from app.models.tld_price import TLDPrice


@dataclass(frozen=True)
class TldPriceSnapshot:
    tld: str
    min_register_usd: Optional[float]
    min_register_registrar: Optional[str]
    min_renew_usd: Optional[float]
    min_renew_registrar: Optional[str]
    min_transfer_usd: Optional[float]
    min_transfer_registrar: Optional[str]
    latest_recorded_at: Optional[datetime]


async def get_tld_price_snapshot(db: AsyncSession, tld: str) -> TldPriceSnapshot:
    tld = (tld or "").lower().lstrip(".")

    # Latest record per registrar for this TLD, then take min renew.
    subq = (
        select(
            TLDPrice.registrar,
            func.max(TLDPrice.recorded_at).label("max_date"),
        )
        .where(TLDPrice.tld == tld)
        .group_by(TLDPrice.registrar)
        .subquery()
    )

    rows = (
        await db.execute(
            select(TLDPrice)
            .join(
                subq,
                (TLDPrice.registrar == subq.c.registrar)
                & (TLDPrice.recorded_at == subq.c.max_date),
            )
            .where(TLDPrice.tld == tld)
        )
    ).scalars().all()

    if not rows:
        return TldPriceSnapshot(
            tld=tld,
            min_register_usd=None,
            min_register_registrar=None,
            min_renew_usd=None,
            min_renew_registrar=None,
            min_transfer_usd=None,
            min_transfer_registrar=None,
            latest_recorded_at=None,
        )

    def _reg_price(r) -> float:
        return float(r.registration_price or 1e12)

    def _renew_price(r) -> float:
        return float(r.renewal_price or r.registration_price or 1e12)

    def _transfer_price(r) -> float:
        return float(r.transfer_price or r.registration_price or 1e12)

    best_reg = min(rows, key=_reg_price)
    best_renew = min(rows, key=_renew_price)
    best_transfer = min(rows, key=_transfer_price)
    latest = max((r.recorded_at for r in rows if r.recorded_at), default=None)

    return TldPriceSnapshot(
        tld=tld,
        min_register_usd=float(best_reg.registration_price),
        min_register_registrar=str(best_reg.registrar),
        min_renew_usd=float(best_renew.renewal_price or best_renew.registration_price),
        min_renew_registrar=str(best_renew.registrar),
        min_transfer_usd=float(best_transfer.transfer_price or best_transfer.registration_price),
        min_transfer_registrar=str(best_transfer.registrar),
        latest_recorded_at=latest,
    )

