<?php
/**
 * Consent Module Entry Point
 *
 * @package AmbassadorHub\Consent
 */

namespace AmbassadorHub\Consent;

use AmbassadorHub\Donations\DonationsModule;
use AmbassadorHub\Donors\DonorsModule;

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

final class ConsentModule {
	public static function init(): void {
		MigrationRunner::init();
		// The self-service consent REST API (status/withdraw endpoints) ships
		// in the AmbassadorHub Premium add-on, not here.
		Admin\Menu::init();
		Automations::init();
		Admin\Settings\SettingsManager::init();
		self::register_form_hooks();
		do_action( 'ambh_consent_module_init' );
	}

	private static function register_form_hooks(): void {

		// Revoke all donor consent records when a donor is anonymized (GDPR erasure).
		add_action( 'ambh_donor_anonymized', array( self::class, 'handle_donor_anonymized' ), 10, 1 );

		// Ambassador registration form — marketing consent checkbox.
		add_action( 'ambh_render_registration_form_fields', array( self::class, 'render_ambassador_consent_checkbox' ) );
		add_action( 'ambh_successful_signup_from_submission', array( self::class, 'handle_ambassador_consent_submission' ), 10, 2 );

		// Ambassador registration form — privacy policy checkbox.
		add_action( 'ambh_render_registration_form_fields', array( self::class, 'render_ambassador_privacy_policy_checkbox' ), 20 );
		add_action( 'ambh_successful_signup_from_submission', array( self::class, 'handle_ambassador_privacy_policy_submission' ), 20, 2 );

		// Donation form — marketing consent checkbox.
		add_action( 'ambh_render_donation_form_fields', array( self::class, 'render_donor_consent_checkbox' ) );
		add_action( 'ambh_successful_donation_form_submission', array( self::class, 'handle_donor_consent_submission' ), 10, 2 );

		// Donation form — privacy policy checkbox.
		add_action( 'ambh_render_donation_form_fields', array( self::class, 'render_donor_privacy_policy_checkbox' ), 20 );
		add_action( 'ambh_successful_donation_form_submission', array( self::class, 'handle_donor_privacy_policy_submission' ), 20, 2 );
	}

	public static function render_ambassador_consent_checkbox(): void {

		if ( ! get_option( 'ambh_ambassador_consent_enabled' ) ) {
			return; // Consent not enabled, don't render anything
		}

		$text = get_option( 'ambh_ambassador_general_consent_text' );
		if ( $text ) {
			echo '<label class="ambh-consent-checkbox"><input type="checkbox" name="ambh_consent_granted" value="1" required> ' . esc_html( $text ) . '</label>';
		}
	}

	public static function handle_ambassador_consent_submission( int $user_id, array $form_data ): void {
		if ( ! empty( $form_data['ambh_consent_granted'] ) ) {
			ConsentManager::grant(
				'wp_user',
				$user_id,
				ConsentPurpose::MARKETING_AMBASSADOR,
				'email',
				(string) get_option( 'ambh_ambassador_general_consent_text' ),
				'registration_form',
				'global',
				null
			);
		}
	}

	public static function render_donor_consent_checkbox(): void {

		if ( ! get_option( 'ambh_donor_consent_enabled' ) ) {
			return; // Consent not enabled, don't render anything
		}

		$text = get_option( 'ambh_donor_general_consent_text' );
		if ( $text ) {
			echo '<label class="ambh-consent-checkbox"><input type="checkbox" name="ambh_consent_granted" value="1" required> ' . esc_html( $text ) . '</label>';
		}
	}

	public static function handle_donor_consent_submission( int $donation_id, array $form_data ): void {

		$donor_id = DonationsModule::get( $donation_id );
		if ( ! $donor_id ) {
			return; // Donation not found, can't associate consent
		}

		$donor_id = $donor_id->donor_id;
		if ( ! $donor_id ) {
			return; // Donor not found, can't associate consent
		}

		if ( ! empty( $form_data['ambh_consent_granted'] ) ) {
			ConsentManager::grant(
				'donor',
				$donor_id,
				ConsentPurpose::MARKETING_DONOR,
				'email',
				(string) get_option( 'ambh_donor_general_consent_text' ),
				'donation_form',
				'global',
				null
			);
		}
	}

