<?php
/**
 * WP Courseware Students Functions.
 *
 * @package WPCW
 * @subpackage Functions
 * @since 4.3.0
 */

// Exit if accessed directly
defined( 'ABSPATH' ) || exit;

/**
 * Get Student.
 *
 * @since 4.3.0
 *
 * @param int|bool $student_id The Student Id.
 *
 * @return \WPCW\Models\Student|bool An student object or false.
 */
function wpcw_get_student( $student_id = false ) {
	if ( ! did_action( 'wpcw_loaded' ) ) {
		wpcw_doing_it_wrong( __FUNCTION__, 'wpcw_get_student should not be called the student object is setup.', '4.3.0' );

		return false;
	}

	return new \WPCW\Models\Student( $student_id );
}

/**
 * Get Test Student.
 *
 * @since 4.3.0
 *
 * @return \WPCW\Models\Student $test_student The test student object.
 */
function wpcw_get_test_student() {
	$test_student = new \WPCW\Models\Student();

	$test_data = array(
		'ID'                  => rand(),
		'user_login'          => 'teststudent',
		'user_pass'           => wp_generate_password(),
		'user_nicename'       => 'teststudent',
		'user_email'          => 'wpcw.test.student@wpcwtest.com',
		'user_url'            => '',
		'user_registered'     => date( 'Y-m-d H:i:s' ),
		'user_activation_key' => uniqid(),
		'user_status'         => 0,
		'display_name'        => esc_html__( 'John Smith', 'wp-courseware' ),
		'first_name'          => esc_html__( 'John', 'wp-courseware' ),
		'last_name'           => esc_html__( 'Smith', 'wp-courseware' ),
		'email'               => 'wpcw.test.student@wpcwtest.com',
		'billing_address_1'   => esc_html__( '430 E. WP Courseware Street', 'wp-courseware' ),
		'billing_address_2'   => esc_html__( 'Suite 120', 'wp-courseware' ),
		'billing_city'        => esc_html__( 'Phoenix', 'wp-courseware' ),
		'billing_state'       => esc_html__( 'AZ', 'wp-courseware' ),
		'billing_postcode'    => esc_html__( '85001', 'wp-courseware' ),
		'billing_country'     => esc_html__( 'United States', 'wp-courseware' ),
	);

	$test_student->set_data( $test_data );

	return $test_student;
}

/**
 * Create a new student.
 *
 * @since 4.3.0
 *
 * @param string $email Student email.
 * @param string $username Student username.
 * @param string $password Student password.
 * @param array $courses The courses the student should be enrolled into.
 *
 * @return int|WP_Error Returns WP_Error on failure, Int (user ID) on success.
 */
