"""Unit tests for charging power scheduling helpers."""

from __future__ import annotations

from datetime import UTC, datetime, timedelta
from zoneinfo import ZoneInfo

from custom_components.tibber_prices.services.charging.deadline_solver import resolve_deadline
from custom_components.tibber_prices.services.charging.power_scheduler import build_power_schedule


def _make_intervals(prices: list[float]) -> list[dict[str, object]]:
    base = datetime(2026, 1, 1, 0, 0, tzinfo=UTC)
    return [
        {
            "startsAt": (base + timedelta(minutes=15 * index)).isoformat(),
            "total": price,
            "level": "NORMAL",
        }
        for index, price in enumerate(prices)
    ]


def test_continuous_mode_uses_partial_last_interval_power() -> None:
    """Continuous mode should reduce the last interval power when possible."""
    result = build_power_schedule(
        _make_intervals([0.20, 0.10, 0.15]),
        2.5,
        max_charge_power_w=4000,
        min_charge_power_w=1000,
        charging_efficiency=1.0,
    )

    assert result["mode"] == "continuous"
    assert result["total_grid_energy_kwh"] == 2.5
    assert sorted(interval["power_w"] for interval in result["intervals"]) == [2000, 4000, 4000]


def test_stepped_mode_uses_smallest_sufficient_step() -> None:
    """Stepped mode should choose the smallest allowed step that finishes the plan."""
    result = build_power_schedule(
        _make_intervals([0.20, 0.10, 0.15]),
        2.5,
        max_charge_power_w=4000,
        charge_power_steps_w=[1000, 2000, 4000],
        charging_efficiency=1.0,
    )

    assert result["mode"] == "stepped"
    assert result["total_grid_energy_kwh"] == 2.5
    assert sorted(interval["power_w"] for interval in result["intervals"]) == [2000, 4000, 4000]


def test_resolve_deadline_next_peak_period() -> None:
    """Deadline helper should resolve the next future peak period start."""
    now = datetime(2026, 1, 1, 0, 0, tzinfo=UTC)
    home_tz = ZoneInfo("UTC")
    coordinator_data = {
        "pricePeriods": {
            "peak_price": {
                "periods": [
                    {
                        "start": datetime(2026, 1, 1, 1, 0, tzinfo=UTC),
                        "end": datetime(2026, 1, 1, 2, 0, tzinfo=UTC),
                    }
                ]
            }
        }
    }

    deadline, source = resolve_deadline(
        coordinator_data=coordinator_data,
        now=now,
        home_tz=home_tz,
        must_reach_by_event="next_peak_period",
    )

    assert deadline == datetime(2026, 1, 1, 1, 0, tzinfo=UTC)
    assert source == "next_peak_period"