	/**
	 * Render the privacy policy acceptance checkbox on the ambassador registration form.
	 *
	 * Shown only when a privacy policy consent text is configured. The checkbox
	 * is required — the form cannot be submitted without accepting the policy.
	 *
	 * @return void
	 */
	public static function render_ambassador_privacy_policy_checkbox(): void {
		$text = get_option( 'ambh_privacy_policy_consent_text' );
		if ( ! $text ) {
			return;
		}

		echo '<label class="ambh-consent-checkbox ambh-privacy-policy-checkbox"><input type="checkbox" name="ambh_privacy_policy_accepted" value="1" required> ' . esc_html( $text ) . '</label>';
	}

	/**
	 * Record privacy policy acceptance from the ambassador registration form.
	 *
	 * @param int   $user_id   Newly created user ID.
	 * @param array $form_data Submitted form data.
	 *
	 * @return void
	 */
	public static function handle_ambassador_privacy_policy_submission( $user_id, $form_data ): void {
		if ( empty( $form_data['ambh_privacy_policy_accepted'] ) ) {
			return;
		}

		ConsentManager::grant(
			'wp_user',
			$user_id,
			ConsentPurpose::PRIVACY_POLICY,
			'email',
			(string) get_option( 'ambh_privacy_policy_consent_text' ),
			'registration_form',
			'global',
			null
		);
	}

	/**
	 * Render the privacy policy acceptance checkbox on the donation form.
	 *
	 * @return void
	 */
	public static function render_donor_privacy_policy_checkbox(): void {
		$text = get_option( 'ambh_privacy_policy_consent_text' );
		if ( ! $text ) {
			return;
		}

		echo '<label class="ambh-consent-checkbox ambh-privacy-policy-checkbox"><input type="checkbox" name="ambh_donor_privacy_policy_accepted" value="1" required> ' . esc_html( $text ) . '</label>';
	}

	/**
	 * Record privacy policy acceptance from the donation form.
	 *
	 * @param int   $donation_id Donation ID.
	 * @param array $form_data   Submitted form data.
	 *
	 * @return void
	 */
	public static function handle_donor_privacy_policy_submission( $donation_id, $form_data ): void {
		if ( empty( $form_data['ambh_donor_privacy_policy_accepted'] ) ) {
			return;
		}

		$donation = DonationsModule::get( $donation_id );
		if ( ! $donation || ! $donation->donor_id ) {
			return;
		}

		ConsentManager::grant(
			'donor',
			(int) $donation->donor_id,
			ConsentPurpose::PRIVACY_POLICY,
			'email',
			(string) get_option( 'ambh_privacy_policy_consent_text' ),
			'donation_form',
			'global',
			null
		);
	}

	/**
	 * Get the email address associated with a consent subject.
	 *
	 * @param string $subject_type The type of subject (e.g. 'wp_user', 'donor').
	 * @param int $subject_id The ID of the subject.
	 *
	 * @return string|null The email address if found, or null if not available.
	 */
	public static function get_subject_email( string $subject_type, int $subject_id ): ?string {

		$email = null;

		if ( 'wp_user' === $subject_type ) {
			$user_info = get_userdata( $subject_id );
			$email     = $user_info ? $user_info->user_email : null;
		}

		if ( 'donor' === $subject_type ) {
			$donor_info = DonorsModule::get( $subject_id );
			$email      = $donor_info ? $donor_info->email : null;
		}

		// Add handling for other subject types (e.g. donors) as needed.
		return apply_filters( 'ambh_get_consent_subject_email', $email, $subject_type, $subject_id );
	}

	/**
	 * Revoke all active consent records when a donor is anonymized.
	 *
	 * Hooked into `ambh_donor_anonymized`. The Donors module fires this action
	 * after overwriting PII, so consent records must be revoked at this point
	 * to comply with GDPR erasure.
	 *
	 * @param int $donor_id The anonymized donor ID.
	 * @return void
	 */
	public static function handle_donor_anonymized( int $donor_id ): void {
		ConsentManager::withdraw_all_for_subject( 'donor', $donor_id, 'system' );
	}
}
