<?php

namespace Emoxie\Expandable_Paywall;

use WP_Error;

class Helper {

	static public string $default_paywall_type = 'basic';
	static public string $default_authentication_type = 'wordpress';
	static protected array $default_paywall_types = [ 'none', 'basic' ];
	static protected array $default_authentication_types = [ 'wordpress' => 'Native Wordpress' ];
	static protected string $default_authentication_role_non_paid = 'subscriber';
	static protected string $default_authentication_role_paid = 'paid_subscriber';
	static protected int $default_excerpt_length = 55;

	static protected array $roles_that_bypass_paywall = [ 'administrator', 'editor', 'author' ];
	static protected array $roles_that_bypass_authentication = [ 'administrator', 'editor', 'author' ];

	/**
	 * @return array
	 */
	static public function paywall_types(): array {
		return apply_filters( EXPANDABLE_PAYWALL_SLUG . '_paywall_types', self::$default_paywall_types );
	}

	/**
	 * @return string
	 */
	static public function active_paywall(): string {
		return (string) get_option( EXPANDABLE_PAYWALL_SLUG . '_paywall_type', self::$default_paywall_type );
	}

	/**
	 * @return array
	 */
	static public function authentication_types(): array {
		return apply_filters( EXPANDABLE_PAYWALL_SLUG . '_authentication_types', self::$default_authentication_types );
	}




	static public function show_authentication_role_paid(): bool {
		if ( 'metered' === Helper::active_paywall() || 'darwin' === Helper::active_authentication() || apply_filters( EXPANDABLE_PAYWALL_SLUG . '_show_authentication_role_paid', false ) ) { //TODO document this
			return true;
		}

		return false;
	}

	/**
	 * @return string
	 */
	static public function active_authentication(): string {
		return get_option( EXPANDABLE_PAYWALL_SLUG . '_authentication_type', self::$default_authentication_type );
	}

	/**
	 * @return mixed|void
	 */
	static public function authentication_role_non_paid() {
		return get_option( EXPANDABLE_PAYWALL_SLUG . '_authentication_role_non_paid', self::$default_authentication_role_non_paid );
	}

	/**
	 * @return mixed|void
	 */
	static public function authentication_role_paid() {
		return get_option( EXPANDABLE_PAYWALL_SLUG . '_authentication_role_paid', self::$default_authentication_role_paid );
	}

	/**
	 * @return array
	 */
	static public function authentication_roles(): array {
		return [ self::authentication_role_paid(), self::authentication_role_non_paid() ];
	}

	/**
	 * @return mixed|void
	 */
	static public function paywall_excerpt_length() {
		return apply_filters( EXPANDABLE_PAYWALL_SLUG . '_paywall_excerpt_length', self::$default_excerpt_length );
	}

	static public function roles_that_bypass_paywall() {
		return apply_filters( EXPANDABLE_PAYWALL_SLUG . '_roles_that_bypass_paywall', self::$roles_that_bypass_paywall );
	}

	static public function excluded_roles_from_authentication() {
		return apply_filters( EXPANDABLE_PAYWALL_SLUG . '_roles_that_bypass_authentication', self::$roles_that_bypass_authentication );
	}

	static public function post_types() {
		return apply_filters( EXPANDABLE_PAYWALL_SLUG . '_post_types', maybe_unserialize( get_option( EXPANDABLE_PAYWALL_SLUG . '_paywall_basic_post_types' ) ) );
	}

	static public function is_authenticated() {
		return apply_filters( EXPANDABLE_PAYWALL_SLUG . '_authenticated', self::authenticated() );
	}

	static public function protected_categories() {
		return apply_filters( EXPANDABLE_PAYWALL_SLUG . '_protected_categories', maybe_unserialize( get_option( EXPANDABLE_PAYWALL_SLUG . '_paywall_basic_include_categories' ) ) );
	}

	static public function forgot_password_url() {
		return apply_filters( EXPANDABLE_PAYWALL_SLUG . '_forgot_password_url', wp_lostpassword_url() );
	}

	static public function native_authentication_roles(){
		return apply_filters( EXPANDABLE_PAYWALL_SLUG . '_local_authentication_roles', [ 'administrator', 'editor', 'author' ]);
	}

