<?php
namespace Dreamfox\DeliveryDate\Helpers;

class TimeslotHelper
{
	/**
	 * Generate slot labels between start and end with the given duration in hours.
	 * Returns array of "HH:MM-HH:MM" strings.
	 */
	public static function generateSlots( $startTime, $endTime, $durationHours )
	{
		$slots        = array();
		$durationMins = max( 1, min( 12, (int) $durationHours ) ) * 60;
		$startMins    = self::_timeToMinutes( $startTime );
		$endMins      = self::_timeToMinutes( $endTime );

		// Handle end time of "24:00" as 1440 minutes
		if ( '24:00' === $endTime ) {
			$endMins = 1440;
		}

		$cursor = $startMins;
		while ( ( $cursor + $durationMins ) <= $endMins ) {
			$slotEnd = $cursor + $durationMins;
			$slots[] = self::_minutesToTime( $cursor ) . '-' . self::_minutesToTime( $slotEnd );
			$cursor  = $slotEnd;
		}

		return $slots;
	}

	/**
	 * Remove slots whose end time has already passed when the date is today.
	 *
	 * @param array  $slots   Array of "HH:MM-HH:MM" strings.
	 * @param string $dateYmd Y-m-d representation of the selected date.
	 * @return array
	 */
	public static function filterPastSlots( array $slots, $dateYmd )
	{
		if ( wp_date( 'Y-m-d' ) !== $dateYmd ) {
			return $slots;
		}

		$nowMins = self::_timeToMinutes( wp_date( 'H:i' ) );

		return array_values(
			array_filter( $slots, function ( $slot ) use ( $nowMins ) {
				$parts = explode( '-', $slot, 2 );
				return self::_timeToMinutes( $parts[1] ) > $nowMins;
			} )
		);
	}

	/**
	 * Validate a submitted timeslot for a given date against generated slots and capacity.
	 *
	 * @param  string $rawDate  Delivery date as posted at checkout (raw, unnormalized format).
	 * @param  string $slot     Submitted slot label, e.g. "09:00-11:00".
	 * @param  object $settings TimeslotSettings instance (getStartTime/getEndTime/getDuration/getMaxOrders).
	 * @return string|null Error message, or null when valid.
	 */
	public static function validateSubmittedSlot( $rawDate, $slot, $settings )
	{
		if ( '' === $slot ) {
			return __( 'Please select a delivery timeslot.', 'woocommerce-delivery-date' );
		}

		$dateYmd  = self::parseDateToYmd( $rawDate );
		$allSlots = self::generateSlots( $settings->getStartTime(), $settings->getEndTime(), $settings->getDuration() );
		$allSlots = self::filterPastSlots( $allSlots, $dateYmd );

		if ( ! in_array( $slot, $allSlots, true ) ) {
			return __( 'The selected delivery timeslot is no longer available. Please choose another.', 'woocommerce-delivery-date' );
		}

		$booked = \Dreamfox\DeliveryDate\Repositories\OrderRepository::countOrdersForTimeslot( $rawDate, $slot );
		if ( $booked >= $settings->getMaxOrders() ) {
			return __( 'That timeslot is fully booked. Please choose another.', 'woocommerce-delivery-date' );
		}

		return null;
	}

	/**
	 * Parse a date string in the WordPress date_format setting to Y-m-d.
	 *
	 * @param  string $dateString Date as formatted on the checkout (e.g. "15/06/2026").
	 * @return string Y-m-d or original string on failure.
	 */
	public static function parseDateToYmd( $dateString )
	{
		$format  = get_option( 'date_format', 'Y-m-d' );
		$dateObj = \DateTime::createFromFormat( $format, $dateString );
		if ( $dateObj instanceof \DateTime ) {
			return $dateObj->format( 'Y-m-d' );
		}
		// Fallback via strtotime
		$ts = strtotime( $dateString );
		return $ts ? wp_date( 'Y-m-d', $ts ) : $dateString;
	}

	// -------------------------------------------------------------------------

	private static function _timeToMinutes( $time )
	{
		$parts = explode( ':', $time );
		return ( (int) $parts[0] ) * 60 + ( isset( $parts[1] ) ? (int) $parts[1] : 0 );
	}

	private static function _minutesToTime( $minutes )
	{
		// Cap at 24:00
		$minutes = min( 1440, (int) $minutes );
		$h       = intdiv( $minutes, 60 );
		$m       = $minutes % 60;
		return sprintf( '%02d:%02d', $h, $m );
	}
}
