import math
from datetime import date, timedelta
from decimal import Decimal

from pandas._libs.tslibs.offsets import BDay

from wbportfolio.preferences import get_product_termination_notice_period


def get_next_termination_reminder_businessdate(delisted_date: date, today: date) -> date | None:
    """Computes next business day reminder using geometric interval from delisted_date.

    Args:
        delisted_date: Product termination date.
        today: Current date.

    Returns:
        Next reminder business date or delisted_date if imminent.
    """
    remaining_days = (delisted_date - today).days
    initial_period_days = get_product_termination_notice_period()
    if remaining_days <= 1:
        return delisted_date + timedelta(days=1)

    # Geometric step: 2^(log2(ratio)-1)
    interval = pow(2, int(math.log2(remaining_days / initial_period_days)) - 1)
    next_termination_reminder_date = delisted_date - timedelta(days=int(initial_period_days * interval))

    # Weekend → next business day
    return (next_termination_reminder_date - timedelta(days=1) + BDay(1)).date()


def get_termination_message(product, today: date) -> str:
    day_until_termination = (product.delisted_date - today).days
    humanized_days = "tomorrow" if day_until_termination == 1 else f"{day_until_termination} days"
    return f"The product {product} will be terminated in {humanized_days} ({product.delisted_date:%Y-%m-%d}). Please act accordingly."


def get_adjusted_shares(old_shares: Decimal, old_price: Decimal, new_price: Decimal) -> Decimal:
    return old_shares * (old_price / new_price)
