<?php
/**
 * Class to initiate the ics feed for MDJM
 */

/**
 * 
 */
class MDJM_ICS_Feed {

	public function __construct() {
		$this->sync_status = mdjm_get_option( 'gcal_event_status', array() );
	}

	// Register API endpoint with auth for ics feed.
	public function mdjm_register_calendar_feed() {
		register_rest_route(
			'mdjm/v1',
			'/calendar-feed',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'generate_protected_calendar' ),
				'permission_callback' => array( $this, 'mdjm_verify_basic_auth' ),
			)
		);
	}

	public function mdjm_verify_basic_auth() {

		if ( ! isset( $_SERVER['PHP_AUTH_USER'] ) ) {
			$this->mdjm_send_auth_headers();
			return new WP_Error( 'rest_forbidden', 'Authentication required.', array( 'status' => 401 ) );
		}

		$username = $_SERVER['PHP_AUTH_USER'];
		$password = $_SERVER['PHP_AUTH_PW'];

		$user = wp_authenticate( $username, $password );

		if ( is_wp_error( $user ) ) {
			$this->mdjm_send_auth_headers();
			return new WP_Error( 'rest_forbidden', 'Invalid credentials.', array( 'status' => 403 ) );
		}

		wp_set_current_user( $user->ID );

		return true;
	}

	public function mdjm_send_auth_headers() {
		header( 'WWW-Authenticate: Basic realm="Protected Calendar Feed"' );
		header( 'Content-Type: application/json; charset=utf-8' );
	}

	public function format_start_date( $event ) {

		if ( empty( $event ) ) {
			return;
		}

		$date_format = 'Y-m-d H:i:s';
		$event_date  = $event->date;
		$time        = $event->get_start_time();
		$start_time  = DateTime::createFromFormat( $date_format, $event_date . ' ' . $time );
		return $start_time->format( 'Ymd\THis\Z' );
	}

	public function format_end_date( $event ) {

		if ( empty( $event ) ) {
			return;
		}
		$date_format = 'Y-m-d H:i:s';
		$time        = $event->get_finish_time();
		$end_date    = get_post_meta( $event->ID, '_mdjm_event_end_date', true );

		if ( ! $end_date ) {
			$end_date = $event->date;
		}

		$end_time = DateTime::createFromFormat( $date_format, $end_date . ' ' . $time );

		return $end_time->format( 'Ymd\THis\Z' );
	}

	public function escape_ics_text( $text ) {
		$text = str_replace( '\\', '\\\\', $text ); // Escape backslashes
		$text = str_replace( ',', '\,', $text ); // Escape commas
		$text = str_replace( ';', '\;', $text ); // Escape semicolons
		$text = str_replace( "\n", "\\n", $text ); // Escape newlines
		return $text;
	}
	
	public function generate_protected_calendar( WP_REST_Request $request ) {
		$event_posts  = mdjm_get_events();
		$ics_calendar = "BEGIN:VCALENDAR\r\n";
		$ics_calendar .= "VERSION:2.0\r\n";
	
		$MDJM_Cal = new MDJM_GCal_Init();
	
		if ( $event_posts ) {
			foreach ( $event_posts as $event_post ) {
				$event = new MDJM_Event( $event_post->ID );
	
				if ( empty( $event ) ) {
					continue;
				}
	
				$post_status = ( isset( $event->post_status ) ? $event->post_status : '' );
	
				if ( in_array( $post_status, $this->sync_status, true ) ) {
					$event_summary     = $this->escape_ics_text( $MDJM_Cal->mdjm_event_summary( $event ) );
					$event_location    = $this->escape_ics_text( $MDJM_Cal->mdjm_event_location( $event ) );
					$event_description = $this->escape_ics_text(
						html_entity_decode( $MDJM_Cal->mdjm_event_description( $event ), ENT_QUOTES | ENT_HTML5, 'UTF-8' )
					);
	
					$event_start = $this->format_start_date( $event ); // Ensure proper format
					$event_end   = $this->format_end_date( $event );   // Ensure proper format

					// if event end date is before current date, skip
					if ( strtotime( $event_end ) < time() ) {
						continue;
					}
	
					$timestamp = gmdate( 'Ymd\THis\Z' ); // Current UTC time

					$ics_calendar .= "BEGIN:VEVENT\r\n";
					$ics_calendar .= 'DTSTAMP:' . $timestamp . "\r\n";
					$ics_calendar .= 'UID:' . md5( $event->ID ) . "\r\n";
					$ics_calendar .= 'SUMMARY:' . html_entity_decode( $event_summary ) . "\r\n";
					$ics_calendar .= 'DTSTART:' . $event_start . "\r\n";
					$ics_calendar .= 'DTEND:' . $event_end . "\r\n";
					$ics_calendar .= 'DESCRIPTION:' . html_entity_decode( $event_description ) . "\r\n";
					$ics_calendar .= 'LOCATION:' . html_entity_decode( $event_location ) . "\r\n";
					$ics_calendar .= "END:VEVENT\r\n";
				}
			}
		}
	
		$ics_calendar .= "END:VCALENDAR\r\n";		
	
		header( 'Content-Type: text/calendar; charset=utf-8' );
		header( 'Content-Disposition: inline' );
		header( 'Cache-Control: no-cache, must-revalidate' );
		header( 'Pragma: no-cache' );
		header( 'Expires: 0' );
		header( 'Content-Length: ' . strlen($ics_calendar) );
	
		echo $ics_calendar;
	}
	
}
