<?php

declare(strict_types=1);

namespace App\Services;

use DateInterval;
use DateTimeImmutable;
use DateTimeZone;

final class SunTimesService
{
    public function forRange(array $tenant, string $from, string $to): array
    {
        $latitude = isset($tenant['latitude']) ? (float) $tenant['latitude'] : null;
        $longitude = isset($tenant['longitude']) ? (float) $tenant['longitude'] : null;
        $timezoneName = (string) ($tenant['timezone'] ?? 'Europe/Berlin');

        if ($latitude === null || $longitude === null || $latitude === 0.0 && $longitude === 0.0) {
            return [];
        }

        $timezone = new DateTimeZone($timezoneName);
        $start = new DateTimeImmutable($from, new DateTimeZone('UTC'));
        $end = new DateTimeImmutable($to, new DateTimeZone('UTC'));
        $day = $start->setTimezone($timezone)->setTime(0, 0);
        $lastDay = $end->setTimezone($timezone)->setTime(0, 0);

        $result = [];
        while ($day < $lastDay) {
            $solar = date_sun_info($day->setTime(12, 0)->getTimestamp(), $latitude, $longitude);
            $key = $day->format('Y-m-d');

            $result[$key] = [
                'sunrise' => $this->formatSolarTimestamp($solar['sunrise'] ?? false, $timezone),
                'sunset' => $this->formatSolarTimestamp($solar['sunset'] ?? false, $timezone),
            ];

            $day = $day->add(new DateInterval('P1D'));
        }

        return $result;
    }

    private function formatSolarTimestamp(int|float|bool $timestamp, DateTimeZone $timezone): ?string
    {
        if (!is_int($timestamp) && !is_float($timestamp)) {
            return null;
        }

        return (new DateTimeImmutable('@' . (string) (int) $timestamp))
            ->setTimezone($timezone)
            ->format('H:i');
    }
}
