#!/usr/bin/env python3
"""
alltemps.py - continuously tracks running min/max temperature.

Reads the current temperature from temperature.txt once a minute, keeps
running minimum and maximum values (with the time each was recorded) and
writes them to:

    mintemp.txt, mintemptime.txt, maxtemp.txt, maxtemptime.txt, temprange.txt

At midnight, both min and max are reset to the current temperature.
"""

import time
from datetime import datetime

INPUT_FILE = "temperature.txt"
MIN_TEMP_FILE = "mintemp.txt"
MIN_TIME_FILE = "mintemptime.txt"
MAX_TEMP_FILE = "maxtemp.txt"
MAX_TIME_FILE = "maxtemptime.txt"
RANGE_FILE = "temprange.txt"
INTERVAL = 60  # seconds


def read_temperature():
    """Return the temperature from INPUT_FILE as a float, or None on failure."""
    try:
        with open(INPUT_FILE, "r") as f:
            return float(f.read().strip())
    except (OSError, ValueError) as e:
        print(f"Could not read a valid temperature from {INPUT_FILE}: {e}")
        return None


def write_value(filename, value):
    """Write a single value to a file."""
    try:
        with open(filename, "w") as f:
            f.write(f"{value}\n")
    except OSError as e:
        print(f"Could not write {filename}: {e}")


def save_all(min_temp, min_time, max_temp, max_time):
    write_value(MIN_TEMP_FILE, min_temp)
    write_value(MIN_TIME_FILE, min_time)
    write_value(MAX_TEMP_FILE, max_temp)
    write_value(MAX_TIME_FILE, max_time)
    write_value(RANGE_FILE, round(max_temp - min_temp, 2))


def seconds_until_next_minute():
    """Sleep time so readings land on the start of each minute (incl. midnight)."""
    now = time.time()
    return INTERVAL - (now % INTERVAL)


def main():
    min_temp = max_temp = None
    min_time = max_time = None
    last_date = None

    print("alltemps.py started. Press Ctrl+C to stop.")

    try:
        while True:
            now = datetime.now()
            now_str = now.strftime("%Y-%m-%d %H:%M:%S")
            temp = read_temperature()

            if temp is not None:
                new_day = last_date is not None and now.date() != last_date

                if min_temp is None or new_day:
                    # First reading, or midnight: reset both to current temp
                    min_temp = max_temp = temp
                    min_time = max_time = now_str
                    if new_day:
                        print("--- Midnight reset ---")
                else:
                    if temp < min_temp:
                        min_temp, min_time = temp, now_str
                    if temp > max_temp:
                        max_temp, max_time = temp, now_str

                last_date = now.date()
                save_all(min_temp, min_time, max_temp, max_time)

                print(f"[{now_str}]")
                print(f"  Current temp : {temp}")
                print(f"  Min temp     : {min_temp}  (at {min_time})")
                print(f"  Max temp     : {max_temp}  (at {max_time})")
                print(f"  Temp range   : {round(max_temp - min_temp, 2)}")
                print()

            time.sleep(seconds_until_next_minute())

    except KeyboardInterrupt:
        print("\nStopped.")


if __name__ == "__main__":
    main()