if ( ! function_exists( 'wpcw_create_new_student' ) ) {
	function wpcw_create_new_student( $email, $username = '', $password = '', $courses = array() ) {
		// Check Email.
		if ( empty( $email ) || ! is_email( $email ) ) {
			return new WP_Error( 'registration-error-invalid-email', esc_html__( 'Please provide a valid email address.', 'wp-courseware' ) );
		}

		// Existing Email?
		if ( email_exists( $email ) ) {
			return new WP_Error( 'registration-error-email-exists', apply_filters( 'wpcw_registration_error_email_exists', esc_html__( 'An account is already registered with your email address. Please log in.', 'wp-courseware' ), $email ) );
		}

		// Username.
		if ( ! empty( $username ) ) {
			$username = sanitize_user( $username );

			if ( empty( $username ) || ! validate_username( $username ) ) {
				return new WP_Error( 'registration-error-invalid-username', esc_html__( 'Please enter a valid account username.', 'wp-courseware' ) );
			}

			if ( username_exists( $username ) ) {
				return new WP_Error( 'registration-error-username-exists', esc_html__( 'An account is already registered with that username. Please choose another.', 'wp-courseware' ) );
			}
		} else {
			$username = sanitize_user( current( explode( '@', $email ) ), true );

			$append     = 1;
			$o_username = $username;

			while ( username_exists( $username ) ) {
				$username = $o_username . $append;
				$append++;
			}
		}

		// Password.
		if ( empty( $password ) ) {
			$password           = wp_generate_password();
			$password_generated = true;
		} elseif ( empty( $password ) ) {
			return new WP_Error( 'registration-error-missing-password', __( 'Please enter an account password.', 'wp-courseware' ) );
		} else {
			$password_generated = false;
		}

		// Use WP_Error to handle registration errors.
		$errors = new WP_Error();

		do_action( 'wpcw_register_student_before', $username, $email, $errors );

		$errors = apply_filters( 'wpcw_registration_errors', $errors, $username, $email );

		if ( $errors->get_error_code() ) {
			return $errors;
		}

		/**
		 * Fitler: New Student Data.
		 *
		 * @since 4.3.0
		 *
		 * @param array The new student data.
		 *
		 * @return array The modified student data.
		 */
		$new_student_data = apply_filters( 'wpcw_new_student_data', array(
			'user_login' => $username,
			'user_pass'  => $password,
			'user_email' => $email,
			'role'       => 'subscriber',
		) );

		$student_id = wp_insert_user( $new_student_data );

		if ( is_wp_error( $student_id ) ) {
			return new WP_Error( 'registration-error', '<strong>' . __( 'Error:', 'wp-courseware' ) . '</strong> ' . __( 'Couldn&#8217;t register you&hellip; please contact us if you continue to have problems.', 'wp-courseware' ) );
		}

		if ( ! empty( $courses ) ) {
			wpcw()->enrollment->enroll_student( $student_id, $courses );
		}

		/**
		 * Action: Created Student.
		 *
		 * @since 4.3.0
		 *
		 * @param int $student_id The student id.
		 * @param array $new_student_data The new student data.
		 * @param string $password_generated The newly generated password.
		 */
		do_action( 'wpcw_created_student', $student_id, $new_student_data, $password_generated );

		/**
		 * Action: Student Registered
		 *
		 * @since 4.3.0
		 *
		 * @param int $student_id The student id.
		 * @param array $new_student_data The new student data.
		 * @param string $password_generated The newly generated password.
		 */
		do_action( 'wpcw_student_registered', $student_id, $new_student_data, $password_generated );

		return $student_id;
	}
}

/**
 * Login a student (set auth cookie and set global user object).
 *
 * @since 4.3.0
 *
 * @param int $student_id
 */
function wpcw_set_student_auth_cookie( $student_id ) {
	global $current_user;

	$current_user = get_user_by( 'id', $student_id );

	wp_set_auth_cookie( $student_id, true );
}

/**
 * Get Student Account Menu Items.
 *
 * @since 4.3.0
 *
 * @return array The array of menu items.
 */
function wpcw_get_student_account_menu_items() {
	$endpoints = array(
		'courses'        => wpcw_get_setting( 'student_courses_endpoint', 'courses' ),
		'orders'         => wpcw_get_setting( 'student_orders_endpoint', 'orders' ),
		'subscriptions'  => wpcw_get_setting( 'student_subscriptions_endpoint', 'subscriptions' ),
		'edit-account'   => wpcw_get_setting( 'student_edit_account_endpoint', 'edit-account' ),
		'student-logout' => wpcw_get_setting( 'student_logout_endpoint', 'student-logout' ),
	);

	$menu_items = array(
		'dashboard'      => esc_html__( 'Dashboard', 'wp-courseware' ),
		'courses'        => esc_html__( 'Courses', 'wp-courseware' ),
		'orders'         => esc_html__( 'Orders', 'wp-courseware' ),
		'subscriptions'  => esc_html__( 'Subscriptions', 'wp-courseware' ),
		'edit-account'   => esc_html__( 'Account', 'wp-courseware' ),
		'student-logout' => esc_html__( 'Logout', 'wp-courseware' ),
	);

	// Remove missing endpoints.
	foreach ( $endpoints as $endpoint_id => $endpoint ) {
		if ( empty( $endpoint ) ) {
			unset( $menu_items[ $endpoint_id ] );
		}
	}

	/**
	 * Action: Student Account Menu Items.
	 *
	 * @since 4.3.0
	 *
	 * @param array $menu_items The student account menu items.
	 */
	return apply_filters( 'wpcw_student_account_menu_items', $menu_items );
}

/**
 * Get Student Account Menu Items Classes.
 *
 * @since 4.3.0
 *
 * @param string $endpoint The account endpoint.
 *
 * @return string The account endpoint classes.
 */