	/**
	 * @param null $selected
	 *
	 * @return string
	 */
	static public function get_categories_dropdown( $selected = null ): string {
		$categories = get_categories( [ 'hide_empty' => 0 ] );
		$dropdown   = '';
		if ( is_null( $selected ) ) {
			$selected = (array) maybe_unserialize( get_option( EXPANDABLE_PAYWALL_SLUG . '_paywall_basic_include_categories' ) );
		}

		foreach ( $categories as $category ) {
			$dropdown .= '<option value="' . $category->term_id . '"';

			if ( in_array( $category->term_id, $selected ) ) {
				$dropdown .= ' selected="selected"';
			}

			$dropdown .= '>' . $category->name . '</option>';
		}

		return $dropdown;
	}


	/**
	 * Check if the user is authenticated.
	 *
	 * @return bool True if the user is authenticated, false otherwise.
	 */
	static private function authenticated(): bool {
		if ( ! is_user_logged_in() ) {
			return false;
		}

		$current_user = wp_get_current_user();
		$user_roles   = $current_user->roles;
		Logger::log( 'authenticated', 'Current User Role(s) = ' . print_r( $user_roles, true ) );

		if ( is_super_admin( $current_user->ID ) || ! empty( array_intersect( $user_roles, self::roles_that_bypass_paywall() ) ) ) {
			Logger::log( 'authenticated', is_super_admin( $current_user->ID ) ? 'User is Super Admin' : 'User IS in roles that bypass paywall' );

			return true;
		}

		Logger::log( 'authenticated', empty( $user_roles ) ? 'User has no role set' : 'User is not authenticated' );

		return false;
	}


	static public function get_current_url(): string {
		global $wp;

		return home_url( add_query_arg( [], $wp->request ) );
	}

	static public function get_referer_url(): string {
		$unique_id     = uniqid();
		$cache_busting = '?cache_busting=' . $unique_id;

		if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
			$referer = $_SERVER['HTTP_REFERER'];

			if ( str_contains( $referer, '?' ) ) {
				$cache_busting = '&cache_busting=' . $unique_id;
			}

			return $referer . $cache_busting;
		}

		return home_url() . $cache_busting;
	}

	/**
	 * @param $message
	 * @param $post_id
	 *
	 * @return void
	 * @deprecated 2.0.20 Use Emoxie\Expandable_Paywall\Logger
	 */
	static public function log( $message, $post_id = null ) {
		_deprecated_function( __FUNCTION__, '2.0.20', 'Emoxie\Expandable_Paywall\Logger' );
	}

	static public function is_admin_user(){
		// The sanitize_text_field function strips out all tags and remove line breaks, tabs, and extra white space
		$username = isset( $_REQUEST['username'] ) ? sanitize_text_field( $_REQUEST['username'] ) : ( isset( $_REQUEST['log'] ) ? sanitize_text_field( $_REQUEST['log'] ) : null );

		if ( ! is_null( $username ) ) {
			$username = strtolower( $username );

			if ( is_multisite() ) {
				$super_admins = get_super_admins();
				if ( is_array( $super_admins ) && in_array( $username, $super_admins, true ) ) {
					return true;
				}
			}

			return in_array( $username, Helper::get_admin_users() );
		}

		// Return false if no username provided
		return false;
	}


	static public function get_admin_users(): array {
		$users = get_users( [
			'role__in' => Helper::native_authentication_roles(),
		] );

		return array_reduce( $users, function ( $carry, $user ) {
			$carry[] = strtolower( $user->user_email );
			$carry[] = strtolower( $user->user_login );

			return $carry;
		}, [] );
	}

	static public function local_authentication() {
		Logger::log('local_authentication', 'Using Local Authentication');

		$username = sanitize_text_field( $_REQUEST['username'] ?? $_REQUEST['log'] ?? '' );
		$password = sanitize_text_field( $_REQUEST['password'] ?? $_REQUEST['pwd'] ?? '' );

		if ( empty( $username ) || empty( $password ) ) {
			return new WP_Error( 'empty_fields', __( 'Username or Password is empty' ) );
		}

		$user = is_email( $username )
			? wp_authenticate_email_password( null, $username, $password )
			: wp_authenticate_username_password( null, $username, $password );

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

		wp_set_auth_cookie( $user->ID, true, true );
		do_action( 'wp_login', $user->user_login, $user );

		return $user;
	}

}