<?php
/**
 * Timezone Helper Utility
 *
 * Provides timezone conversion utilities for RSS scheduling.
 * Always uses WordPress timezone, never server timezone.
 *
 * @package Wisewand
 * @since 2.1.3
 * @license GPL-2.0-or-later
 */

namespace Wisewand\Utils;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Timezone utilities
 *
 * Handles timezone conversions for RSS scheduling feature.
 * All times use WordPress timezone (wp_timezone()).
 *
 * @since 2.1.3
 */
class Timezone_Helper {

	/**
	 * Get WordPress timezone object
	 *
	 * Returns the timezone configured in WordPress settings.
	 * This is THE timezone to use for all scheduling operations.
	 *
	 * @since 2.1.3
	 * @return \DateTimeZone WordPress timezone object.
	 */
	public static function get_wp_timezone() {
		return wp_timezone();
	}

	/**
	 * Get current time in WordPress timezone
	 *
	 * Returns current DateTime in WordPress timezone.
	 * Use this instead of time() or current_time().
	 *
	 * @since 2.1.3
	 * @return \DateTime Current time in WP timezone.
	 */
	public static function get_current_wp_time() {
		return new \DateTime( 'now', wp_timezone() );
	}

	/**
	 * Convert time to WordPress timezone DateTime
	 *
	 * Creates DateTime for today/tomorrow at specified time.
	 * If time is in the past today, schedules for tomorrow.
	 *
	 * Example:
	 * - Current time: 12:00 PM
	 * - Schedule time: 11:00 (HH:MM format)
	 * - Result: Tomorrow at 11:00 AM (because 11:00 already passed)
	 *
	 * @since 2.1.3
	 * @param string $time Time in HH:MM or HH:MM:SS format.
	 * @return \DateTime|false DateTime object in WP timezone, or false on failure.
	 */
	public static function get_wp_datetime( $time ) {
		$tz  = wp_timezone();
		$now = new \DateTime( 'now', $tz );

		// Parse time (HH:MM or HH:MM:SS)
		$schedule_time = \DateTime::createFromFormat( 'H:i', $time, $tz );

		// If format didn't match (maybe HH:MM:SS?), try that
		if ( false === $schedule_time ) {
			$schedule_time = \DateTime::createFromFormat( 'H:i:s', $time, $tz );
		}

		// Still failed? Invalid time format
		if ( false === $schedule_time ) {
			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
				error_log( 'Wisewand Timezone Helper: Invalid time format: ' . $time );
			}
			return false;
		}

		// Set date to today
		$schedule_time->setDate(
			(int) $now->format( 'Y' ),
			(int) $now->format( 'm' ),
			(int) $now->format( 'd' )
		);

		// If time is in the past, schedule for tomorrow
		if ( $schedule_time < $now ) {
			$schedule_time->modify( '+1 day' );

			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
				error_log( sprintf(
					'Wisewand Timezone Helper: Time %s is in the past, scheduling for tomorrow: %s',
					$time,
					$schedule_time->format( 'Y-m-d H:i:s' )
				) );
			}
		}

		return $schedule_time;
	}

	/**
	 * Format DateTime for WordPress post_date
	 *
	 * Converts DateTime to MySQL-compatible format for post_date.
	 * Format: YYYY-MM-DD HH:MM:SS
	 *
	 * @since 2.1.3
	 * @param \DateTime $datetime DateTime object to format.
	 * @return string MySQL-compatible datetime string.
	 */
	public static function format_for_post_date( $datetime ) {
		return $datetime->format( 'Y-m-d H:i:s' );
	}

	/**
	 * Get timezone string for display
	 *
	 * Returns user-friendly timezone string.
	 * Example: "America/New_York" or "UTC+5"
	 *
	 * @since 2.1.3
	 * @return string Timezone string for display.
	 */
	public static function get_timezone_string() {
		$timezone_string = get_option( 'timezone_string' );

		// If timezone_string is set, use it
		if ( ! empty( $timezone_string ) ) {
			return $timezone_string;
		}

		// Fallback: use UTC offset
		$offset  = (float) get_option( 'gmt_offset', 0 );
		$hours   = (int) $offset;
		$minutes = abs( ( $offset - $hours ) * 60 );

		$sign = ( $offset >= 0 ) ? '+' : '-';
		$hours = abs( $hours );

		return sprintf( 'UTC%s%d:%02d', $sign, $hours, $minutes );
	}

	/**
	 * Get next occurrence of time
	 *
	 * Finds next occurrence of specified time (today or tomorrow).
	 * Useful for scheduling recurring events.
	 *
	 * @since 2.1.3
	 * @param string $time Time in HH:MM format.
	 * @return \DateTime|false Next occurrence, or false on error.
	 */
	public static function get_next_occurrence( $time ) {
		$datetime = self::get_wp_datetime( $time );

		if ( false === $datetime ) {
			return false;
		}

		// get_wp_datetime already handles "today vs tomorrow" logic
		return $datetime;
	}

	/**
	 * Check if time is valid for today
	 *
	 * Returns true if time hasn't passed yet today.
	 * Used to determine if we can schedule for today vs tomorrow.
	 *
	 * @since 2.1.3
	 * @param string $time Time in HH:MM format.
	 * @return bool True if time is still valid for today.
	 */
	public static function is_time_future_today( $time ) {
		$tz  = wp_timezone();
		$now = new \DateTime( 'now', $tz );

		$schedule_time = \DateTime::createFromFormat( 'H:i', $time, $tz );
		if ( false === $schedule_time ) {
			return false;
		}

		// Set to today
		$schedule_time->setDate(
			(int) $now->format( 'Y' ),
			(int) $now->format( 'm' ),
			(int) $now->format( 'd' )
		);

		return $schedule_time > $now;
	}
}
