<?php
/**
 * The public-facing functionality of the plugin.
 *
 * Defines the plugin name, version, and two hooks to
 * enqueue the public-facing stylesheet and JavaScript.
 * As you add hooks and methods, update this description.
 *
 * @package    Plugnmeet
 * @subpackage Plugnmeet/public
 * @author     Jibon Costa <jibon@mynaparrot.com>
 */
if ( ! defined( 'PLUGNMEET_BASE_NAME' ) ) {
	die;
}

class Plugnmeet_Public {

	/**
	 * The ID of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string $plugin_name The ID of this plugin.
	 */
	private $plugin_name;

	/**
	 * The unique prefix of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string $plugin_prefix The string used to uniquely prefix technical functions of this plugin.
	 */
	private $plugin_prefix;

	/**
	 * The version of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string $version The current version of this plugin.
	 */
	private $version;

	/**
	 * @var object
	 */
	private $setting_params;

	/**
	 * @var object|null
	 */
	private $current_room_info = null;

	/**
	 * Initialize the class and set its properties.
	 *
	 * @param string $plugin_name The name of the plugin.
	 * @param string $plugin_prefix The unique prefix of this plugin.
	 * @param string $version The version of this plugin.
	 *
	 * @since    1.0.0
	 */
	public function __construct( $plugin_name, $plugin_prefix, $version ) {

		$this->plugin_name    = $plugin_name;
		$this->plugin_prefix  = $plugin_prefix;
		$this->version        = $version;
		$this->setting_params = (object) get_option( "plugnmeet_settings" );

	}

