"""Utilities for generating test data."""

import random
from collections.abc import Iterator
from datetime import datetime, timedelta


def generate_timeseries(
    metric: str,
    role: str,
    days: int = 7,
    interval_minutes: int = 15,
    base_value: float = 3.8,
    variance: float = 0.2,
) -> Iterator[tuple[int, float]]:
    """Generate sample time series data.

    Yields (timestamp, value) tuples with realistic variance patterns.

    Args:
        metric: Metric name (for documentation)
        role: Role name (for documentation)
        days: Number of days of data to generate
        interval_minutes: Minutes between data points
        base_value: Base value around which to vary
        variance: Maximum random variance from base

    Yields:
        (timestamp, value) tuples
    """
    now = datetime.now()
    points = int(days * 24 * 60 / interval_minutes)

    for i in range(points):
        ts = now - timedelta(minutes=i * interval_minutes)
        # Add a diurnal pattern (higher at noon)
        hour_factor = 0.1 * abs(12 - ts.hour) / 12
        value = base_value + random.uniform(-variance, variance) + hour_factor
        yield (int(ts.timestamp()), value)


def generate_counter_with_reboots(
    start_value: int = 0,
    readings: int = 100,
    reboot_probability: float = 0.05,
    increment_range: tuple[int, int] = (1, 50),
) -> list[tuple[datetime, int]]:
    """Generate counter values with occasional reboots.

    Simulates a monotonically increasing counter that occasionally
    resets to a low value (simulating device reboot).

    Args:
        start_value: Initial counter value
        readings: Number of readings to generate
        reboot_probability: Chance of reboot at each reading (0.0 to 1.0)
        increment_range: (min, max) range for counter increments

    Returns:
        List of (datetime, value) tuples
    """
    now = datetime.now()
    values: list[tuple[datetime, int]] = []
    current = start_value

    for i in range(readings):
        ts = now - timedelta(minutes=(readings - i) * 15)

        if random.random() < reboot_probability:
            # Simulate reboot - counter resets to small value
            current = random.randint(0, 100)
        else:
            # Normal increment
            current += random.randint(*increment_range)

        values.append((ts, current))

    return values


def generate_battery_discharge_curve(
    hours: int = 24,
    interval_minutes: int = 15,
    start_voltage: float = 4.2,
    end_voltage: float = 3.5,
) -> list[tuple[int, float]]:
    """Generate a realistic battery discharge curve.

    Simulates 18650 Li-ion discharge with realistic curve shape.

    Args:
        hours: Duration of discharge in hours
        interval_minutes: Minutes between readings
        start_voltage: Starting voltage (fully charged)
        end_voltage: Ending voltage

    Returns:
        List of (timestamp, voltage_mv) tuples (millivolts)
    """
    now = datetime.now()
    points = int(hours * 60 / interval_minutes)
    values: list[tuple[int, float]] = []

    for i in range(points):
        ts = now - timedelta(minutes=(points - i) * interval_minutes)
        # Simple linear discharge with some noise
        progress = i / points
        voltage = start_voltage - (start_voltage - end_voltage) * progress
        # Add small random variation
        voltage += random.uniform(-0.02, 0.02)
        values.append((int(ts.timestamp()), voltage * 1000))  # Convert to mV

    return values