function wpcw_get_student_account_menu_item_classes( $endpoint ) {
	global $wp;

	$classes = array(
		'wpcw-student-account-navigation-link',
		'wpcw-student-account-navigation-link-' . $endpoint,
	);

	// Set current item class.
	$current = isset( $wp->query_vars[ $endpoint ] );
	if ( 'dashboard' === $endpoint && ( isset( $wp->query_vars['page'] ) || empty( $wp->query_vars ) ) ) {
		$current = true; // Dashboard is not an endpoint, so needs a custom check.
	}

	if ( 'orders' === $endpoint && ( isset( $wp->query_vars['view-order'] ) ) ) {
		$current = true;
	}

	if ( 'subscriptions' === $endpoint && ( isset( $wp->query_vars['view-subscription'] ) ) ) {
		$current = true;
	}

	if ( $current ) {
		$classes[] = 'is-active';
	}

	/**
	 * Filter: Student Account Menu Item Classes.
	 *
	 * @since 4.3.0
	 */
	$classes = apply_filters( 'wpcw_student_account_menu_item_classes', $classes, $endpoint );

	return implode( ' ', array_map( 'sanitize_html_class', $classes ) );
}

/**
 * Get Student Account Endpoint Url.
 *
 * @since 4.3.0
 *
 * @param string $endpoint The endpoint string.
 *
 * @return string The endpoint url.
 */
function wpcw_get_student_account_endpoint_url( $endpoint ) {
	if ( 'dashboard' === $endpoint ) {
		return wpcw_get_page_permalink( 'account' );
	}

	if ( 'student-logout' === $endpoint ) {
		return wpcw_logout_url();
	}

	return wpcw_get_endpoint_url( $endpoint, '', wpcw_get_page_permalink( 'account' ) );
}

/**
 * Get Student Account Order Actions.
 *
 * @since 4.3.0
 *
 * @param int|\WPCW\Models\Order $order The order object.
 *
 * @return array The array of action items.
 */
