<?php
namespace AcademyProMeeting\Integration;

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

class Zoom {
	public static function init() {
		$self = new self();
		add_action( 'wp_ajax_academy_pro_meeting/get_zoom_settings', array( $self, 'get_zoom_settings' ) );
		add_action( 'wp_ajax_academy_pro_meeting/save_zoom_settings', array( $self, 'save_zoom_settings' ) );
		add_action( 'wp_ajax_academy_pro_meeting/save_zoom_meeting_credentials', array( $self, 'save_zoom_meeting_credentials' ) );
		add_action( 'wp_ajax_academy_pro_meeting/create_zoom_meeting', array( $self, 'create_zoom_meeting' ) );
		add_action( 'wp_ajax_academy_pro_meeting/update_zoom_meeting', array( $self, 'update_zoom_meeting' ) );
	}

	public function get_zoom_settings() {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}
		$settings = get_user_meta( get_current_user_id(), 'academy_pro_zoom_settings', true );
		wp_send_json_success( json_decode( $settings, true ) );
	}

	public static function get_zoom_api_settings( $user_id ) {
		$zoom_meta_key = get_user_meta( $user_id, 'academy_pro_zoom_credentials', true );
		return json_decode( $zoom_meta_key, true );
	}

	public static function get_user_zoom_settings( $user_id ) {
		$settings = get_user_meta( $user_id, 'academy_pro_zoom_settings', true );
		if ( ! empty( $settings ) ) {
			return json_decode( $settings, true );
		}
		return array(
			'join_before_host'  => true,
			'host_video'        => false,
			'participant_video' => false,
			'mute_upon_entry'   => false,
			'auto_recording'    => false,
			'enforce_login'     => false,
		);
	}

	public static function generate_access_token( $account_id, $client_id, $client_secret ) {
		$url = 'https://zoom.us/oauth/token?grant_type=account_credentials';

		if ( ! $account_id || ! $client_id || ! $client_secret ) {
			return false;
		}

		$url = $url . '&account_id=' . $account_id;
		// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
		$encode   = base64_encode( $client_id . ':' . $client_secret );
		$response = wp_remote_post(
			$url,
			array(
				'headers' => array(
					'ContentType'   => 'application/x-www-form-urlencoded',
					'Authorization' => 'Basic' . $encode,
				),
				'timeout' => 60,
			)
		);

		if ( ! is_wp_error( $response ) ) {
			$generate_token = json_decode( $response['body'] );
			if ( is_object( $generate_token ) && property_exists( $generate_token, 'access_token' ) ) {
				set_transient( 'academy_pro_zoom_access_token_' . get_current_user_id(), $generate_token->access_token, $generate_token->expires_in );
				return $generate_token->access_token;
			}
			return false;
		}
		return false;
	}
	public static function get_access_token( $user_id ) {
		$access_token = get_transient( 'academy_pro_zoom_access_token_' . $user_id );
		// if not have access token then create new one
		if ( false === $access_token ) {
			$settings = self::get_zoom_api_settings( $user_id );
			$access_token = self::generate_access_token( $settings['account_id'], $settings['client_id'], $settings['client_secret'] );
		}
		return $access_token;
	}

	public function save_zoom_settings() {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$enforce_login = (bool) ( isset( $_POST['enforce_login'] ) ? \Academy\Helper::sanitize_checkbox_field( $_POST['enforce_login'] ) : false );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$host_video = (bool) ( isset( $_POST['host_video'] ) ? \Academy\Helper::sanitize_checkbox_field( $_POST['host_video'] ) : false );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$join_before_host = (bool) ( isset( $_POST['join_before_host'] ) ? \Academy\Helper::sanitize_checkbox_field( $_POST['join_before_host'] ) : false );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$mute_participants = (bool) ( isset( $_POST['mute_participants'] ) ? \Academy\Helper::sanitize_checkbox_field( $_POST['mute_participants'] ) : false );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$participants_video = (bool) ( isset( $_POST['participants_video'] ) ? \Academy\Helper::sanitize_checkbox_field( $_POST['participants_video'] ) : false );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$recording_settings = ( isset( $_POST['recording_settings'] ) ? \Academy\Helper::sanitize_checkbox_field( $_POST['recording_settings'] ) : 'none' );
		$settings = [
			'join_before_host'      => $join_before_host,
			'host_video'            => $host_video,
			'participants_video'    => $participants_video,
			'mute_participants'     => $mute_participants,
			'enforce_login'         => $enforce_login,
			'recording_settings'    => $recording_settings,
		];
		update_user_meta( get_current_user_id(), 'academy_pro_zoom_settings', wp_json_encode( $settings ) );
		wp_send_json_success( $settings );
	}

	public function save_zoom_meeting_credentials() {
		check_ajax_referer( 'academy_nonce', 'security' );

		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$account_id = sanitize_text_field( $_POST['account_id'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$client_id = sanitize_text_field( $_POST['client_id'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$client_secret = sanitize_text_field( $_POST['client_secret'] );

		if ( empty( $account_id ) || empty( $client_id ) || empty( $client_secret ) ) {
			wp_send_json_error( __( 'Account ID, Client ID and Client Secret is required', 'academy-pro' ) );
		}

		$response = wp_remote_retrieve_body( wp_remote_get('https://api.zoom.us/v2/users/me', array(
			'method'     => 'GET',
			'headers' => array(
				'Authorization' => 'Bearer ' . self::generate_access_token( $account_id, $client_id, $client_secret ),
				'Content-Type' => 'application/json',
			),
			'sslverify'  => false,
		)) );
		$response = json_decode( $response, true );
		if ( count( $response ) && 'active' === $response['status'] ) {
			$user_id = get_current_user_id();
			$form_data = array(
				'account_id' => $account_id,
				'client_id' => $client_id,
				'client_secret' => $client_secret,
				'host_email' => $response['email'],
				'status' => $response['status']
			);
			update_user_meta( $user_id, 'academy_pro_zoom_credentials', wp_json_encode( $form_data ) );
			wp_send_json_success( $form_data );
		}
		wp_send_json_error( __( 'Wrong API Key and Secret Key', 'academy-pro' ) );
	}

	public function create_zoom_meeting() {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}

		$user_id = get_current_user_id();
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_title = ( isset( $_POST['meetingTitle'] ) ? sanitize_text_field( $_POST['meetingTitle'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_description = ( isset( $_POST['meetingSummary'] ) ? sanitize_text_field( $_POST['meetingSummary'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_date = ( isset( $_POST['meetingDate'] ) ? sanitize_text_field( $_POST['meetingDate'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_time = ( isset( $_POST['meetingTime'] ) ? sanitize_text_field( $_POST['meetingTime'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_duration = ( isset( $_POST['meetingDuration'] ) ? sanitize_text_field( $_POST['meetingDuration'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_duration_unit = ( isset( $_POST['meetingTimeUnit'] ) ? sanitize_text_field( $_POST['meetingTimeUnit'] ) : 'minute' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$timezone = ( isset( $_POST['meetingTimeZone'] ) ? sanitize_text_field( $_POST['meetingTimeZone'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$password = sanitize_text_field( $_POST['meetingPassword'] );

		$meeting_start_time    = \DateTime::createFromFormat( 'Y-m-d H:i', $meeting_date . ' ' . $meeting_time );
		if ( ! $meeting_start_time ) {
			wp_send_json_error( __( 'Sorry, Invalid Date Time Format', 'academy-pro' ) );
		}

		$request_body     = wp_json_encode(array(
			'topic'      => $meeting_title,
			'description' => $meeting_description,
			'type'       => 2,
			'start_time' => $meeting_start_time->format( 'Y-m-d\TH:i:s' ),
			'timezone'   => $timezone,
			'duration'   => ( 'hour' === $meeting_duration_unit ? $meeting_duration * 60 : $meeting_duration ),
			'password'   => $password,
			'settings'   => self::get_user_zoom_settings( $user_id ),
		));

		$response = wp_remote_retrieve_body(wp_remote_post('https://api.zoom.us/v2/users/me/meetings', array(
			'method'     => 'POST',
			'headers' => array(
				'Authorization' => 'Bearer ' . self::get_access_token( $user_id ),
				'Content-Type' => 'application/json',
			),
			'sslverify'  => false,
			'body'  => $request_body
		)));

		$response_array = json_decode( $response, true );
		if ( empty( $response ) || ! isset( $response_array['id'] ) ) {
			wp_send_json_error( __( 'Sorry, Failed to Create Zoom Meeting.', 'academy-pro' ) );
		}

		$args = array(
			'post_title'    => $meeting_title,
			'post_content'  => $meeting_description,
			'post_status'   => 'publish',
			'post_author'   => $user_id,
			'post_type'     => 'academy_meeting',
			'meta_input'    => array(
				'academy_meeting_type' => 'zoom',
				'academy_meeting_request' => $request_body,
				'academy_meeting_response' => $response

			)
		);
		$is_post = wp_insert_post( $args );
		wp_send_json_success( [ 'post_id' => $is_post ] );

	}

	public function update_zoom_meeting() {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}

		$user_id = get_current_user_id();
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$post_id = (int) ( isset( $_POST['post_id'] ) ? sanitize_text_field( $_POST['post_id'] ) : 0 );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_id = (int) ( isset( $_POST['meeting_id'] ) ? sanitize_text_field( $_POST['meeting_id'] ) : 0 );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_title = ( isset( $_POST['meetingTitle'] ) ? sanitize_text_field( $_POST['meetingTitle'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_description = ( isset( $_POST['meetingSummary'] ) ? sanitize_text_field( $_POST['meetingSummary'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_date = ( isset( $_POST['meetingDate'] ) ? sanitize_text_field( $_POST['meetingDate'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_time = ( isset( $_POST['meetingTime'] ) ? sanitize_text_field( $_POST['meetingTime'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_duration = ( isset( $_POST['meetingDuration'] ) ? sanitize_text_field( $_POST['meetingDuration'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$meeting_duration_unit = ( isset( $_POST['meetingTimeUnit'] ) ? sanitize_text_field( $_POST['meetingTimeUnit'] ) : 'minute' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$timezone = ( isset( $_POST['meetingTimeZone'] ) ? sanitize_text_field( $_POST['meetingTimeZone'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$password = sanitize_text_field( $_POST['meetingPassword'] );

		$meeting_start_time    = \DateTime::createFromFormat( 'Y-m-d H:i', $meeting_date . ' ' . $meeting_time );
		if ( ! $meeting_start_time ) {
			wp_send_json_error( __( 'Sorry, Invalid Date Time Format', 'academy-pro' ) );
		}

		$request_body     = wp_json_encode(array(
			'topic'      => $meeting_title,
			'type'       => 2,
			'start_time' => $meeting_start_time->format( 'Y-m-d\TH:i:s' ),
			'timezone'   => $timezone,
			'duration'   => ( 'hour' === $meeting_duration_unit ? $meeting_duration * 60 : $meeting_duration ),
			'password'   => $password,
			'settings'   => self::get_user_zoom_settings( $user_id ),
		));

			$response_code = wp_remote_retrieve_response_code(wp_remote_post('https://api.zoom.us/v2/meetings/' . $meeting_id, array(
				'method'     => 'PATCH',
				'headers' => array(
					'Authorization' => 'Bearer ' . self::get_access_token( $user_id ),
					'Content-Type' => 'application/json',
				),
				'sslverify'  => false,
				'body'  => $request_body
			)));

		if ( 204 !== (int) $response_code ) {
			wp_send_json_error( __( 'Sorry, Failed to update zoom meeting', 'academy-pro' ) );
		}

		// Update Existing Response
		$zoom_response = json_decode( get_post_meta( $post_id, 'academy_meeting_response', true ), true );
		$zoom_response['topic']   = $meeting_title;
		$zoom_response['start_time'] = $meeting_start_time->format( 'Y-m-d\TH:i:s' );
		$zoom_response['duration'] = ( 'hour' === $meeting_duration_unit ? $meeting_duration * 60 : $meeting_duration );
		$zoom_response['timezone'] = $timezone;
		$zoom_response['password'] = $password;
		$zoom_response['settings'] = array_merge( $zoom_response['settings'], self::get_user_zoom_settings( $user_id ) );

		$args = array(
			'ID' => $post_id,
			'post_title'    => $meeting_title,
			'post_content'  => $meeting_description,
			'post_status'   => 'publish',
			'post_author'   => $user_id,
			'post_type'     => 'academy_meeting',
			'meta_input'    => array(
				'academy_meeting_type' => 'zoom',
				'academy_meeting_request' => $request_body,
				'academy_meeting_response' => wp_json_encode( $zoom_response )

			)
		);
		$is_post = wp_update_post( $args );
		wp_send_json_success( [ 'post_id' => $is_post ] );
	}

	public function delete_zoom_meeting( $meeting_id, $post_id ) {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}
		$user_id = get_current_user_id();

		$request_body     = wp_json_encode(array(
			'meetingId' => $meeting_id,
		));

		$response_code = wp_remote_retrieve_response_code(wp_remote_post('https://api.zoom.us/v2/meetings/' . $meeting_id, array(
			'method'     => 'DELETE',
			'headers' => array(
				'Authorization' => 'Bearer ' . self::get_access_token( $user_id ),
				'Content-Type' => 'application/json',
			),
			'sslverify'  => false,
			'body'  => $request_body
		)));

		if ( 204 !== (int) $response_code && 404 !== $response_code ) {
			wp_send_json_error( __( 'Sorry, Failed to Delete Zoom Meeting.', 'academy-pro' ) );
		}

		wp_delete_post( $post_id, true );
		wp_send_json_success( [ 'post_id' => $post_id ] );
	}

}
