<?php
/**
 * Goodmeet_Settings API Class
 *
 * This class manages the API functionality for the goodmeet plugin settings.
 *
 * @package SOVLIX\GOODMEET\API
 */

namespace SOVLIX\GOODMEET\API;

use WP_REST_Controller;
use WP_REST_Server;
use WP_Error;

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

if ( ! class_exists( 'Goodmeet_Settings' ) ) {
	/**
	 * Goodmeet_Settings Class
	 */
	class Goodmeet_Settings extends WP_REST_Controller {
		/**
		 * Goodmeet_Settings constructor
		 */
		public function __construct() {
			$this->namespace = 'goodmeet/v2';
			$this->rest_base = 'settings';
		}

		/**
		 * Register REST API routes for settings
		 *
		 * @since 1.0.0
		 */
		public function register_routes() {
			// New route for google meet settings.
			register_rest_route(
				$this->namespace,
				'/' . $this->rest_base . '/google_meet',
				array(
					array(
						'methods'             => WP_REST_Server::READABLE,
						'callback'            => array( $this, 'get_google_meet_settings' ),
						'permission_callback' => array( $this, 'check_permissions' ),
					),
					array(
						'methods'             => WP_REST_Server::EDITABLE,
						'callback'            => array( $this, 'save_google_meet_settings' ),
						'permission_callback' => array( $this, 'check_permissions' ),
					),
				)
			);

			// Set addon routes.
			register_rest_route(
				$this->namespace,
				'/' . $this->rest_base . '/addon',
				array(
					array(
						'methods'             => WP_REST_Server::READABLE,
						'callback'            => array( $this, 'get_addon_settings' ),
						'permission_callback' => array( $this, 'check_permissions' ),
					),
					array(
						'methods'             => WP_REST_Server::EDITABLE,
						'callback'            => array( $this, 'save_addon_settings' ),
						'permission_callback' => array( $this, 'check_permissions' ),
					),
				)
			);

			// Set integration routes.
			register_rest_route(
				$this->namespace,
				'/' . $this->rest_base . '/integration',
				array(
					array(
						'methods'             => WP_REST_Server::READABLE,
						'callback'            => array( $this, 'get_integration_settings' ),
						'permission_callback' => array( $this, 'check_permissions' ),
					),
					array(
						'methods'             => WP_REST_Server::EDITABLE,
						'callback'            => array( $this, 'save_integration_settings' ),
						'permission_callback' => array( $this, 'check_permissions' ),
					),
				)
			);

			// Access control routes.
			register_rest_route(
				$this->namespace,
				'/' . $this->rest_base . '/access_control',
				array(
					array(
						'methods'             => WP_REST_Server::READABLE,
						'callback'            => array( $this, 'get_access_control_settings' ),
						'permission_callback' => array( $this, 'check_access_control_permissions' ),
					),
					array(
						'methods'             => WP_REST_Server::EDITABLE,
						'callback'            => array( $this, 'save_access_control_settings' ),
						'permission_callback' => array( $this, 'check_access_control_permissions' ),
					),
				)
			);

			// Roles list (used by Access Control + meeting form Select2 fields).
			register_rest_route(
				$this->namespace,
				'/' . $this->rest_base . '/roles',
				array(
					array(
						'methods'             => WP_REST_Server::READABLE,
						'callback'            => array( $this, 'get_roles' ),
						'permission_callback' => array( $this, 'check_roles_permissions' ),
					),
				)
			);

			// WP users list (used by co-host picker on Host Settings tab + meeting form).
			register_rest_route(
				$this->namespace,
				'/' . $this->rest_base . '/users',
				array(
					array(
						'methods'             => WP_REST_Server::READABLE,
						'callback'            => array( $this, 'get_users' ),
						'permission_callback' => array( $this, 'check_users_permissions' ),
					),
				)
			);

			// Global co-host defaults: returns raw user IDs + emails for Select2 prefill.
			register_rest_route(
				$this->namespace,
				'/' . $this->rest_base . '/global_cohost_defaults',
				array(
					array(
						'methods'             => WP_REST_Server::READABLE,
						'callback'            => array( $this, 'get_global_cohost_defaults' ),
						'permission_callback' => array( $this, 'check_roles_permissions' ),
					),
				)
			);
		}

		/**
		 * Return global co-host defaults as raw user IDs + emails.
		 *
		 * @return \WP_REST_Response
		 */
		public function get_global_cohost_defaults() {
			$global = goodmeet_get_access_control_settings();

			$user_ids = array();
			if ( ! empty( $global['default_cohost_users'] ) && is_array( $global['default_cohost_users'] ) ) {
				foreach ( $global['default_cohost_users'] as $uid ) {
					$uid = (int) $uid;
					if ( $uid > 0 && get_userdata( $uid ) ) {
						$user_ids[] = $uid;
					}
				}
			}

			$emails = array();
			if ( ! empty( $global['default_cohost_emails'] ) && is_array( $global['default_cohost_emails'] ) ) {
				foreach ( $global['default_cohost_emails'] as $email ) {
					$email = sanitize_email( $email );
					if ( $email && is_email( $email ) ) {
						$emails[] = strtolower( $email );
					}
				}
			}

			return rest_ensure_response(
				array(
					'user_ids' => array_values( array_unique( $user_ids ) ),
					'emails'   => array_values( array_unique( $emails ) ),
				)
			);
		}

		/**
		 * Permission gate for access control settings (admin only).
		 *
		 * @return bool
		 */
		public function check_access_control_permissions() {
			return current_user_can( 'manage_options' );
		}

		/**
		 * Permission gate for roles list (any user who can create/edit meetings).
		 *
		 * @return bool
		 */
		public function check_roles_permissions() {
			return current_user_can( 'edit_posts' );
		}

		/**
		 * Permission gate for user list (admin only — prevents email enumeration).
		 *
		 * @return bool
		 */
		public function check_users_permissions() {
			return current_user_can( 'manage_options' );
		}

		/**
		 * Check if the current user has permission to edit posts.
		 *
		 * This function checks if the current user has the capability to edit posts.
		 * It returns true if the user has the 'edit_posts' capability, and false otherwise.
		 *
		 * @return bool True if the current user can edit posts, false otherwise.
		 */
		public function check_permissions() {
			return current_user_can( 'edit_posts' );
		}

		/**
		 * Retrieves google meet settings api.
		 *
		 * @param WP_REST_Request $request Request object.
		 *
		 * @return WP_Error|WP_REST_Response
		 */
		public function get_google_meet_settings( $request ) {
			$settings = get_option( 'goodmeet_google_meet_settings', array() );
			// Cast string '1'/'0' booleans to real booleans so JS !! checks work correctly.
			$bool_keys = array( 'hide_sidebar', 'hide_header_footer', 'enable_should_register', 'enable_recurring_meeting', 'allow_vendor_own_calendar' );
			foreach ( $bool_keys as $key ) {
				if ( isset( $settings[ $key ] ) ) {
					$settings[ $key ] = (bool) $settings[ $key ];
				}
			}
			return rest_ensure_response( $settings );
		}

		/**
		 * Save Google meet settings Api
		 *
		 * @param WP_REST_Request $request Request object.
		 *
		 * @return WP_Error|WP_REST_Response
		 */
		public function save_google_meet_settings( $request ) {
			$data = json_decode( $request->get_body() );

			// Validate and sanitize the data.
			$validated_data = $this->validate_and_sanitize_google_meet_settings( $data );

			if ( is_wp_error( $validated_data ) ) {
				return $validated_data;
			}

			// Update settings in the options.
			update_option( 'goodmeet_google_meet_settings', $validated_data );

			$response = array(
				'google_meet_settings_saved' => true,
				'google_meet_settings'       => $validated_data,
			);

			return rest_ensure_response( $response );
		}

		/**
		 * Validate and sanitize google meet settings api.
		 *
		 * @param object $data Mhub Settings API data.
		 *
		 * @return WP_Error|array Validated and sanitized settings data.
		 */
		private function validate_and_sanitize_google_meet_settings( $data ) {
			// Sanitize data before saving.
			$sanitized_data = array(
				'meeting_timezone'            => isset( $data->meeting_timezone ) ? sanitize_text_field( $data->meeting_timezone ) : '',
				'hide_sidebar'                => isset( $data->hide_sidebar ) ? sanitize_text_field( $data->hide_sidebar ) : '',
				'hide_header_footer'          => isset( $data->hide_header_footer ) ? sanitize_text_field( $data->hide_header_footer ) : '',
				'reminder_time'               => isset( $data->reminder_time ) ? sanitize_text_field( $data->reminder_time ) : '',
				'event_status'                => isset( $data->event_status ) ? sanitize_text_field( $data->event_status ) : '',
				'send_updates'                => isset( $data->send_updates ) ? sanitize_text_field( $data->send_updates ) : '',
				'transparency'                => isset( $data->transparency ) ? sanitize_text_field( $data->transparency ) : '',
				'event_visibility'            => isset( $data->event_visibility ) ? sanitize_text_field( $data->event_visibility ) : '',
				'enable_should_register'      => isset( $data->enable_should_register ) ? sanitize_text_field( $data->enable_should_register ) : '',
				'enable_recurring_meeting'    => isset( $data->enable_recurring_meeting ) ? sanitize_text_field( $data->enable_recurring_meeting ) : '',
				'allow_vendor_own_calendar'   => isset( $data->allow_vendor_own_calendar ) ? ( $data->allow_vendor_own_calendar ? '1' : '0' ) : '0',
			);

			return $sanitized_data;
		}

		/**
		 * Get addon settings
		 *
		 * @return WP_REST_Response|WP_Error
		 */
		public function get_addon_settings() {
			$settings = get_option( 'goodmeet_addons_settings', array() );
			return rest_ensure_response( $settings );
		}

		/**
		 * Get integration settings
		 *
		 * @return WP_REST_Response|WP_Error
		 */
		public function get_integration_settings() {
			$settings = get_option( 'goodmeet_integration_settings', array() );
			return rest_ensure_response( $settings );
		}

		/**
		 * Save addon settings
		 *
		 * @param WP_REST_Request $request Request object.
		 * @return WP_REST_Response|WP_Error
		 */
		public function save_addon_settings( $request ) {
			$settings = $request->get_param( 'goodmeet_addons_settings' );

			if ( ! is_array( $settings ) ) {
				return new WP_Error(
					'invalid_settings',
					__( 'Settings must be an array.', 'goodmeet' ),
					array( 'status' => 400 )
				);
			}

			$updated = update_option( 'goodmeet_addons_settings', $settings );

			$response = array(
				'addon_settings_saved' => true,
			);

			return rest_ensure_response( $response );
		}

		/**
		 * Save integration settings
		 *
		 * @param WP_REST_Request $request Request object.
		 * @return WP_REST_Response|WP_Error
		 */
		public function save_integration_settings( $request ) {
			$settings = $request->get_param( 'goodmeet_integration_settings' );

			if ( ! is_array( $settings ) ) {
				return new WP_Error(
					'invalid_settings',
					__( 'Settings must be an array.', 'goodmeet' ),
					array( 'status' => 400 )
				);
			}

			$updated = update_option( 'goodmeet_integration_settings', $settings );

			$response = array(
				'integration_settings_saved' => true,
			);

			return rest_ensure_response( $response );
		}

		/**
		 * Get access control settings (Pro feature, admin only).
		 *
		 * @return \WP_REST_Response|\WP_Error
		 */
		public function get_access_control_settings() {
			$settings = goodmeet_get_access_control_settings();
			return rest_ensure_response( $settings );
		}

		/**
		 * Save access control settings. Pro-gated; non-Pro requests strip fields.
		 *
		 * @param \WP_REST_Request $request Request object.
		 * @return \WP_REST_Response|\WP_Error
		 */
		public function save_access_control_settings( $request ) {
			if ( ! goodmeet_fs()->can_use_premium_code__premium_only() ) {
				return rest_ensure_response(
					array(
						'access_control_settings_saved' => false,
						'reason'                        => 'pro_required',
					)
				);
			}

			$data = json_decode( $request->get_body() );

			$sanitized = $this->validate_and_sanitize_access_control_settings( $data );

			if ( is_wp_error( $sanitized ) ) {
				return $sanitized;
			}

			update_option( 'goodmeet_access_control_settings', $sanitized );

			return rest_ensure_response(
				array(
					'access_control_settings_saved' => true,
					'access_control_settings'       => $sanitized,
				)
			);
		}

		/**
		 * Validate and sanitize access control settings.
		 *
		 * @param object $data Raw posted data.
		 * @return array|\WP_Error
		 */
		private function validate_and_sanitize_access_control_settings( $data ) {
			$valid_roles = array_keys( wp_roles()->get_names() );

			$visibility_allowed = array( 'public', 'logged_in', 'role_based' );
			$meeting_visibility = isset( $data->meeting_visibility ) ? sanitize_text_field( $data->meeting_visibility ) : 'public';
			if ( ! in_array( $meeting_visibility, $visibility_allowed, true ) ) {
				$meeting_visibility = 'public';
			}

			$visibility_roles_raw = isset( $data->visibility_roles ) && is_array( $data->visibility_roles ) ? $data->visibility_roles : array();
			$visibility_roles     = array_values(
				array_intersect(
					array_map( 'sanitize_text_field', $visibility_roles_raw ),
					$valid_roles
				)
			);

			$default_cohost_users_raw = isset( $data->default_cohost_users ) && is_array( $data->default_cohost_users ) ? $data->default_cohost_users : array();
			$default_cohost_users     = array();
			foreach ( $default_cohost_users_raw as $uid ) {
				$uid = (int) $uid;
				if ( $uid > 0 && get_userdata( $uid ) ) {
					$default_cohost_users[] = $uid;
				}
			}

			$default_cohost_emails_raw = isset( $data->default_cohost_emails ) && is_array( $data->default_cohost_emails ) ? $data->default_cohost_emails : array();
			$default_cohost_emails     = array();
			foreach ( $default_cohost_emails_raw as $email ) {
				$email = sanitize_email( $email );
				if ( $email && is_email( $email ) ) {
					$default_cohost_emails[] = strtolower( $email );
				}
			}
			$default_cohost_emails = array_values( array_unique( $default_cohost_emails ) );

			return array(
				'meeting_visibility'    => $meeting_visibility,
				'visibility_roles'      => $visibility_roles,
				'default_cohost_users'  => array_values( array_unique( $default_cohost_users ) ),
				'default_cohost_emails' => $default_cohost_emails,
			);
		}

		/**
		 * Return WP user list for co-host picker. Capped to 500.
		 *
		 * @return \WP_REST_Response
		 */
		public function get_users() {
			$users = get_users(
				array(
					'number'  => 500,
					'orderby' => 'display_name',
					'order'   => 'ASC',
					'fields'  => array( 'ID', 'display_name', 'user_email' ),
				)
			);

			$options = array();
			foreach ( $users as $user ) {
				$options[] = array(
					'value' => (int) $user->ID,
					'label' => sprintf( '%s (%s)', $user->display_name, $user->user_email ),
					'email' => $user->user_email,
				);
			}

			return rest_ensure_response( $options );
		}

		/**
		 * Return WP role list as { value, label } pairs.
		 *
		 * @return \WP_REST_Response
		 */
		public function get_roles() {
			$roles   = wp_roles()->get_names();
			$options = array();
			foreach ( $roles as $slug => $label ) {
				$options[] = array(
					'value' => $slug,
					'label' => translate_user_role( $label ),
				);
			}
			return rest_ensure_response( $options );
		}
	}
}
