<?php

namespace SugarCalendarBookings\Support\Helpers;

use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;

/**
 * Time helper.
 *
 * @since 1.0.0
 */
class Time {

	/**
	 * Convert minutes to human readable duration.
	 *
	 * @since 1.0.0
	 *
	 * @param int $minutes Duration in minutes.
	 *
	 * @return string Human readable duration (e.g., "2h 30m" or "45m").
	 */
	public static function human_readable_duration( $minutes ) {

		if ( $minutes <= 0 ) {
			return '';
		}

		$parts = [];

		// Hours.
		$hours = floor( $minutes / 60 );

		if ( $hours > 0 ) {
			$parts[] = $hours . 'h';
			$minutes = $minutes % 60;
		}

		// Remaining minutes.
		if ( $minutes > 0 ) {
			$parts[] = $minutes . 'm';
		}

		return implode( ' ', $parts );
	}

	/**
	 * Convert minutes to the most appropriate unit (hours or minutes).
	 *
	 * @since 1.0.0
	 *
	 * @param int $minutes Duration in minutes.
	 *
	 * @return array{value: int, unit: string} Duration with the most appropriate unit.
	 */
	public static function convert_duration( $minutes ) {

		if ( $minutes <= 0 ) {
			return [
				'value' => 0,
				'unit'  => 'min',
			];
		}

		if ( $minutes % 60 === 0 ) {
			return [
				'value' => $minutes / 60,
				'unit'  => 'hr',
			];
		}

		return [
			'value' => $minutes,
			'unit'  => 'min',
		];
	}

	/**
	 * Format time periods (ranges) for display.
	 *
	 * Converts an array of time periods with start/end minutes to formatted time range strings.
	 *
	 * @since 1.1.0
	 *
	 * @param array  $periods     Array of time periods with 'start' and 'end' keys (in minutes from midnight).
	 * @param string $time_format PHP time format string (e.g., 'g:i a', 'H:i'). If null, uses WordPress time format.
	 * @param string $separator   Separator between start and end times (default: ' - ').
	 * @param string $glue        Glue for multiple periods (default: ', ').
	 *
	 * @return string Formatted time periods string (e.g., "9:00 am - 5:00 pm, 7:00 pm - 9:00 pm").
	 */
	public static function format_time_periods( $periods, $time_format = null, $separator = ' - ', $glue = ', ' ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh

		if ( empty( $periods ) ) {
			return '';
		}

		// Get default time format if not provided.
		if ( $time_format === null ) {
			$time_format = get_option( 'time_format' );
		}

		$time_strings = [];

		foreach ( $periods as $period ) {
			$start = $period['start'] ?? 0;
			$end   = $period['end'] ?? 0;

			$start_hours = floor( $start / 60 );
			$start_mins  = $start % 60;
			$end_hours   = floor( $end / 60 );
			$end_mins    = $end % 60;

			$start_time = DateTime::createFromFormat( 'H:i', sprintf( '%02d:%02d', $start_hours, $start_mins ) );
			$end_time   = DateTime::createFromFormat( 'H:i', sprintf( '%02d:%02d', $end_hours, $end_mins ) );

			// Skip invalid time periods.
			if ( ! $start_time || ! $end_time ) {
				continue;
			}

			$time_strings[] = sprintf(
				'%1$s%2$s%3$s',
				$start_time->format( $time_format ),
				$separator,
				$end_time->format( $time_format )
			);
		}

		return implode( $glue, $time_strings );
	}

	/**
	 * Get minutes from midnight for a given datetime.
	 *
	 * @since 1.4.0
	 *
	 * @param DateTimeInterface $dt Datetime instance.
	 *
	 * @return int Minutes from midnight (0-1439).
	 */
	public static function minutes_from_midnight( DateTimeInterface $dt ): int {

		return (int) $dt->format( 'G' ) * 60 + (int) $dt->format( 'i' );
	}

	/**
	 * Get valid timezone UTC offsets.
	 *
	 * Returns an array of valid UTC offset values that WordPress core supports.
	 *
	 * @since 1.2.0
	 *
	 * @see wp_timezone_choice() in wp-includes/functions.php
	 *
	 * @return array Array of valid UTC offset values (floats).
	 */
	public static function get_valid_timezone_offsets() {

		// phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine
		return [ -12.0, -11.5, -11.0, -10.5, -10.0, -9.5, -9.0, -8.5, -8.0, -7.5, -7.0, -6.5, -6.0, -5.5, -5.0, -4.5, -4.0, -3.5, -3.0, -2.5, -2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 5.75, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 8.75, 9.0, 9.5, 10.0, 10.5, 11.0, 11.5, 12.0, 12.75, 13.0, 13.75, 14.0 ];
	}
}
