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

namespace Hafenstudios\Leadlotse\Support;

use Hafenstudios\Core\Core;
use Hafenstudios\Core\Licensing\ProGate;

defined( 'ABSPATH' ) || exit;

/**
 * Der Free/Pro-Schnitt von Leadlotse (L-P1, FREEMIUS-LAUNCH.md Abschnitt 2).
 *
 * Pro sind genau drei Funktionen: Veranstaltungs-Anmeldung mit Ticket und
 * QR-Check-in (L-R1), WhatsApp-Leads (L-W1) und die Ausfuellhilfe Google/Apple
 * (L-A1). Alles andere bleibt frei.
 *
 * BESTANDSSCHUTZ ist die Leitplanke: der Gate greift ausschliesslich beim
 * KONFIGURIEREN, also wenn eine Definition eine Pro-Funktion NEU einschaltet.
 * Der Betrieb bestehender Formulare wird nie gegated - Frontend-Renderer,
 * Ticket-Mails, QR-Pruefung, Check-in-Seite und Teilnehmerliste kennen diese
 * Klasse bewusst nicht. Grund: auf echten Sites laufen damit gerade
 * Veranstaltungs-Anmeldungen; ein Ticket darf nicht mitten in der
 * Veranstaltung ungueltig werden.
 *
 * Der Vergleich laeuft ueber used(): Pro-Funktion ist NEU eingeschaltet, wenn
 * used() sie in der neuen Definition sieht und in der bisherigen nicht. Beim
 * Anlegen ist die "bisherige" Definition ein leeres Array - und weil die
 * Ausfuellhilfe im Schema den Default AN hat, blockiert das Anlegen eines
 * gewoehnlichen Formulars nie (LP1-3).
 */
final class ProFeatures {

	public const SLUG = 'leadlotse';

	/**
	 * Karten-ID des Kauf-Moments. Liegt im Hans-Speicher (Nutzer-Meta), damit
	 * ein Wegklicken dauerhaft und ueberall gilt.
	 */
	public const CARD_ID = 'leadlotse_pro_upsell';

	/**
	 * Ist Leadlotse Pro freigeschaltet?
	 *
	 * @return bool
	 */
	public static function enabled(): bool {
		return ProGate::enabled( self::SLUG );
	}

	/**
	 * Ziel des Kauf-Knopfs.
	 *
	 * @return string
	 */
	public static function upgrade_url(): string {
		return ProGate::upgrade_url( self::SLUG );
	}

	/**
	 * Welche Pro-Funktionen nutzt diese Formular-Definition?
	 *
	 * @param array<string, mixed> $definition Formular-Definition (auch leer).
	 * @return array{event:bool,whatsapp:bool,identity:bool}
	 */
	public static function used( array $definition ): array {
		$settings = is_array( $definition['settings'] ?? null ) ? $definition['settings'] : array();
		$event    = is_array( $settings['event'] ?? null ) ? $settings['event'] : array();
		$whatsapp = is_array( $settings['whatsapp'] ?? null ) ? $settings['whatsapp'] : array();
		$identity = is_array( $settings['identity'] ?? null ) ? $settings['identity'] : array();

		// Das Opt-in am Telefonfeld gehoert zu L-W1 und funktioniert unabhaengig
		// vom Click-to-Chat-Block - beide zaehlen als "WhatsApp in Benutzung".
		$optin = false;
		foreach ( (array) ( $definition['fields'] ?? array() ) as $field ) {
			if ( is_array( $field ) && ! empty( $field['whatsapp_optin'] ) ) {
				$optin = true;
				break;
			}
		}

		return array(
			'event'    => ! empty( $event['enabled'] ),
			'whatsapp' => ! empty( $whatsapp['enabled'] ) || $optin,
			// Default AN wie in DefinitionSchema: ein fehlender Schluessel heisst an.
			'identity' => ! isset( $identity['enabled'] ) || ! empty( $identity['enabled'] ),
		);
	}

