<?php
/**
 * @package Hafenstudios\Kurato
 */

namespace Hafenstudios\Kurato\Rest;

use Hafenstudios\Core\Events\EventBus;
use Hafenstudios\Kurato\Doi\DoiService;

defined( 'ABSPATH' ) || exit;

/**
 * Oeffentlicher Abo-Bestaetigungs-Endpoint (`kurato/v1/confirm`).
 *
 * Kein Login (Bestaetigungslink aus der DOI-Mail), aber mit Rate Limit und
 * signiertem Token. Der Abmelde-Endpoint folgt in K4c zusammen mit den
 * Versand-Mails, die den Abmeldelink erst erzeugen.
 */
final class SubscriptionsController {

	public const REST_NAMESPACE = 'kurato/v1';

	private DoiService $doi;

	/**
	 * @param DoiService $doi Kurato-DOI-Service.
	 */
	public function __construct( DoiService $doi ) {
		$this->doi = $doi;
	}

	/**
	 * Registriert die Route.
	 *
	 * @return void
	 */
	public function register_routes(): void {
		register_rest_route(
			self::REST_NAMESPACE,
			'/confirm',
			array(
				'methods'             => array( \WP_REST_Server::READABLE, \WP_REST_Server::CREATABLE ),
				'callback'            => array( $this, 'confirm' ),
				'permission_callback' => '__return_true',
				'args'                => array(
					'token' => array( 'type' => 'string', 'required' => true ),
				),
			)
		);
	}

	/**
	 * Bestaetigt ein Abo per Token.
	 *
	 * @param \WP_REST_Request $request Request.
	 * @return \WP_REST_Response|\WP_Error
	 */
	public function confirm( \WP_REST_Request $request ) {
		$ip  = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
		$key = 'kurato_confirm_' . md5( $ip );

		$count = (int) get_transient( $key );
		if ( $count >= 15 ) {
			return new \WP_Error(
				'kurato_rate_limited',
				__( 'Es wurden zu viele Bestaetigungsversuche gesendet. Bitte versuchen Sie es in einigen Minuten erneut.', 'kurato' ),
				array( 'status' => 429 )
			);
		}
		set_transient( $key, $count + 1, 10 * MINUTE_IN_SECONDS );

		$sub = $this->doi->confirm( (string) $request->get_param( 'token' ) );
		if ( is_wp_error( $sub ) ) {
			// Klick aus der Mail: gepflegte Seite statt JSON (L-F3-Muster).
			if ( \Hafenstudios\Core\Http\BrowserResponse::is_browser_request() ) {
				\Hafenstudios\Core\Http\BrowserResponse::send_page(
					__( 'Bestaetigung nicht moeglich', 'kurato' ),
					$sub->get_error_message(),
					false,
					400
				);
			}
			return $sub;
		}

		// Flotten-Event nur beim ersten Bestaetigen (idempotent, wie Leadlotse).
		if ( ! empty( $sub['_newly_confirmed'] ) ) {
			EventBus::emit(
				'subscription_confirmed',
				array(
					'subscription_id' => (int) $sub['id'],
					'list_id'         => (int) $sub['list_id'],
					'contact_id'      => (int) $sub['contact_id'],
				)
			);
		}

		$message = __( 'Vielen Dank. Ihre Anmeldung ist bestaetigt.', 'kurato' );

		if ( \Hafenstudios\Core\Http\BrowserResponse::is_browser_request() ) {
			\Hafenstudios\Core\Http\BrowserResponse::send_page(
				__( 'Anmeldung bestaetigt', 'kurato' ),
				$message
			);
		}

		return new \WP_REST_Response(
			array(
				'confirmed' => true,
				'message'   => $message,
			),
			200
		);
	}
}
