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

namespace Hafenstudios\Kurato\Intake;

use Hafenstudios\Core\Events\EventBus;
use Hafenstudios\Kurato\Db\ContactRepository;
use Hafenstudios\Kurato\Db\StageRepository;

defined( 'ABSPATH' ) || exit;

/**
 * Uebernahme von Leadlotse-Anfragen als Kurato-Kontakte (BAUPLAN Abschnitt 7).
 *
 * Lauscht auf das Flotten-Event hafenstudios/lead_created. Jede Anfrage wird zu
 * einem Kontakt: neue E-Mail legt einen Kontakt in der ersten Pipeline-Stufe an,
 * eine bekannte E-Mail aktualisiert den bestehenden Kontakt (Dedup, kein zweiter
 * Kontaktspeicher). Quelle und UTM-Daten wandern mit, damit spaeter sichtbar ist,
 * ueber welchen Kanal der Kontakt kam.
 *
 * Der Intake laeuft nur, wenn der Betreiber die Uebernahme aktiviert hat
 * (Einstellung intake.from_leadlotse, Default an). So bleibt Leadlotse ohne
 * Kurato voll nutzbar und umgekehrt.
 */
final class LeadIntake {

	private ContactRepository $contacts;

	private StageRepository $stages;

	/**
	 * @param ContactRepository $contacts Kontakt-Repository.
	 * @param StageRepository   $stages   Stufen-Repository.
	 */
	public function __construct( ContactRepository $contacts, StageRepository $stages ) {
		$this->contacts = $contacts;
		$this->stages   = $stages;
	}

	/**
	 * Registriert den Event-Listener.
	 *
	 * @return void
	 */
	public function register(): void {
		EventBus::on( 'lead_created', array( $this, 'on_lead_created' ), 10, 1 );
	}

	/**
	 * Verarbeitet eine eingegangene Anfrage.
	 *
	 * @param array<string, mixed> $lead Event-Payload von Leadlotse.
	 * @return void
	 */
	public function on_lead_created( $lead ): void {
		if ( ! is_array( $lead ) ) {
			return;
		}

		$email = sanitize_email( (string) ( $lead['email'] ?? '' ) );
		if ( '' === $email ) {
			// Ohne E-Mail kein sinnvoller Kontakt (keine Dedup-Basis).
			return;
		}

		$source  = is_array( $lead['source'] ?? null ) ? $lead['source'] : array();
		$contact = is_array( $lead['contact'] ?? null ) ? $lead['contact'] : array();

		$existing   = $this->contacts->find_by_email( $email );
		$contact_id = 0;
		$created    = false;

		if ( null === $existing ) {
			$stage_id   = $this->stages->first_stage_id();
			$contact_id = $this->contacts->insert(
				array(
					'email'        => $email,
					'display_name' => (string) ( $contact['display_name'] ?? '' ),
					'first_name'   => (string) ( $contact['first_name'] ?? '' ),
					'last_name'    => (string) ( $contact['last_name'] ?? '' ),
					'phone'        => (string) ( $contact['phone'] ?? '' ),
					'stage_id'     => $stage_id > 0 ? $stage_id : null,
					'source'       => (string) ( $lead['source_plugin'] ?? 'leadlotse' ),
					'utm_source'   => (string) ( $source['utm_source'] ?? '' ),
					'utm_medium'   => (string) ( $source['utm_medium'] ?? '' ),
					'utm_campaign' => (string) ( $source['utm_campaign'] ?? '' ),
					'consent_id'   => absint( $lead['consent_id'] ?? 0 ),
				)
			);
			if ( $contact_id > 0 ) {
				$created = true;
			} else {
				// Insert scheiterte (UNIQUE-Race: paralleler Submit derselben
				// E-Mail). Den nun vorhandenen Kontakt als bestehend behandeln.
				$existing = $this->contacts->find_by_email( $email );
			}
		}

		if ( null !== $existing ) {
			$contact_id = (int) $existing['id'];
			// Nur leere Felder auffuellen, bestehende Daten nicht ueberschreiben.
			$patch = array();
			foreach ( array( 'display_name', 'first_name', 'last_name', 'phone' ) as $key ) {
				if ( '' === (string) ( $existing[ $key ] ?? '' ) && '' !== (string) ( $contact[ $key ] ?? '' ) ) {
					$patch[ $key ] = (string) $contact[ $key ];
				}
			}
			foreach ( array( 'utm_source', 'utm_medium', 'utm_campaign' ) as $key ) {
				if ( '' === (string) ( $existing[ $key ] ?? '' ) && '' !== (string) ( $source[ $key ] ?? '' ) ) {
					$patch[ $key ] = (string) $source[ $key ];
				}
			}
			if ( array() !== $patch ) {
				$this->contacts->update( $contact_id, $patch );
			}
		}

		if ( $contact_id <= 0 ) {
			return;
		}

		/**
		 * Nach der Uebernahme: erlaubt weiteren Flotten-Komponenten, an den
		 * Kontakt anzuknuepfen (z.B. Tag vergeben, Sequenz starten).
		 *
		 * @param int                  $contact_id Kontakt-ID.
		 * @param array<string, mixed> $lead       Ursprungs-Payload.
		 * @param bool                 $created    Wurde ein neuer Kontakt angelegt?
		 */
		EventBus::emit( 'contact_intake', $contact_id, $lead, $created );
	}
}
