<?php
namespace SabaiApps\Framework\User;

/**
 * AbstractIdentity class for representing user identities.
 * Provides methods for accessing and managing identity data, serialization, and checking anonymity.
 */
abstract class AbstractIdentity implements \Serializable {

	/**
	 * @var array Data associated with the identity.
	 */
	protected $_data;

	/**
	 * Constructor.
	 *
	 * @param array $data Data associated with the identity.
	 */
	public function __construct( array $data = array() ) {
		$this->_data = $data;
	}

	/**
	 * Serializes the identity data.
	 *
	 * @return string Serialized data.
	 */
	public function serialize() {
		return serialize( $this->_data );
	}

	/**
	 * Unserializes the identity data.
	 *
	 * @param string $serialized Serialized data.
	 */
	public function unserialize( $serialized ) {
		$this->_data = unserialize( $serialized );
	}

	/**
	 * Serializes the identity data (PHP 7.4+).
	 *
	 * @return array Data to serialize.
	 */
	public function __serialize() {
		return $this->_data;
	}

	/**
	 * Unserializes the identity data (PHP 7.4+).
	 *
	 * @param array $serialized Serialized data.
	 */
	public function __unserialize( $serialized ) {
		$this->_data = $serialized;
	}

	/**
	 * Returns the data associated with the identity.
	 *
	 * @return array Identity data.
	 */
	public function getData() {
		return $this->_data;
	}

	/**
	 * Gets a specific value from the identity data.
	 *
	 * @param string $key Key of the data to retrieve.
	 * @return mixed Value associated with the key, or null if not found.
	 */
	public function get( $key ) {
		return array_key_exists( $key, $this->_data ) ? $this->_data[ $key ] : null;
	}

	/**
	 * Checks if the identity is anonymous.
	 *
	 * @return bool True if anonymous, false otherwise.
	 */
	abstract public function isAnonymous();

	/**
	 * Magic method for accessing identity data.
	 *
	 * @param string $key Key of the data to retrieve.
	 * @return mixed Value associated with the key, or null if not found.
	 */
	public function __get( $key ) {
		return $this->get( $key );
	}

	/**
	 * Magic method for setting identity data.
	 *
	 * @param string $name Key of the data to set.
	 * @param mixed  $value Value to set.
	 */
	public function __set( $name, $value ) {
		if ( ! array_key_exists( $name, $this->_data ) ) {
			return;
		}

		$this->_data[ $name ] = $value;
	}

	/**
	 * Magic method for checking if a key exists and is set in the identity data.
	 *
	 * @param string $key Key to check.
	 * @return bool True if the key exists and is set, false otherwise.
	 */
	public function __isset( $key ) {
		return array_key_exists( $key, $this->_data ) && isset( $this->_data[ $key ] );
	}
}