function wpcw_get_student_account_orders_actions( $order ) {
	if ( ! is_object( $order ) ) {
		$order_id = absint( $order );
		$order    = wpcw_get_order( $order_id );
	}

	$actions = array(
		'view'   => array(
			'url'  => $order->get_view_order_url(),
			'name' => __( 'View', 'wp-courseware' ),
		),
		'cancel' => array(
			'url'  => $order->get_order_cancel_url( wpcw_get_page_permalink( 'account' ) ),
			'name' => __( 'Cancel', 'wp-courseware' ),
		),
	);

	if ( ! in_array( $order->get_status(), apply_filters( 'wpcw_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ) ) {
		unset( $actions['cancel'] );
	}

	/**
	 * Filter: Student Account Order Actions.
	 *
	 * @since 4.3.0
	 *
	 * @param array $actions The order actions.
	 * @param \WPCW\Models\Order $order The order object.
	 */
	return apply_filters( 'wpcw_student_account_order_actions', $actions, $order );
}

/**
 * Get Student Progress Bar.
 *
 * @since 4.3.0
 *
 * @param int $student_id The student id.
 * @param int $course_id The course id.
 *
 * @return string $student_progress The student progress bar.
 */
function wpcw_get_student_progress_bar( $student_id, $course_id = 0 ) {
	return wpcw()->students->get_student_progress_bar( $student_id, $course_id );
}

/**
 * Student Account Content.
 *
 * @since 4.3.0
 */
if ( ! function_exists( 'wpcw_student_account_content' ) ) {
	function wpcw_student_account_content() {
		global $wp;

		if ( ! empty( $wp->query_vars ) ) {
			foreach ( $wp->query_vars as $key => $value ) {
				if ( 'pagename' === $key ) {
					continue;
				}

				if ( has_action( 'wpcw_student_account_' . $key . '_endpoint' ) ) {
					do_action( 'wpcw_student_account_' . $key . '_endpoint', $value );
					return;
				}
			}
		}

		wpcw_get_template( 'account/account-dashboard.php', array( 'student' => get_user_by( 'id', get_current_user_id() ) ) );
	}
}

/**
 * Student Account Navigation.
 *
 * @since 4.3.0
 */
if ( ! function_exists( 'wpcw_student_account_navigation' ) ) {
	function wpcw_student_account_navigation() {
		wpcw_get_template( 'account/account-navigation.php' );
	}
}

/**
 * Student Account Courses.
 *
 * @since 4.3.0
 *
 * @param int $current_page The current page of courses.
 */
if ( ! function_exists( 'wpcw_student_account_courses' ) ) {
	function wpcw_student_account_courses( $current_page ) {
		$current_page = empty( $current_page ) ? 1 : absint( $current_page );

		$courses = wpcw_get_courses( apply_filters( 'wpcw_student_account_courses_query', array(
			'student_id' => get_current_user_id(),
			'page'       => $current_page,
		) ) );

		wpcw_get_template( 'account/account-view-courses.php', array( 'courses' => $courses, 'current_page' => absint( $current_page ) ) );
	}
}

/**
 * Student Account Orders.
 *
 * @since 4.3.0
 *
 * @param int $current_page The current page of orders.
 */
if ( ! function_exists( 'wpcw_student_account_orders' ) ) {
	function wpcw_student_account_orders( $current_page ) {
		$current_page = empty( $current_page ) ? 1 : absint( $current_page );

		$orders = wpcw_get_orders( apply_filters( 'wpcw_student_account_orders_query', array(
			'student_id' => get_current_user_id(),
			'page'       => $current_page,
		) ) );

		wpcw_get_template( 'account/account-view-orders.php', array( 'orders' => $orders, 'current_page' => absint( $current_page ) ) );
	}
}

/**
 * Student Account View Order.
 *
 * @since 4.3.0
 *
 * @param int $order_id The order id.
 */
if ( ! function_exists( 'wpcw_student_account_view_order' ) ) {
	function wpcw_student_account_view_order( $order_id ) {
		$order = wpcw_get_order( $order_id );

		if ( get_current_user_id() !== $order->get_student_id() ) {
			echo '<div class="wpcw-error">' . __( 'Invalid order.', 'wp-courseware' ) . ' <a href="' . wpcw_get_page_permalink( 'account' ) . '" class="wpcw-forward">' . __( 'Account', 'wp-courseware' ) . '</a>' . '</div>';
			return;
		}

		wpcw_get_template( 'account/account-view-order.php', array( 'order' => $order, 'order_id' => $order_id ) );
	}
}

/**
 * Student Account Subscriptions.
 *
 * @since 4.3.0
 *
 * @param int $current_page The current page of subscriptions.
 */
if ( ! function_exists( 'wpcw_student_account_subscriptions' ) ) {
	function wpcw_student_account_subscriptions( $current_page ) {
		$current_page = empty( $current_page ) ? 1 : absint( $current_page );

		$subscriptions = wpcw_get_subscriptions( apply_filters( 'wpcw_student_account_subscriptions_query', array(
			'student_id' => get_current_user_id(),
			'page'       => $current_page,
		) ) );

		wpcw_get_template( 'account/account-view-subscriptions.php', array( 'subscriptions' => $subscriptions, 'current_page' => absint( $current_page ) ) );
	}
}

/**
 * Student Account View Subscription.
 *
 * @since 4.3.0
 */
if ( ! function_exists( 'wpcw_student_account_view_subscription' ) ) {
	function wpcw_student_account_view_subscription( $subscription_id ) {
		$subscription = wpcw_get_subscription( $subscription_id );

		if ( get_current_user_id() !== $subscription->get_student_id() ) {
			wpcw_print_notice( sprintf( __( 'Invalid Subscription <a href="%s">View Account &rarr;</a>', 'wp-courseware' ), wpcw_get_page_permalink( 'account' ) ), 'info' );
			return;
		}

		wpcw_get_template( 'account/account-view-subscription.php', array( 'subscription' => $subscription, 'subscription_id' => $subscription_id ) );
	}
}

/**
 * Student Edit Account.
 *
 * @since 4.3.0
 */
if ( ! function_exists( 'wpcw_student_account_edit_account' ) ) {
	function wpcw_student_account_edit_account() {
		$current_student = wp_get_current_user();
		$address         = array();

		if ( wpcw()->students->account_billing_fields_enabled() ) {
			$address = wpcw()->countries->get_billing_address_fields( get_user_meta( get_current_user_id(), 'billing_country', true ), 'billing_' );

			foreach ( $address as $key => $field ) {
				$value = get_user_meta( get_current_user_id(), $key, true );

				if ( ! $value ) {
					switch ( $key ) {
						case 'billing_email' :
							$value = $current_student->user_email;
							break;
						case 'billing_country' :
							$value = wpcw()->countries->get_base_country();
							break;
						case 'billing_state' :
							$value = wpcw()->countries->get_base_state();
							break;
					}
				}

				$address[ $key ]['value'] = apply_filters( 'wpcw_student_account_edit_address_field_value', $value, $key, 'billing' );
			}
		}

		wpcw_get_template( 'account/form-edit-account.php', array(
			'student' => get_user_by( 'id', get_current_user_id() ),
			'address' => $address,
		) );
	}
}