	/**
	 * Verbindliche Pruefung beim Speichern einer Definition (REST und Admin).
	 *
	 * @param array<string, mixed>      $definition Neue, bereits bereinigte Definition.
	 * @param array<string, mixed>|null $previous   Bisherige Definition (null = neues Formular).
	 * @return \WP_Error|null Fehler, wenn eine Pro-Funktion neu eingeschaltet wird.
	 */
	public static function check_definition( array $definition, ?array $previous ): ?\WP_Error {
		if ( self::enabled() ) {
			return null;
		}

		$now    = self::used( $definition );
		$before = self::used( is_array( $previous ) ? $previous : array() );

		foreach ( $now as $feature => $is_on ) {
			if ( $is_on && ! $before[ $feature ] ) {
				return new \WP_Error(
					'leadlotse_pro_required',
					self::message( (string) $feature ),
					array(
						'status'  => 403,
						'feature' => $feature,
					)
				);
			}
		}

		return null;
	}

	/**
	 * Fehlermeldung nach Hausmuster "Ursache + naechster Schritt", immer mit dem
	 * Bestandsschutz-Versprechen.
	 *
	 * @param string $feature event, whatsapp oder identity.
	 * @return string
	 */
	public static function message( string $feature ): string {
		if ( 'event' === $feature ) {
			return __( 'Veranstaltungs-Anmeldungen gehoeren zu Leadlotse Pro. Bestehende Anmeldeformulare laufen unveraendert weiter; fuer ein neues Formular brauchen Sie eine Pro-Lizenz.', 'leadlotse' );
		}
		if ( 'whatsapp' === $feature ) {
			return __( 'WhatsApp-Leads gehoeren zu Leadlotse Pro. Formulare mit WhatsApp laufen unveraendert weiter; zum Einschalten an einem weiteren Formular brauchen Sie eine Pro-Lizenz.', 'leadlotse' );
		}
		return __( 'Die Ausfuellhilfe mit Google und Apple gehoert zu Leadlotse Pro. Bestehende Formulare und eingerichtete Anbieter laufen unveraendert weiter; zum Einschalten brauchen Sie eine Pro-Lizenz.', 'leadlotse' );
	}

	/**
	 * Der Kauf-Moment: ein Titel, ein Satz Nutzen, der Preis, ein Knopf.
	 * Kein Modal, kein Countdown, kein zweiter Nag (UX-KONZEPT-COCKPIT Kap. 6).
	 *
	 * @return array{id:string,title:string,text:string,price:string,button:string,url:string}
	 */
	public static function card(): array {
		return array(
			'id'     => self::CARD_ID,
			'title'  => __( 'Anmeldungen, WhatsApp und Ausfuellhilfe', 'leadlotse' ),
			'text'   => __( 'Mit Pro nehmen Sie Anmeldungen mit Ticket und QR-Check-in auf, antworten per WhatsApp und lassen Formulare per Google oder Apple ausfuellen.', 'leadlotse' ),
			'price'  => __( 'Leadlotse Pro, 39 EUR im Jahr.', 'leadlotse' ),
			'button' => __( 'Leadlotse Pro ansehen', 'leadlotse' ),
			'url'    => self::upgrade_url(),
		);
	}

	/**
	 * Der Kauf-Moment fuer diesen Nutzer, oder null: mit Lizenz gibt es ihn
	 * nicht, und einmal weggeklickt kommt er nie wieder (Hans-Speicher in der
	 * Nutzer-Meta, dieselbe Ablage wie alle Hans-Karten).
	 *
	 * @return array<string, mixed>|null
	 */
	public static function card_for_user(): ?array {
		if ( self::enabled() || Core::instance()->hans()->is_dismissed( self::CARD_ID ) ) {
			return null;
		}
		return self::card();
	}

	/**
	 * Schloss-Schild fuer gesperrte, aber sichtbare Flaechen. Farbe ist nie der
	 * einzige Traeger: das Schild traegt den Text "Pro" (UX-KONZEPT 7).
	 *
	 * @return string HTML.
	 */
	public static function badge(): string {
		return '<span class="hs-shield hs-shield--grey hs-shield--locked"><span class="dashicons dashicons-lock" aria-hidden="true"></span>'
			. esc_html__( 'Pro', 'leadlotse' ) . '</span>';
	}
}
