<?php

declare(strict_types=1);

namespace App\Support\Baselines\Compare;

use InvalidArgumentException;

final class CompareOrchestrationContext
{
    /**
     * @param  array<string, mixed>  $normalizedScope
     * @param  array<string, mixed>  $coverageContext
     * @param  array<string, mixed>  $launchContext
     */
    public function __construct(
        public readonly int $workspaceId,
        public readonly int $tenantId,
        public readonly int $baselineProfileId,
        public readonly int $baselineSnapshotId,
        public readonly int $operationRunId,
        public readonly array $normalizedScope,
        public readonly CompareStrategySelection $strategySelection,
        public readonly array $coverageContext = [],
        public readonly array $launchContext = [],
    ) {
        if ($this->workspaceId <= 0 || $this->tenantId <= 0 || $this->baselineProfileId <= 0 || $this->baselineSnapshotId <= 0 || $this->operationRunId <= 0) {
            throw new InvalidArgumentException('Compare orchestration contexts require positive workspace, tenant, profile, snapshot, and operation run identifiers.');
        }
    }

    public function strategyKey(): CompareStrategyKey
    {
        if (! $this->strategySelection->strategyKey instanceof CompareStrategyKey) {
            throw new InvalidArgumentException('Compare orchestration context requires a supported strategy selection before execution.');
        }

        return $this->strategySelection->strategyKey;
    }

    public function inventorySyncRunId(): ?int
    {
        $value = $this->coverageContext['inventory_sync_run_id'] ?? $this->launchContext['inventory_sync_run_id'] ?? null;

        return is_numeric($value) ? (int) $value : null;
    }

    /**
     * @return array{
     *   workspace_id: int,
     *   managed_environment_id: int,
     *   baseline_profile_id: int,
     *   baseline_snapshot_id: int,
     *   operation_run_id: int,
     *   normalized_scope: array<string, mixed>,
     *   strategy_selection: array{
     *     selection_state: string,
     *     strategy_key: ?string,
     *     matched_scope_entries: list<array<string, mixed>>,
     *     rejected_scope_entries: list<array<string, mixed>>,
     *     operator_reason: string,
     *     diagnostics: array<string, mixed>
     *   },
     *   coverage_context: array<string, mixed>,
     *   launch_context: array<string, mixed>
     * }
     */
    public function toArray(): array
    {
        return [
            'workspace_id' => $this->workspaceId,
            'managed_environment_id' => $this->tenantId,
            'baseline_profile_id' => $this->baselineProfileId,
            'baseline_snapshot_id' => $this->baselineSnapshotId,
            'operation_run_id' => $this->operationRunId,
            'normalized_scope' => $this->normalizedScope,
            'strategy_selection' => $this->strategySelection->toArray(),
            'coverage_context' => $this->coverageContext,
            'launch_context' => $this->launchContext,
        ];
    }
}