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

namespace Hafenstudios\Kurato\Cockpit;

use Hafenstudios\Core\Support\Secrets;

defined( 'ABSPATH' ) || exit;

/**
 * Kopplungs-Zustand des Connectors. Haelt site_id, den verschluesselten
 * site_key (ausschliesslich ueber Core\Support\Secrets), key_version und Plan.
 *
 * `is_paired()` ist der zentrale Schalter des Null-Risiko-Defaults: erst wenn
 * hier ein site_key liegt, registriert der Connector Auth-Hooks und CORS.
 */
class Config {

	public const OPTION = 'hs_kurato_cockpit';

	public const SERVICE_DEFAULT = 'https://api.kurato.cloud';
	public const ORIGIN_DEFAULT  = 'https://app.kurato.cloud';

	/**
	 * Rohe Kopplungsdaten (immer ein Array).
	 *
	 * @return array<string, mixed>
	 */
	private function data(): array {
		$data = get_option( self::OPTION, array() );
		return is_array( $data ) ? $data : array();
	}

	/**
	 * Ist die Site gekoppelt (site_id und entschluesselbarer site_key vorhanden)?
	 *
	 * @return bool
	 */
	public function is_paired(): bool {
		return '' !== $this->site_id() && '' !== $this->site_key();
	}

	/**
	 * Site-ID des Dienstes.
	 *
	 * @return string
	 */
	public function site_id(): string {
		return (string) ( $this->data()['site_id'] ?? '' );
	}

	/**
	 * Aktuelle Schluessel-Version.
	 *
	 * @return int
	 */
	public function key_version(): int {
		return (int) ( $this->data()['key_version'] ?? 1 );
	}

	/**
	 * Gemeldeter Plan (free|pro).
	 *
	 * @return string
	 */
	public function plan(): string {
		return (string) ( $this->data()['plan'] ?? 'free' );
	}

	/**
	 * Zeitpunkt der Kopplung (Unix).
	 *
	 * @return int
	 */
	public function paired_at(): int {
		return (int) ( $this->data()['paired_at'] ?? 0 );
	}

	/**
	 * Entschluesselter site_key (leer, wenn keiner gespeichert ist).
	 *
	 * @return string
	 */
	public function site_key(): string {
		$stored = (string) ( $this->data()['site_key'] ?? '' );
		return '' === $stored ? '' : Secrets::decrypt( $stored );
	}

	/**
	 * Speichert das Ergebnis eines Pairings. Der site_key wird sofort
	 * verschluesselt (Secrets/libsodium) und nie im Klartext in der DB gehalten.
	 *
	 * @param array<string, mixed> $pairing site_id, site_key, key_version, plan.
	 * @return void
	 */
	public function save_pairing( array $pairing ): void {
		update_option(
			self::OPTION,
			array(
				'site_id'     => (string) ( $pairing['site_id'] ?? '' ),
				'site_key'    => Secrets::encrypt( (string) ( $pairing['site_key'] ?? '' ) ),
				'key_version' => (int) ( $pairing['key_version'] ?? 1 ),
				'plan'        => (string) ( $pairing['plan'] ?? 'free' ),
				'paired_at'   => time(),
			)
		);
	}

	/**
	 * Trennt die Kopplung: loescht site_key und den ganzen Zustand. Damit
	 * deaktiviert der Connector beim naechsten Laden alle Auth-Hooks und CORS.
	 *
	 * @return void
	 */
	public function clear(): void {
		delete_option( self::OPTION );
	}

	/**
	 * Konfigurierte App-Origin fuer CORS und die wp-admin-Sperre.
	 *
	 * @return string
	 */
	public function origin(): string {
		/**
		 * Filtert die erlaubte Cockpit-App-Origin (fuer Staging).
		 *
		 * @param string $origin Default https://app.kurato.cloud.
		 */
		$origin = apply_filters( 'kurato_cockpit_origin', self::ORIGIN_DEFAULT );
		return ( is_string( $origin ) && '' !== $origin ) ? $origin : self::ORIGIN_DEFAULT;
	}

	/**
	 * Basis-URL des Cockpit-Dienstes.
	 *
	 * @return string
	 */
	public function service_url(): string {
		/**
		 * Filtert die Basis-URL des Cockpit-Dienstes.
		 *
		 * @param string $url Default https://api.kurato.cloud.
		 */
		$url = apply_filters( 'kurato_cockpit_service_url', self::SERVICE_DEFAULT );
		return ( is_string( $url ) && '' !== $url ) ? rtrim( $url, '/' ) : self::SERVICE_DEFAULT;
	}
}
