<?php
/**
 * PS_Label_Identity — single source of truth dla installation_id.
 *
 * Polityka SPEC/05_DATA_MODEL.md: 1 klucz `parcselect_installation_id` (UUID v4).
 * Aktualnie 3 kolidujace klucze:
 *   - parcselect_installation_id (canonical wg Parcselect_Label_Installation::current)
 *   - parcselect_label_installation_id(legacy)
 *   - parcselect_label_oracle_installation_id(NIE ISTNIEJE)
 *
 * PS_Label_Identity unifies READ — wszystkie miejsca w kodzie powinny uzywac ::current()
 * zamiast bezposredniego get_option(). Migration: kopiuje legacy do canonical jesli
 * canonical pusty (idempotent, one-shot).
 *
 * Polityka backward compat: legacy keys NIE sa usuwane, tylko unified READ.
 *
 * @package ParcelSelectorFree
 */

defined( 'ABSPATH' ) || exit;

final class Parcselect_Label_Identity {

	const CANONICAL_OPTION = 'parcselect_installation_id';

	/** Legacy keys checked w priority order. */
	const LEGACY_OPTIONS = array(
		'parcselect_label_installation_id',
		'parcselect_installation_id',
		'parcselect_label_oracle_installation_id',
	);

	public static function init() {
		// Migration on init — idempotent.
		add_action( 'plugins_loaded', array( __CLASS__, 'migrate_to_canonical' ), 100 );
	}

	/**
	 * Single source of truth — zawsze zwroc canonical installation_id.
	 *
	 * @return string Empty jesli plugin nie enrolled.
	 */
	public static function current() {
		$canonical = (string) get_option( self::CANONICAL_OPTION, '' );
		if ( '' !== $canonical ) {
			return $canonical;
		}
		// Fallback: pierwszy non-empty z legacy keys.
		foreach ( self::LEGACY_OPTIONS as $opt ) {
			$v = (string) get_option( $opt, '' );
			if ( '' !== $v ) {
				return $v;
			}
		}
		return '';
	}

	/**
	 * Alias dla current() — semantyczny clarity.
	 */
	public static function canonical() {
		return self::current();
	}

	/**
	 * Migration: jesli canonical pusty a legacy ma wartosc, skopiuj do canonical.
	 * Idempotent — pomija jesli canonical juz ustawiony.
	 *
	 * @return bool true if migration ran (legacy → canonical), false otherwise.
	 */
	public static function migrate_to_canonical() {
		$canonical = (string) get_option( self::CANONICAL_OPTION, '' );
		if ( '' !== $canonical ) {
			return false; // Already set.
		}

		foreach ( self::LEGACY_OPTIONS as $opt ) {
			$v = (string) get_option( $opt, '' );
			if ( '' !== $v ) {
				update_option( self::CANONICAL_OPTION, $v, false );
				if ( class_exists( 'Parcselect_Label_Debug' ) ) {
					Parcselect_Label_Debug::info( 0, 'identity.migrated', array(
						'from'    => $opt,
						'to'      => self::CANONICAL_OPTION,
						'value12' => substr( $v, 0, 12 ) . '...',
					) );
				}
				return true;
			}
		}
		return false;
	}

	/**
	 * Diagnostyka: zwraca wszystkie znane klucze i ich wartosci (do debug).
	 *
	 * @return array
	 */
	public static function diagnostic() {
		$out = array(
			'canonical_key'   => self::CANONICAL_OPTION,
			'canonical_value' => get_option( self::CANONICAL_OPTION, '__EMPTY__' ),
			'legacy'          => array(),
		);
		foreach ( self::LEGACY_OPTIONS as $opt ) {
			$out['legacy'][ $opt ] = get_option( $opt, '__EMPTY__' );
		}
		return $out;
	}
}
