<?php
/**
 * Meeting Hub Functions
 *
 * @package WEMEET
 * @version 1.0.0
 */

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

if ( ! function_exists( 'wemeet_delete_meeting' ) ) {
	/**
	 * Delete Meeting
	 *
	 * @param int $id Delete Id.
	 *
	 * @return int|boolean
	 *
	 * @since 1.0.0
	 */
	function wemeet_delete_meeting( $id ) {
		delete_post_meta( $id, 'wemeet__meeting_settings', null );
		$deleted = wp_delete_post( $id );
		return $deleted;
	}
}


if ( ! function_exists( 'wemeet_meetings' ) ) {
	/**
	 * Fetch jitsi all meetings
	 *
	 * @return array
	 *
	 * @since 1.0.0
	 */
	function wemeet_meetings() {

		$user_id = get_current_user_id();

		$args = array(
			'post_type'      => 'wemeet_meeting',
			'post_status'    => 'published',
			'posts_per_page' => -1,
		);

		// If the user does not have the manage_options capability, limit the query to their own meetings.
		if ( ! current_user_can( 'manage_options' ) ) {
			$args['author'] = $user_id;
		}

		$wp_query = new \WP_Query( $args );
		$results  = $wp_query->posts;

		$meetings = array();

		foreach ( $results as $result ) {
			$meeting         = array();
			$settings        = get_post_meta( $result->ID, 'wemeet__meeting_settings', true );
			$settings        = maybe_unserialize( $settings );
			$settings['url'] = get_permalink( $result->ID );

			$meeting['id']       = $result->ID;
			$meeting['title']    = $result->post_title;
			$meeting['settings'] = $settings;
			$meeting['date']     = $result->post_date;
			$meetings[]          = $meeting;

		}

		wp_reset_postdata();

		return $meetings;
	}

}

if ( ! function_exists( 'wemeet_meeting' ) ) {

	/**
	 * Fetch a single meeting from the DB
	 *
	 * @param int $id Meeting Id.
	 *
	 * @return object
	 *
	 * @since 1.0.0
	 */
	function wemeet_meeting( $id ) {
		$meeting = array();

		$post                = get_post( $id );
		$settings            = get_post_meta( $id, 'wemeet__meeting_settings', true );
		$meeting_description = get_post_meta( $id, 'meeting_description', true );

		$meeting['id']                  = $post->ID;
		$meeting['title']               = $post->post_title;
		$meeting['settings']            = maybe_unserialize( $settings );
		$meeting['meeting_description'] = $meeting_description;
		$meeting['date']                = $post->post_date;

		return $meeting;
	}
}

if ( ! function_exists( 'wemeet_timezone_offset' ) ) {
	/**
	 * Retrieve the timezone offset in hours and minutes.
	 *
	 * This function fetches the timezone offset from WordPress options. If the offset is empty,
	 * it defaults to 'UTC'. The offset is returned in the format specified by WordPress options.
	 *
	 * @return string The timezone offset in hours and minutes.
	 */
	function wemeet_timezone_offset() {
		$fetched_offset = get_option( 'timezone_string' );
		$offset         = empty( $fetched_offset ) ? 'UTC' : $fetched_offset;
		return $offset;
	}

}

if ( ! function_exists( 'wemeet_convert_to_minutes' ) ) {
	/**
	 * Convert hours and minutes to minutes.
	 *
	 * This function takes the given hour and minute values and converts them into minutes.
	 * It multiplies the hour value by 60 and adds the minute value to get the total minutes.
	 *
	 * @param int $hour The hour value to be converted.
	 * @param int $minute The minute value to be converted.
	 * @return int The total minutes calculated from the provided hour and minute values.
	 */
	function wemeet_convert_to_minutes( $hour, $minute ) {
		$hour   = $hour * 60;
		$result = $hour + $minute;
		return $result;
	}
}

if ( ! function_exists( 'wemeet_pro_plugin_exists' ) ) {
	/**
	 * Checks if the WeMeet Pro plugin is installed.
	 *
	 * @return bool True if WeMeet Pro plugin exists, false otherwise.
	 */
	function wemeet_pro_plugin_exists() {
		return file_exists( WP_PLUGIN_DIR . '/wemeet-pro/wemeet-pro.php' );
	}
}


