<?php
/**
 * Opening Hours management for locations.
 *
 * Supports multiple time slots per day, 24-hour format, 24/7 mode,
 * and shared (global) opening hours via options.
 *
 * @package SEOvaultSEO\LocalSEO
 */

namespace SEOvaultSEO\LocalSEO;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class OpeningHours {

	protected $location_id = 0;
	protected $options     = array();

	protected static $days = array(
		'sunday',
		'monday',
		'tuesday',
		'wednesday',
		'thursday',
		'friday',
		'saturday',
	);

	protected static $day_abbr = array(
		'sunday'    => 'Su',
		'monday'    => 'Mo',
		'tuesday'   => 'Tu',
		'wednesday' => 'We',
		'thursday'  => 'Th',
		'friday'    => 'Fr',
		'saturday'  => 'Sa',
	);

	protected static $day_full = array(
		'sunday'    => 'Sunday',
		'monday'    => 'Monday',
		'tuesday'   => 'Tuesday',
		'wednesday' => 'Wednesday',
		'thursday'  => 'Thursday',
		'friday'    => 'Friday',
		'saturday'  => 'Saturday',
	);

	public function __construct( $location_id = 0 ) {
		$this->location_id = absint( $location_id );
		$this->options     = get_option( 'seovaultseo_local_settings', array() );
		if ( ! is_array( $this->options ) ) {
			$this->options = array();
		}
	}

	public static function get_days() {
		return self::$days;
	}

	public static function get_day_abbr( $day ) {
		return self::$day_abbr[ $day ] ?? '';
	}

	public static function get_day_full( $day ) {
		return self::$day_full[ $day ] ?? '';
	}

	public function is_open_247() {
		if ( $this->location_id ) {
			$override = LocationMeta::get( $this->location_id, 'open_247' );
			if ( 'on' === $override ) {
				return true;
			}
		}

		return isset( $this->options['open_247'] ) && 'on' === $this->options['open_247'];
	}

	public function should_generate() {
		$hide = isset( $this->options['hide_opening_hours'] ) ? $this->options['hide_opening_hours'] : '';
		return 'on' !== $hide;
	}

	public function generate_schema() {
		if ( ! $this->should_generate() ) {
			return array();
		}

		if ( $this->is_open_247() ) {
			return $this->schema_247();
		}

		return $this->schema_specific();
	}

	protected function schema_247() {
		return array(
			array(
				'@type'     => 'OpeningHoursSpecification',
				'dayOfWeek' => array( 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ),
				'opens'     => '00:00',
				'closes'    => '23:59',
			),
		);
	}

	protected function schema_specific() {
		$output      = array();
		$grouped     = array();
		$grouped_24h = array();

		foreach ( self::$days as $day ) {
			$hours = $this->get_day_hours( $day );

			if ( 'on' === $hours['_24h'] ) {
				$grouped_24h[] = self::$day_full[ $day ];
				continue;
			}

			$opens  = $hours['_from'];
			$closes = $hours['_to'];

			if ( '' === $opens ) {
				$opens  = 'closed';
				$closes = 'closed';
			}

			$use_multiple = LocationMeta::get( $this->location_id, 'multiple_opening_hours' );
			if ( 'on' === $use_multiple && '' !== $hours['_second_from'] ) {
				$closes = $hours['_second_to'];
			}

			if ( 'closed' === $opens ) {
				continue;
			}

			$key = $opens . '-' . $closes;
			if ( ! isset( $grouped[ $key ] ) ) {
				$grouped[ $key ] = array(
					'opens'  => $opens,
					'closes' => $closes,
					'days'   => array(),
				);
			}
			$grouped[ $key ]['days'][] = self::$day_full[ $day ];
		}

		if ( ! empty( $grouped_24h ) ) {
			$output[] = array(
				'@type'     => 'OpeningHoursSpecification',
				'dayOfWeek' => $grouped_24h,
				'opens'     => '00:00',
				'closes'    => '23:59',
			);
		}

		foreach ( $grouped as $entry ) {
			$output[] = array(
				'@type'     => 'OpeningHoursSpecification',
				'dayOfWeek' => $entry['days'],
				'opens'     => $entry['opens'],
				'closes'    => $entry['closes'],
			);
		}

		return $output;
	}