	/**
	 * Register the stylesheets for the public-facing side of the site.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_styles() {
		wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/plugnmeet-public.css', [], $this->version );

	}

	/**
	 * Register the JavaScript for the public-facing side of the site.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_scripts() {
		wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/plugnmeet-public.js', array(), $this->version );
		add_thickbox();

		$script = array(
			'ajaxurl' => admin_url( 'admin-ajax.php' ),
			'i18n'    => array(
				'checking'    => __( 'Checking...', 'plugnmeet' ),
				'redirecting' => __( 'Redirecting...', 'plugnmeet' ),
			)
		);
		wp_localize_script( $this->plugin_name, 'plugnmeet_frontend', $script );
	}

	public function start_session() {
		// Don't start a session for WP-CLI or REST API requests.
		if ( ( defined( 'WP_CLI' ) && WP_CLI ) || wp_is_serving_rest_request() ) {
			return;
		}

		// Don't start a session on "true" admin pages, but DO allow it for AJAX requests.
		if ( is_admin() && ! wp_doing_ajax() ) {
			return;
		}

		if ( ! session_id() ) {
			session_start();
		}
	}

	public function setQueryVar( $vars ) {
		$vars[] = 'Plug-N-Meet-Conference';
		$vars[] = 'plugnmeet_room';

		return $vars;
	}

	public function custom_add_rewrite_rule() {
		add_rewrite_rule( '^Plug-N-Meet-conference$', 'index.php?Plug-N-Meet-Conference=1', 'top' );

		$slug = ! empty( $this->setting_params->room_slug_path ) ? rtrim( $this->setting_params->room_slug_path, "/" ) : "plugnmeet/room";
		add_rewrite_rule( $slug . '/([^/]+)/?$', 'index.php?plugnmeet_room=$matches[1]', 'top' );
	}

	public function pre_get_posts( $query ) {
		if ( ! $query->is_main_query() || is_admin() ) {
			return;
		}

		$room_uuid = get_query_var( 'plugnmeet_room' );
		if ( ! empty( $room_uuid ) ) {
			$host_page_id = $this->setting_params->room_host_page ?? 0;
			if ( ! empty( $host_page_id ) ) {
				$query->set( 'page_id', $host_page_id );
				$query->set( 'post_type', 'page' );
				$query->is_page     = true;
				$query->is_singular = true;
				$query->is_home     = false;
				$query->is_archive  = false;

				// Fetch and store room info
				global $wpdb;
				$this->current_room_info = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix . "plugnmeet_rooms WHERE room_id = %s", $room_uuid ) );
			}
		}
	}

	public function filter_page_title( $title, $id = null ) {
		$host_page_id = $this->setting_params->room_host_page ?? 0;
		if ( $this->current_room_info && $id == $host_page_id ) {
			return $this->current_room_info->room_title;
		}

		return $title;
	}

	public function filter_browser_title( $title_parts ) {
		if ( $this->current_room_info ) {
			$title_parts['title'] = $this->current_room_info->room_title;
		}

		return $title_parts;
	}

	public function filter_page_content( $content ) {
		if ( in_the_loop() && $this->current_room_info ) {
			return $this->formatRoomViewForShortCode( $this->current_room_info->id );
		}

		return $content;
	}

	public function on_display_plugnmeet_conference( $template ) {
		if ( is_admin() || ! is_main_query() ) {
			return $template;
		}

		if ( ! get_query_var( 'Plug-N-Meet-Conference' ) ) {
			return $template;
		}
		$id = isset( $_GET['id'] ) ? sanitize_text_field( $_GET['id'] ) : 0;
		if ( empty( $id ) ) {
			die( __( "room Id is missing", 'plugnmeet' ) );
		}

		if ( ! class_exists( 'Plugnmeet_RoomPage' ) ) {
			require PLUGNMEET_ROOT_PATH . "/admin/class-plugnmeet-room-page.php";
		}

		$class         = new Plugnmeet_RoomPage();
		$roomInfo      = $class->getRoomById( $id );
		$room_metadata = json_decode( $roomInfo->room_metadata, true );

		$custom_design_params = isset( $room_metadata['custom_design'] ) ? $room_metadata['custom_design'] : [];
		$jsOptions            = $this->getJsOptions( $custom_design_params );

		require plugin_dir_path( dirname( __FILE__ ) ) . 'public/partials/plugnmeet-public-display-client.php';

		exit();
	}

	private function getJsOptions( $custom_design_params ) {
		$config = $this->setting_params;
		if ( ! isset( $config->client_load ) || $config->client_load === "remote" ) {
			$assetsPath = $config->plugnmeet_server_url . "/assets";
		} else {
			$assetsPath = plugins_url( 'public/client/dist/assets', PLUGNMEET_BASE_NAME );
		}

		$plugNmeetConfig = [
			'serverUrl'                    => esc_url_raw( $config->plugnmeet_server_url ),
			'staticAssetsPath'             => esc_url_raw( $assetsPath ),
			'enableDynacast'               => filter_var( $config->enable_dynacast, FILTER_VALIDATE_BOOLEAN ),
			'enableSimulcast'              => filter_var( $config->enable_simulcast, FILTER_VALIDATE_BOOLEAN ),
			'videoCodec'                   => esc_attr( $config->video_codec ),
			'defaultWebcamResolution'      => esc_attr( $config->default_webcam_resolution ),
			'defaultScreenShareResolution' => esc_attr( $config->default_screen_share_resolution ),
			'defaultAudioPreset'           => isset( $config->default_audio_preset ) ? esc_attr( $config->default_audio_preset ) : 'music',
			'stopMicTrackOnMute'           => filter_var( $config->stop_mic_track_on_mute, FILTER_VALIDATE_BOOLEAN ),
		];

		$custom_designs = [];
		foreach ( $custom_design_params as $key => $val ) {
			if ( empty( $val ) ) {
				$custom_designs[ $key ] = isset( $config->$key ) ? $config->$key : '';
			} else {
				$custom_designs[ $key ] = $val;
			}
		}

		$designCustomization = [];
		if ( ! empty( $custom_designs['primary_color'] ) ) {
			$designCustomization['primary_color'] = esc_attr( $custom_designs['primary_color'] );
		}
		if ( ! empty( $custom_designs['secondary_color'] ) ) {
			$designCustomization['secondary_color'] = esc_attr( $custom_designs['secondary_color'] );
		}
		if ( ! empty( $custom_designs['background_color'] ) ) {
			$designCustomization['background_color'] = esc_attr( $custom_designs['background_color'] );
		}
		if ( ! empty( $custom_designs['background_image'] ) ) {
			$designCustomization['background_image'] = esc_url_raw( $custom_designs['background_image'] );
		}
		if ( ! empty( $custom_designs['header_color'] ) ) {
			$designCustomization['header_bg_color'] = esc_attr( $custom_designs['header_color'] );
		}
		if ( ! empty( $custom_designs['footer_color'] ) ) {
			$designCustomization['footer_bg_color'] = esc_attr( $custom_designs['footer_color'] );
		}
		if ( ! empty( $custom_designs['side_panel_bg_color'] ) ) {
			$designCustomization['side_panel_bg_color'] = esc_attr( $custom_designs['side_panel_bg_color'] );
		}
		if ( ! empty( $custom_designs['custom_css_url'] ) ) {
			$designCustomization['custom_css_url'] = esc_url_raw( $custom_designs['custom_css_url'] );
		}

		if ( ! empty( $custom_design_params['logo'] ) ) {
			$designCustomization['custom_logo'] = esc_url_raw( $custom_design_params['logo'] );
		} else if ( ! empty( $config->logo ) ) {
			$designCustomization['custom_logo'] = esc_url_raw( $config->logo );
		}

		if ( ! empty( $designCustomization ) ) {
			$plugNmeetConfig['designCustomization'] = $designCustomization;
		}

		$jsonConfig = json_encode( $plugNmeetConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES );

		return "window.plugNmeetConfig = JSON.parse(`" . addslashes( $jsonConfig ) . "`);";
	}

	/**
	 * Example of Shortcode processing function.
	 *
	 * Shortcode can take attributes like [plugnmeet_room_view id='123']
	 * Shortcodes can be enclosing content [plugnmeet_room_view id='123']custom content[/plugnmeet_room_view].
	 *
	 * @see https://developer.wordpress.org/plugins/shortcodes/enclosing-shortcodes/
	 *
	 * @since    1.0.0
	 *
	 * @param array $atts ShortCode Attributes.
	 * @param mixed $content ShortCode enclosed content.
	 * @param string $tag The Shortcode tag.
	 */
	public function plugnmeet_shortcode_room_view( $atts, $content = null, $tag = "" ) {

		$atts = shortcode_atts(
			array(
				'id' => 0, // Default to 0 to better handle cases where no ID is provided.
			),
			$atts,
			$this->plugin_prefix . 'room_view'
		);

		$id = intval( $atts['id'] );

		/**
		 * If the shortcode is enclosing, the content will be used as the ID,
		 * overriding the 'id' attribute.
		 * e.g. [plugnmeet_room_view]123[/plugnmeet_room_view]
		 */
		if ( ! empty( $content ) ) {
			$id = intval( do_shortcode( $content ) );
		}

		if ( ! $id ) {
			// If no ID is provided via attribute or content, there's nothing to show.
			return __( 'Room ID not provided for the shortcode.', 'plugnmeet' );
		}

		// ShortCodes are filters and should always return, never echo.
		return $this->formatRoomViewForShortCode( $id );

	}