if ( ! function_exists( 'wemeet_insert_meeting' ) ) {
	/**
	 * Inserts a new meeting post into the database.
	 *
	 * @param string $title              The title of the meeting.
	 * @param array  $meeting_settings   The settings for the meeting.
	 * @param string $meeting_description The description of the meeting.
	 *
	 * @return int|WP_Error The ID of the inserted meeting post on success, or a WP_Error object on failure.
	 */
	function wemeet_insert_meeting( $title, $meeting_settings, $meeting_description ) {
		$un_meeting_settings       = maybe_unserialize( $meeting_settings );
		$meeting_description_array = json_decode( $meeting_description, true );
		$meeting_description       = isset( $meeting_description_array['content'] ) ? wp_kses_post( $meeting_description_array['content'] ) : '';

		$new_meeting = array(
			'post_title'   => $title,
			'post_type'    => 'wemeet_meeting',
			'post_status'  => 'publish',
			'post_content' => '',
			'meta_input'   => array(
				'wemeet__meeting_settings' => $meeting_settings,
				'meeting_description'    => $meeting_description,
			),

		);

		$meeting_id = wp_insert_post( $new_meeting );

		$thumbnail_id = $un_meeting_settings['image_id'];

		// Set post thumbnail.
		if ( ! empty( $thumbnail_id ) ) {
			set_post_thumbnail( $meeting_id, $thumbnail_id );
		}

		if ( is_wp_error( $meeting_id ) ) {
			$meeting_id->add_data( array( 'status' => 400 ) );
			return $meeting_id;
		}

		return $meeting_id;
	}

}

if ( ! function_exists( 'wemeet_update_meeting' ) ) {
	/**
	 * Updates an existing meeting post in the database.
	 *
	 * @param string $title              The new title of the meeting.
	 * @param array  $meeting_settings   The new settings for the meeting.
	 * @param int    $meeting_id         The ID of the meeting post to update.
	 * @param string $meeting_description The new description of the meeting.
	 *
	 * @return int|WP_Error The number of affected rows on success, or a WP_Error object on failure.
	 */
	function wemeet_update_meeting( $title, $meeting_settings, $meeting_id, $meeting_description ) {
		$un_meeting_settings       = maybe_unserialize( $meeting_settings );
		$meeting_description_array = json_decode( $meeting_description, true );
		$meeting_description       = isset( $meeting_description_array['content'] ) ? wp_kses_post( $meeting_description_array['content'] ) : '';

		$arg = array(
			'ID'           => $meeting_id,
			'post_title'   => $title,
			'post_type'    => 'wemeet_meeting',
			'post_status'  => 'publish',
			'post_content' => '',
			'meta_input'   => array(
				'wemeet__meeting_settings' => $meeting_settings,
				'meeting_description'    => $meeting_description,
			),
		);

		$updated = wp_update_post( $arg );

		$thumbnail_id = isset( $un_meeting_settings['image_id'] ) ? $un_meeting_settings['image_id'] : '';

		// Check if the image ID is empty and remove the thumbnail if it is.
		if ( empty( $thumbnail_id ) ) {
			delete_post_thumbnail( $meeting_id );
		} else {
			// Set the post thumbnail if the image ID is not empty.
			set_post_thumbnail( $meeting_id, $thumbnail_id );
		}

		if ( ! $updated ) {
			return new WP_Error(
				'rest_not_updated',
				__( 'Sorry, the address could not be updated.', 'wemeet' ),
				array( 'status' => 400 )
			);
		}
	}
}

if ( ! function_exists( 'wemeet_prepare_webex_meeting_data' ) ) {
	/**
	 * Prepares meeting data for Webex API.
	 *
	 * @param string $title The title of the meeting.
	 * @param array  $meeting_settings Meeting settings including start time, agenda, password, and more.
	 * @param int    $duration The duration of the meeting in minutes.
	 *
	 * @return array Formatted meeting data for Webex API.
	 */
	function wemeet_prepare_webex_meeting_data( $title, $meeting_settings, $duration ) {
		$gmt_array      = wemeet_get_gmt_offset( $meeting_settings['meeting_timezone'] );
		$gmt_offset_val = $gmt_array['gmt_offset_val'];

		$start_timestamp  = strtotime( $meeting_settings['startDateTime'] ) + ( $gmt_offset_val );
		$start_time       = gmdate( 'Y-m-d H:i:s', $start_timestamp );
		$duration_seconds = $duration * 60;

		// Calculate the end time by adding the duration to the start timestamp.
		$end_timestamp = $start_timestamp + $duration_seconds;
		$end_time      = gmdate( 'Y-m-d H:i:s', $end_timestamp );

		$meeting_arr = array(
			'title'                    => $title,
			'agenda'                   => isset( $meeting_settings['agenda'] ) ? $meeting_settings['agenda'] : null,
			'password'                 => isset( $meeting_settings['password'] ) ? $meeting_settings['password'] : null,
			'start'                    => $start_time,
			'end'                      => $end_time,
			'timezone'                 => isset( $meeting_settings['meeting_timezone'] ) ? $meeting_settings['meeting_timezone'] : null,
			'enabledAutoRecordMeeting' => isset( $meeting_settings['auto_record'] ) ? (bool) $meeting_settings['auto_record'] : false,
			'enabledJoinBeforeHost'    => isset( $meeting_settings['join_before_host'] ) ? (bool) $meeting_settings['join_before_host'] : false,
			'enabledBreakoutSessions'  => isset( $meeting_settings['breakout_sessions'] ) ? (bool) $meeting_settings['breakout_sessions'] : false,
			'enableAutomaticLock'      => isset( $meeting_settings['automatic_lock'] ) ? (bool) $meeting_settings['automatic_lock'] : false,
		);

		if ( ! $meeting_arr['enabledJoinBeforeHost'] ) {
			$meeting_arr['enableConnectAudioBeforeHost'] = false;
		}

		if ( $meeting_arr['enableAutomaticLock'] ) {
			$meeting_arr['automaticLockMinutes'] = isset( $meeting_settings['lock_minutes'] ) ? (int) $meeting_settings['lock_minutes'] : 0;
		}

		return $meeting_arr;
	}
}