	public function get_day_hours( $day ) {
		if ( ! in_array( $day, self::$days, true ) ) {
			return array(
				'_from'        => '',
				'_to'          => '',
				'_second_from' => '',
				'_second_to'   => '',
				'_24h'         => '',
			);
		}

		if ( $this->location_id ) {
			$prefix = LocationMeta::META_PREFIX . 'opening_hours_' . $day;
			return array(
				'_from'        => get_post_meta( $this->location_id, $prefix . '_from', true ),
				'_to'          => get_post_meta( $this->location_id, $prefix . '_to', true ),
				'_second_from' => get_post_meta( $this->location_id, $prefix . '_second_from', true ),
				'_second_to'   => get_post_meta( $this->location_id, $prefix . '_second_to', true ),
				'_24h'         => get_post_meta( $this->location_id, $prefix . '_24h', true ),
			);
		}

		$prefix = 'opening_hours_' . $day;
		return array(
			'_from'        => $this->options[ $prefix . '_from' ] ?? '',
			'_to'          => $this->options[ $prefix . '_to' ] ?? '',
			'_second_from' => $this->options[ $prefix . '_second_from' ] ?? '',
			'_second_to'   => $this->options[ $prefix . '_second_to' ] ?? '',
			'_24h'         => $this->options[ $prefix . '_24h' ] ?? '',
		);
	}

	public function is_currently_open() {
		if ( $this->is_open_247() ) {
			return true;
		}

		$day  = strtolower( current_time( 'l' ) );
		$time = current_time( 'H:i' );

		$hours = $this->get_day_hours( $day );

		if ( 'on' === $hours['_24h'] ) {
			return true;
		}

		if ( '' === $hours['_from'] || 'closed' === $hours['_from'] ) {
			return false;
		}

		if ( $time >= $hours['_from'] && $time <= $hours['_to'] ) {
			return true;
		}

		$use_multiple = LocationMeta::get( $this->location_id, 'multiple_opening_hours' );
		if ( 'on' === $use_multiple && '' !== $hours['_second_from'] ) {
			if ( $time >= $hours['_second_from'] && $time <= $hours['_second_to'] ) {
				return true;
			}
		}

		return false;
	}

	public function render_html( $hide_closed = false ) {
		$html = '<div class="seovault-opening-hours"><table class="seovault-opening-hours-table">';

		foreach ( self::$days as $day ) {
			$hours = $this->get_day_hours( $day );
			$label = self::$day_full[ $day ];

			if ( 'on' === $hours['_24h'] ) {
				$time_str = __( 'Open 24h', 'seovault-ai' );
			} elseif ( '' === $hours['_from'] || 'closed' === $hours['_from'] ) {
				if ( $hide_closed ) {
					continue;
				}
				$time_str = __( 'Closed', 'seovault-ai' );
			} else {
				$time_str     = esc_html( $hours['_from'] ) . ' - ' . esc_html( $hours['_to'] );
				$use_multiple = LocationMeta::get( $this->location_id, 'multiple_opening_hours' );
				if ( 'on' === $use_multiple && '' !== $hours['_second_from'] ) {
					$time_str .= ', ' . esc_html( $hours['_second_from'] ) . ' - ' . esc_html( $hours['_second_to'] );
				}
			}

			$html .= '<tr><td class="seovault-day">' . esc_html( $label ) . '</td><td class="seovault-time">' . esc_html( $time_str ) . '</td></tr>';
		}

		$html .= '</table></div>';
		return $html;
	}
}
