"""Metered usage billing operations."""

from __future__ import annotations

import time

import stripe

from billing.subscriptions import _get_customer_id


def _get_subscription_item_id(user_id: str, metric: str) -> str:
    """Find the subscription item for a given metered metric.

    Looks up the user's active subscription and finds the line item
    whose price has a lookup_key matching the metric name.

    Args:
        user_id: Internal user identifier.
        metric: The usage metric name (should match a Stripe price lookup_key).

    Returns:
        Stripe subscription item ID.

    Raises:
        ValueError: If no matching subscription item is found.
    """
    customer_id = _get_customer_id(user_id)

    subscriptions = stripe.Subscription.list(
        customer=customer_id,
        status="active",
        limit=1,
        expand=["data.items.data.price"],
    )

    if not subscriptions.data:
        raise ValueError(f"No active subscription for user_id '{user_id}'")

    for item in subscriptions.data[0]["items"]["data"]:
        price = item["price"]
        if price.get("lookup_key") == metric or price.get("id") == metric:
            return item.id

    raise ValueError(
        f"No subscription item found for metric '{metric}' on user '{user_id}'. "
        "Ensure the Stripe price has a lookup_key matching the metric name."
    )


def record_usage(user_id: str, metric: str, quantity: int = 1) -> None:
    """Record metered usage for a subscription item.

    Args:
        user_id: Internal user identifier.
        metric: The usage metric name (matches Stripe price lookup_key).
        quantity: Number of units to record. Defaults to 1.

    Raises:
        ValueError: If no matching subscription item is found.
        stripe.StripeError: On Stripe API failures.
    """
    subscription_item_id = _get_subscription_item_id(user_id, metric)

    stripe.SubscriptionItem.create_usage_record(
        subscription_item_id,
        quantity=quantity,
        timestamp=int(time.time()),
        action="increment",
    )


def get_usage(
    user_id: str,
    metric: str,
    period_start: int | None = None,
) -> int:
    """Get total metered usage for a subscription item in the current period.

    Args:
        user_id: Internal user identifier.
        metric: The usage metric name.
        period_start: Unix timestamp for the start of the period to query.
            Defaults to the current subscription period start.

    Returns:
        Total quantity used in the period.

    Raises:
        ValueError: If no matching subscription item is found.
        stripe.StripeError: On Stripe API failures.
    """
    subscription_item_id = _get_subscription_item_id(user_id, metric)

    # Fetch usage record summaries for the period
    summaries = stripe.SubscriptionItem.list_usage_record_summaries(
        subscription_item_id,
        limit=100,
    )

    total = 0
    for summary in summaries.auto_paging_iter():
        # Filter by period_start if provided
        if period_start is not None and summary.period.start < period_start:
            continue
        total += summary.total_usage

    return total
