<?php

namespace Barn2\Plugin\Password_Protected_Categories;

use Barn2\Plugin\Password_Protected_Categories\Dependencies\Lib\Registerable;
use Barn2\Plugin\Password_Protected_Categories\Dependencies\Lib\Service\Premium_Service;

/**
 * The class handles the display of the password login form for a protected category or post. It also handles category login attempts.
 *
 * @package   Barn2\password-protected-categories
 * @author    Barn2 Plugins <support@barn2.co.uk>
 * @license   GPL-3.0
 * @copyright Barn2 Media Ltd
 */
class Password_Form implements Premium_Service, Registerable {

	private static $form_id = 1;

	public function register() {
		\add_action( 'wp', [ $this, 'handle_login' ] );

		add_filter( 'ppc_the_login_form_message', 'wptexturize' );
		add_filter( 'ppc_the_login_form_message', 'convert_smilies' );
		add_filter( 'ppc_the_login_form_message', 'convert_chars' );
		add_filter( 'ppc_the_login_form_message', 'wpautop' );
		add_filter( 'ppc_the_login_form_message', 'shortcode_unautop' );
		add_filter( 'ppc_the_login_form_message', 'do_shortcode' );
	}

	public function handle_login() {
		global $wp_did_header;

		if ( ! $wp_did_header || 'POST' !== $_SERVER['REQUEST_METHOD'] || ! isset( $_POST['ppc_login'] ) ) {
			return;
		}

		if ( ! isset( $_POST['ppc_nonce'] ) || ! \wp_verify_nonce( \sanitize_key( $_POST['ppc_nonce'] ), 'ppc_login' ) ) {
			return;
		}

		if ( ! ( $password = isset( $_POST['post_password'] ) ? sanitize_text_field( $_POST['post_password'] ) : false ) ) {
			return;
		}

		$term_visibilities  = [];
		$central_login_page = false;

		if ( isset( $_POST['ppc_central_login'] ) ) {
			$central_login_page = true;
		}

		if ( $central_login_page ) {
			// Submitting from page with [category_login] shortcode or from sidebar widget, so check all terms.
			$term_visibilities = PPC_Util::to_term_visibilities( PPC_Util::get_password_protected_terms() );
		} elseif ( PPC_Util::is_protectable_category() ) {
			// Submitting from catetory or taxonomy archive.
			$term_visibilities[] = PPC_Util::get_term_visibility( \get_queried_object() );
		} elseif ( PPC_Util::is_protectable_single_post() ) {
			// Submitting from single post, page or attachment.
			$term_visibilities = PPC_Util::get_the_term_visibility();
		}

		if ( ! $term_visibilities ) {
			return;
		}

		foreach ( $term_visibilities as $term_visibility ) {
			if ( $term = $term_visibility->check_password( $password ) ) {
				// Valid password so set password cookie, then redirect
				PPC_Util::set_password_cookie( $term, $password );

				// If submitting form from central login page (i.e. shortcode) then redirect to the unlocked category archive.
				if ( $central_login_page ) {
					\wp_safe_redirect( \get_term_link( $term ) );
				} else {
					// Otherwise redirect back to same page the form was submitted from.
					\wp_safe_redirect( \add_query_arg( null, null ) );
				}

				return;
			}
		}
	}

	public function display_password_form( $message = '' ) {
		echo $this->get_password_form( $message );
	}

	public function get_password_form( $atts = '', $central_login = true ) {
		$container_class = \apply_filters( 'ppc_category_login_form_container', 'ppc-login-form-container' );
		$form_id         = 'ppc-login-form-' . self::$form_id;
		$form_class      = \apply_filters( 'ppc_login_form_class', 'ppc-login-form post-password-form' );
		$form_action     = \add_query_arg( null, null ); // the current page

		$form_values = PPC_Util::merge_form_values( $atts );
		
		$heading = !empty($form_values['heading']) ? apply_filters( 'ppc_the_login_form_heading', esc_html($form_values['heading']) ) : '';
		$show_heading = !empty($form_values['show_heading']) ? apply_filters( 'ppc_the_login_form_show_heading', $form_values['show_heading'] ) : '';
		$form_message = !empty($form_values['message']) ? apply_filters( 'ppc_the_login_form_message', $form_values['message'] ) : '';
		$password_label = !empty($form_values['label']) ? apply_filters( 'ppc_the_login_form_password_label', esc_html($form_values['label']) ) : '';
		$button_text = !empty($form_values['button_text']) ? apply_filters( 'ppc_the_login_form_button_text', sanitize_text_field( $form_values['button_text'] ) ) : '';
		$form_message .= $this->get_error_message();

		$placeholder    = '';

		if ( PPC_Util::get_option( 'form_label_placeholder' ) ) {
			$placeholder    = $password_label;
			$password_label = '';
		}

		\ob_start();
		\do_action( 'ppc_before_category_login_form' );
		?>
		<div class="<?php echo \esc_attr( $container_class ); ?>">
			<form id="<?php echo \esc_attr( $form_id ); ?>" action="<?php echo \esc_url( $form_action ); ?>" class="<?php echo \esc_attr( $form_class ); ?>" method="post">
				<?php if ( $show_heading == 'true' ) : ?>
					<h3 class="ppc-password-heading"><?php echo \wp_kses_post( $heading ); ?></h3>
				<?php endif; ?>
				<?php echo \wp_kses_post( $form_message ); ?>
				<p>
					<?php
					\printf(
						'<label class="ppc-password-label" for="%1$s">%2$s<input type="password" name="post_password" id="%1$s" class="ppc-login-form-password" size="25" placeholder="%3$s" autofocus/></label>',
						\esc_attr( 'pwbox-' . self::$form_id ),
						( $password_label ? sprintf( '<span class="ppc-login-form-label-text">%s</span>', $password_label ) : '' ),
						\esc_attr( $placeholder )
					);
					?>
					<input type="submit" name="Submit" class="ppc-login-form-submit" value="<?php echo \esc_attr( $button_text ); ?>" />
					<input type="hidden" name="ppc_login" value="<?php echo \esc_attr( self::$form_id ); ?>" />
					<?php \wp_nonce_field( 'ppc_login', 'ppc_nonce' ); ?>
					<?php if ( $central_login ) : ?>
						<input type="hidden" name="ppc_central_login" value="1" />
					<?php endif; ?>
				</p>
			</form>
		</div>
		<?php
		\do_action( 'ppc_after_category_login_form' );

		self::$form_id ++;

		return \apply_filters( 'ppc_category_login_form', \ob_get_clean() );
	}

	private function get_error_message() {
		if ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
			return '';
		}

		$submitted_form_id = isset( $_POST['ppc_login'] ) ? absint( $_POST['ppc_login'] ) : false;

		// Check the passed form ID matches the one in $_POST
		if ( ! $submitted_form_id || self::$form_id !== (int) $submitted_form_id ) {
			return '';
		}

		$error    = '';
		$password = isset( $_POST['post_password'] ) ? sanitize_text_field( $_POST['post_password'] ) : false;

		if ( ! $password ) {
			$error = __( 'Please enter a password.', 'password-protected-categories' );
		} else {
			// If we have a password, and we're doing a POST request (therefore we haven't redirected), then the password must be wrong.
			$error = __( 'Incorrect password, please try again.', 'password-protected-categories' );
		}

		return $error ? \sprintf( '<p class="ppc-login-error">%s</p>', $error ) : '';
	}

}
