<?php
/**
 * affilun Cloud link health result.
 *
 * @package Affilun\Application\Cloud
 */

declare(strict_types=1);

namespace Affilun\Application\Cloud;

/**
 * One link-health row returned by affilun Cloud.
 */
final class CloudLinkHealthResult {

	/**
	 * @param string              $url          Checked URL.
	 * @param string              $status       Status token.
	 * @param int                 $httpStatus   HTTP status, or 0.
	 * @param string              $message      Human-readable message.
	 * @param string              $checkedAtIso Checked timestamp.
	 * @param array<string,mixed> $context      Optional product/post context.
	 */
	public function __construct(
		private string $url,
		private string $status,
		private int $httpStatus,
		private string $message,
		private string $checkedAtIso,
		private array $context = array()
	) {}

	/**
	 * Build from response data.
	 *
	 * @param array<string,mixed> $data Response data.
	 */
	public static function fromArray( array $data ): self {
		$message = is_scalar( $data['message'] ?? null ) ? (string) $data['message'] : '';
		if ( $message === '' && is_scalar( $data['failure_class'] ?? null ) ) {
			$message = (string) $data['failure_class'];
		}

		return new self(
			is_scalar( $data['url'] ?? null ) ? (string) $data['url'] : '',
			is_scalar( $data['status'] ?? null ) ? (string) $data['status'] : 'unknown',
			isset( $data['http_status'] ) && is_numeric( $data['http_status'] ) ? (int) $data['http_status'] : 0,
			$message,
			is_scalar( $data['checked_at'] ?? null ) ? (string) $data['checked_at'] : '',
			self::contextFromArray( $data )
		);
	}

	/** Checked URL. */
	public function url(): string {
		return $this->url;
	}

	/** Status token. */
	public function status(): string {
		return $this->status;
	}

	/** HTTP status. */
	public function httpStatus(): int {
		return $this->httpStatus;
	}

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

	/** Checked timestamp. */
	public function checkedAtIso(): string {
		return $this->checkedAtIso;
	}

	/**
	 * Optional product/post context returned by Cloud job result endpoints.
	 *
	 * @return array<string,mixed>
	 */
	public function context(): array {
		return $this->context;
	}

	/**
	 * Extract context fields from a Cloud result row.
	 *
	 * @param array<string,mixed> $data Response data.
	 *
	 * @return array<string,mixed>
	 */
	private static function contextFromArray( array $data ): array {
		$context = array();
		foreach ( array( 'label', 'provider', 'provider_item_id' ) as $key ) {
			if ( is_scalar( $data[ $key ] ?? null ) ) {
				$value = trim( (string) $data[ $key ] );
				if ( $value !== '' ) {
					$context[ $key ] = $value;
				}
			}
		}
		if ( isset( $data['product_id'] ) && is_numeric( $data['product_id'] ) ) {
			$productId = (int) $data['product_id'];
			if ( $productId > 0 ) {
				$context['product_id'] = $productId;
			}
		}

		return $context;
	}
}