	private function formatRoomViewForShortCode( $roomId ) {
		if ( ! class_exists( 'Plugnmeet_RoomPage' ) ) {
			require PLUGNMEET_ROOT_PATH . "/admin/class-plugnmeet-room-page.php";
		}

		$class    = new Plugnmeet_RoomPage();
		$roomInfo = $class->getRoomById( $roomId );

		if ( ! $roomInfo ) {
			return __( 'no room found', 'plugnmeet' );
		}

		$user = wp_get_current_user();
		$role = array(
			'require_password' => "on",
			'join_as'          => 'attendee',
			'can_download'     => "off",
			'can_delete'       => "off"
		);

		if ( ! empty( $roomInfo->roles ) ) {
			$roles    = json_decode( $roomInfo->roles, true );
			$userRole = 'guest';

			if ( $user->ID ) {
				$userRole = $user->roles[0]; // at present let's consider the first one only
			}

			if ( isset( $roles[ $userRole ] ) ) {
				$role = $roles[ $userRole ];
			}
		}

		if ( isset( $role['can_view_recording'] ) && $role['can_view_recording'] === "on" ) {
			wp_enqueue_script( $this->plugin_name . '-recordings', plugin_dir_url( __FILE__ ) . 'js/plugnmeet-public-recordings.js', array(), $this->version );
			wp_localize_script( $this->plugin_name . '-recordings', 'plugnmeet_recordings', array(
				'room_id'      => $roomInfo->room_id,
				'can_play'     => isset( $role['can_play'] ) && $role['can_play'] === "on",
				'can_download' => isset( $role['can_download'] ) && $role['can_download'] === "on",
				'can_delete'   => isset( $role['can_delete'] ) && $role['can_delete'] === "on",
				'nonce'        => array(
					'get_recordings'     => wp_create_nonce( 'plugnmeet_get_recordings' ),
					'download_recording' => wp_create_nonce( 'plugnmeet_download_recording' ),
					'delete_recording'   => wp_create_nonce( 'plugnmeet_delete_recording' ),
				),
				'i18n'         => array(
					'no_recordings'  => __( 'No recordings found', 'plugnmeet' ),
					'confirm_delete' => __( 'Are you sure to delete?', 'plugnmeet' ),
					'play'           => __( 'Play', 'plugnmeet' ),
					'download'       => __( 'Download', 'plugnmeet' ),
					'delete'         => __( 'Delete', 'plugnmeet' ),
					'loading'        => __( 'Loading...', 'plugnmeet' ),
				),
			) );
		}

		ob_start();
		$template_file = $this->pnm_locate_template( 'plugnmeet-public-display.php' );
		extract( array(
			'roomInfo' => $roomInfo,
			'user'     => $user,
			'role'     => $role,
		) );
		require $template_file;

		return ob_get_clean();
	}

	/**
	 * Locate a template file.
	 *
	 * This is a custom template locator for this plugin.
	 * It will check for the file in the child theme, then the parent theme,
	 * and finally fall back to the plugin's default template directory.
	 *
	 * @param string $template_name The name of the template file (e.g., 'my-template.php').
	 *
	 * @return string The path to the template file.
	 */
	public function pnm_locate_template( $template_name ) {
		// Check the child theme for an override.
		$template_path = get_stylesheet_directory() . '/plugnmeet/' . $template_name;
		if ( file_exists( $template_path ) ) {
			return $template_path;
		}

		// Check the parent theme for an override.
		$template_path = get_template_directory() . '/plugnmeet/' . $template_name;
		if ( file_exists( $template_path ) ) {
			return $template_path;
		}

		// If no override is found, return the default plugin template.
		return plugin_dir_path( __FILE__ ) . 'partials/' . $template_name;
	}
}