if ( ! function_exists( 'wemeet_get_gmt_offset' ) ) {
	/**
	 * Get the GMT offset and its value for a given timezone.
	 *
	 * @param string $timezone The timezone identifier, e.g., 'Asia/Dhaka'.
	 *
	 * @return array An array containing the GMT offset string and its value.
	 */
	function wemeet_get_gmt_offset( $timezone ) {
		$dtz               = new DateTimeZone( $timezone );
		$offset_in_seconds = $dtz->getOffset( new DateTime() );
		$hours             = floor( abs( $offset_in_seconds ) / 3600 );
		$minutes           = floor( ( abs( $offset_in_seconds ) % 3600 ) / 60 );
		$gmt_offset        = ( $offset_in_seconds < 0 ? '-' : '+' ) . sprintf( '%02d:%02d', $hours, $minutes );

		list( $hours, $minutes ) = explode( ':', $gmt_offset );
		$gmt_offset_val          = ( $hours * 3600 ) + ( $minutes * 60 );

		return array(
			'gmt_offset'     => $gmt_offset,
			'gmt_offset_val' => $gmt_offset_val,
		);
	}
}

/**
 * Get meetings by mode with visibility filtering.
 *
 * @param string $mode              Mode for filtering meetings ('user', 'role', 'all').
 * @param int    $page_id           Page ID to get saved visibility settings from.
 * @param array  $roles             Array of roles to filter by.
 * @param array  $users             Array of user IDs to filter by.
 * @param bool   $use_passed_values Whether to use passed values instead of saved meta.
 *
 * @return array Array of meeting data.
 */
function wemeet_meetings_by_mode( $mode = 'user', $page_id = 0, $roles = array(), $users = array(), $use_passed_values = false ) {
	$args = array(
		'post_type'      => 'wemeet_meeting',
		'post_status'    => 'publish',
		'posts_per_page' => -1,
	);

	if ( 'role' === $mode ) {
		// Use passed roles if use_passed_values is true, otherwise get saved roles.
		if ( ! $use_passed_values && empty( $roles ) && $page_id ) {
			$roles = get_post_meta( $page_id, '_wemeet_visibility_roles', true );
			if ( ! $roles ) {
				$roles = array();
			}
		}

		if ( ! empty( $roles ) ) {
			$role_users = get_users(
				array(
					'role__in' => $roles,
					'fields'   => array( 'ID' ),
				)
			);

			$user_ids = array_map(
				function ( $user ) {
					return $user->ID;
				},
				$role_users
			);

			if ( ! empty( $user_ids ) ) {
				$args['author__in'] = $user_ids;
			} else {
				// No users found with these roles, return empty.
				$args['author__in'] = array( 0 ); // This will return no posts.
			}
		} else {
			// No roles selected, return empty.
			$args['author__in'] = array( 0 );
		}
	} elseif ( 'user' === $mode ) {
		// Use passed users if use_passed_values is true, otherwise get saved users.
		if ( ! $use_passed_values && empty( $users ) && $page_id ) {
			$users = get_post_meta( $page_id, '_wemeet_visibility_users', true );
			if ( ! $users ) {
				$users = array();
			}
		}

		if ( ! empty( $users ) ) {
			$args['author__in'] = array_map( 'absint', $users );
		} else {
			// No users selected, return empty.
			$args['author__in'] = array( 0 );
		}
	}

	$wp_query = new WP_Query( $args );
	$meetings = array();

	foreach ( $wp_query->posts as $post ) {
		$settings = maybe_unserialize( get_post_meta( $post->ID, 'wemeet__meeting_settings', true ) );

		// Ensure settings is an array.
		if ( ! is_array( $settings ) ) {
			$settings = array();
		}

		$settings['url'] = get_permalink( $post->ID );

		$meetings[] = array(
			'id'       => $post->ID,
			'title'    => $post->post_title,
			'date'     => $post->post_date,
			'settings' => $settings,
		);
	}

	wp_reset_postdata();
	return $meetings;
}
