#!/bin/env python
"""Sets the monitor temperature based on the current time using Hyprsunset"""
from datetime import datetime
from os import environ
from socket import AF_UNIX, SOCK_STREAM, socket


type Range = tuple[float, float]


def lerped_amount(x: float, edges: Range) -> float:
	"""How far `x` is between `values`"""
	return (x - edges[0]) / (edges[1] - edges[0])


def smoothstep(x: float, edges: Range) -> float:
	"""Smoothly interpolates between the `edges` based on `x`"""
	# Technically I should bounds check but whatever
	return (x * x * (3.0 - 2.0 * x)) * (edges[1] - edges[0]) + edges[0]


def day_elapsed(hours: int = 0, minutes: int = 0, seconds: int = 0) -> float:
	"""Converts (H, M, S) into [0, 1] representing how far through the day it is"""
	return ((((hours * 60) + minutes) * 60) + seconds) / 86400


def main(sunrise: Range, sunset: Range, temp_range: Range) -> None:
	"""Adjusts the monitor temperature based on the current time"""
	now = datetime.now()
	elapsed = day_elapsed(now.hour, now.minute, now.second)

	if elapsed <= sunrise[0]:
		temperature = temp_range[0]
	elif elapsed < sunrise[1]:
		temperature = smoothstep(lerped_amount(elapsed, sunrise), temp_range)
	elif elapsed <= sunset[0]:
		temperature = temp_range[1]
	elif elapsed < sunset[1]:
		temperature = smoothstep(lerped_amount(elapsed, sunset), (temp_range[1], temp_range[0]))
	else:
		temperature = temp_range[0]

	hyprsunset = socket(AF_UNIX, SOCK_STREAM)
	# In theory I should use $XDG_RUNTIME_DIR, but for me it's always `/run/user/1000/`
	hyprsunset.connect(f"/run/user/1000/hypr/{environ["HYPRLAND_INSTANCE_SIGNATURE"]}/.hyprsunset.sock")
	# In theory the message might not send in one go, but in practice it does do I won't bother handling it
	_ = hyprsunset.send(f"temperature {temperature:.1f}".encode())


if __name__ == "__main__":
	main(
		(day_elapsed(5), day_elapsed(7)),
		(day_elapsed(21), day_elapsed(23)),
		(2500.0, 6000.0)
	)
