<?php
/**
 * affilun Cloud license verification result.
 *
 * @package Affilun\Application\Cloud
 */

declare(strict_types=1);

namespace Affilun\Application\Cloud;

/**
 * Immutable result from affilun Cloud license verification.
 */
final class CloudLicenseVerificationResult {

	/**
	 * @param bool               $valid        Whether the license is valid.
	 * @param string             $plan         Plan token/label.
	 * @param array<string,bool> $featureFlags Feature flags.
	 * @param int|null           $quotaUsed    Used quota.
	 * @param int|null           $quotaLimit   Quota limit.
	 * @param string|null        $message      Human-readable message.
	 */
	public function __construct(
		private bool $valid,
		private string $plan,
		private array $featureFlags,
		private ?int $quotaUsed,
		private ?int $quotaLimit,
		private ?string $message
	) {}

	/**
	 * Build from response array.
	 *
	 * @param array<string,mixed> $data Response data.
	 */
	public static function fromArray( array $data ): self {
		$flags = array();
		if ( isset( $data['feature_flags'] ) && is_array( $data['feature_flags'] ) ) {
			foreach ( $data['feature_flags'] as $key => $value ) {
				if ( is_string( $key ) ) {
					$flags[ $key ] = (bool) $value;
				}
			}
		}

		return new self(
			(bool) ( $data['valid'] ?? false ),
			is_scalar( $data['plan'] ?? null ) ? (string) $data['plan'] : '',
			$flags,
			isset( $data['quota_used'] ) && is_numeric( $data['quota_used'] ) ? (int) $data['quota_used'] : null,
			isset( $data['quota_limit'] ) && is_numeric( $data['quota_limit'] ) ? (int) $data['quota_limit'] : null,
			is_scalar( $data['message'] ?? null ) ? (string) $data['message'] : null
		);
	}

	/**
	 * Whether the license is valid.
	 */
	public function valid(): bool {
		return $this->valid;
	}

	/**
	 * Plan token/label.
	 */
	public function plan(): string {
		return $this->plan;
	}

	/**
	 * @return array<string,bool>
	 */
	public function featureFlags(): array {
		return $this->featureFlags;
	}

	/**
	 * Used quota.
	 */
	public function quotaUsed(): ?int {
		return $this->quotaUsed;
	}

	/**
	 * Quota limit.
	 */
	public function quotaLimit(): ?int {
		return $this->quotaLimit;
	}

	/**
	 * Human-readable message.
	 */
	public function message(): ?string {
		return $this->message;
	}
}
