from datetime import datetime, timedelta
from typing import TYPE_CHECKING

from .common import (
    ChartBounds,
    FontType,
    RenderMetrics,
    measure_text,
)

if TYPE_CHECKING:
    from PIL import ImageDraw

TEMPERATURE_LABEL_SAMPLE = "00"
CHART_HOURS = 24


def build_hour_slots(now: datetime, hours: int) -> list[datetime]:
    start_hour = now.replace(minute=0, second=0, microsecond=0)
    return [start_hour + timedelta(hours=offset) for offset in range(hours)]


def compute_x_axis_y(
    draw: ImageDraw.ImageDraw,
    font: FontType,
    chart_top: int,
    chart_bottom: int,
    plot_padding: int,
) -> int:
    _, label_height, _ = measure_text(draw, font, TEMPERATURE_LABEL_SAMPLE)
    x_axis_y = round(chart_bottom - label_height - (3 * plot_padding))
    if x_axis_y <= chart_top + (2 * plot_padding):
        message = "Chart bounds are too short to place the x-axis"
        raise ValueError(message)
    return x_axis_y


def build_chart_context(
    draw: ImageDraw.ImageDraw,
    font: FontType,
    chart_bounds: ChartBounds,
    now: datetime,
    metrics: RenderMetrics,
) -> tuple[list[datetime], int]:
    if (
        chart_bounds.right <= chart_bounds.left + metrics.min_chart_dimension
        or chart_bounds.bottom <= chart_bounds.top + metrics.min_chart_dimension
    ):
        message = "Chart bounds are too small to render the dashboard charts"
        raise ValueError(message)

    x_axis_y = compute_x_axis_y(
        draw=draw,
        font=font,
        chart_top=chart_bounds.top,
        chart_bottom=chart_bounds.bottom,
        plot_padding=metrics.plot_padding,
    )
    return build_hour_slots(now, CHART_HOURS), x_axis_y
