<?php
namespace Planaday\Utility;

use DateTime;

class DateAndTimeUtility
{
	public const SECONDS_IN_HOUR = 3600;
	public const SECONDS_IN_MINUTE = 60;
	public const SECONDS_IN_DAY = 86400;

	public const DATE_FORMAT = "Y-m-d";
	public const DATE_TIME_FORMAT = "Y-m-d H:i:s";

    public function currentDate(): string {
        return date(self::DATE_FORMAT);
    }

    public function currentDateTime(): string {
        return date(self::DATE_TIME_FORMAT, time());
    }

	public function dateTimeAt(int $time): string {
		return date(self::DATE_TIME_FORMAT, $time);
	}

    public function dateTimeInPast(int $hours): string {
        $currentTime = time();
        $timeToSubtract = ($hours * 60 * 60);
        $timeInPast = $currentTime - $timeToSubtract;

        return date(self::DATE_TIME_FORMAT, $timeInPast);
    }

    public function addMonths(int $amountOfMonths): string {
	    $time = strtotime(self::currentDate() . " +" . $amountOfMonths . " months");
	    if ($time === false) return '';

        return date(self::DATE_FORMAT, $time );
    }

    public function getReadableData(string|int $time): string {
		if (is_string($time)) $time = strtotime($time);
		if ( $time === false) return '';

        return $this->getReadableDate((new DateTime())->setTimestamp($time));
    }

	public function getReadableDate( DateTime $date): string {
		$dayNumber = (int) $date->format("d");
		$dayOfTheWeek = (int) $date->format("w");
		$monthOfTheYear = (int) $date->format("n") - 1;
		$year = (int) $date->format("Y");

		$days = ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'];
		$months = ['januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december'];
		$currentDay = $days[$dayOfTheWeek];
		$currentMonth = $months[$monthOfTheYear];

		return $currentDay . " " . $dayNumber . " " . $currentMonth . " " . $year;
	}

	/**
	 * @param int $time1 later time
	 * @param int $time2 earlier time
	 *
	 * @return string
	 */
	public function getTimeDifferenceAsString(int $time1, int $time2): string {
		$timeDifference = $time1 - $time2;
		$hours          = floor( $timeDifference / self::SECONDS_IN_HOUR );
		$minutes        = sprintf('%02d', floor( ( $timeDifference % self::SECONDS_IN_HOUR ) / self::SECONDS_IN_MINUTE ));
		$seconds        = sprintf('%02d', $timeDifference % self::SECONDS_IN_MINUTE);

		return $hours . ":" . $minutes . ":" . $seconds;
	}

	public function getNowMilliseconds():float {
		return microtime(true) * 1000;
	}

	public function getNowMillisecondsString():string {
		return number_format(self::getNowMilliseconds(), 4);
	}

	public function getReadableTimestampWithMilli( float $milli): string {
		return date("Y-m-d H:m:s", (int)floor( $milli / 1000)) .
		       '.' . substr(number_format((($milli * 1000) % 1000000)/1000 + 1000),2) . ' GMT';
	}
}

