"""Synthetic sampling-interval and alert-latency study.

This is a generic engineering model, not a claim about a specific sensor's measured performance.
"""
from __future__ import annotations

import math
import random
from dataclasses import dataclass

import matplotlib.pyplot as plt
import numpy as np


@dataclass(frozen=True)
class Case:
    interval_seconds: int
    moving_average_samples: int


def true_temperature(seconds: np.ndarray) -> np.ndarray:
    baseline = 22.0
    start = 10 * 60
    end = 20 * 60
    rise = np.clip((seconds - start) / (end - start), 0.0, 1.0)
    return baseline + 6.0 * rise


def simulate(case: Case, seed: int = 7) -> tuple[np.ndarray, np.ndarray, np.ndarray, float | None]:
    rng = np.random.default_rng(seed)
    seconds = np.arange(0, 30 * 60 + case.interval_seconds, case.interval_seconds)
    truth = true_temperature(seconds)
    measured = truth + rng.normal(0.0, 0.25, size=len(seconds))
    window = max(1, case.moving_average_samples)
    kernel = np.ones(window) / window
    filtered = np.convolve(measured, kernel, mode="valid")
    filtered_seconds = seconds[window - 1 :]
    hits = np.flatnonzero(filtered >= 26.0)
    alert_time = float(filtered_seconds[hits[0]]) if len(hits) else None
    return seconds, measured, filtered_seconds, filtered, alert_time


def main() -> None:
    cases = [Case(5, 3), Case(15, 3), Case(30, 2), Case(60, 2)]
    dense_seconds = np.arange(0, 30 * 60 + 1, 1)
    plt.figure(figsize=(10, 6))
    plt.plot(dense_seconds / 60, true_temperature(dense_seconds), label="True temperature", linewidth=2)

    for case in cases:
        _, _, filtered_seconds, filtered, alert_time = simulate(case)
        label = f"{case.interval_seconds}s interval"
        plt.plot(filtered_seconds / 60, filtered, label=label, alpha=0.9)
        if alert_time is not None:
            delay = alert_time - (10 * 60 + (4 / 6) * 10 * 60)
            print(f"{label}: alert at {alert_time/60:.2f} min; approximate delay {delay:.0f} s")

    plt.axhline(26.0, linestyle="--", label="Alert threshold")
    plt.xlabel("Time (minutes)")
    plt.ylabel("Temperature (C)")
    plt.title("Synthetic sampling interval and alert latency study")
    plt.legend()
    plt.tight_layout()
    plt.show()


if __name__ == "__main__":
    main()
