"""Fast, explainable pre-run credit estimates for the builder UI."""
from __future__ import annotations

from collections.abc import Iterable
from dataclasses import dataclass
from math import ceil


@dataclass(frozen=True)
class CodegenCreditEstimate:
    minimum_credits: int
    maximum_credits: int
    prompt_credits: int
    attachment_credits: int


def estimate_codegen_credits(
    *,
    prompt: str,
    attachment_sizes: Iterable[int] = (),
    attachment_count: int = 0,
) -> CodegenCreditEstimate:
    """Return a conservative range, not a pricing promise.

    Runtime is still the billable source of truth.  This deliberately uses only
    information available before the agent reads the files: prompt size and the
    number/size of attachments.
    """
    prompt_credits = max(0, ceil(len((prompt or "").strip()) / 900))
    sizes = list(attachment_sizes)
    attachment_credits = sum(max(1, ceil(size / (5 * 1024 * 1024))) for size in sizes)
    attachment_credits += max(0, attachment_count - len(sizes))
    complexity_credits = prompt_credits + attachment_credits
    minimum = 5 if complexity_credits <= 1 else 5 + complexity_credits
    maximum = max(minimum, minimum * 3)
    return CodegenCreditEstimate(
        minimum_credits=minimum,
        maximum_credits=maximum,
        prompt_credits=prompt_credits,
        attachment_credits=attachment_credits,
    )
