<?php

declare(strict_types=1);

namespace App\Support\Baselines;

use App\Support\Inventory\InventoryPolicyTypeMeta;

final class BaselineSubjectKey
{
    public static function forPolicy(string $policyType, ?string $displayName = null, ?string $subjectExternalId = null): ?string
    {
        return match (InventoryPolicyTypeMeta::baselineCompareIdentityStrategy($policyType)) {
            'external_id' => self::fromExternalId($policyType, $subjectExternalId),
            default => self::fromDisplayName($displayName),
        };
    }

    public static function fromDisplayName(?string $displayName): ?string
    {
        if (! is_string($displayName)) {
            return null;
        }

        $trimmed = trim($displayName);

        if ($trimmed === '') {
            return null;
        }

        $collapsed = preg_replace('/\\s+/u', ' ', $trimmed);
        $collapsed = is_string($collapsed) ? $collapsed : $trimmed;

        $normalized = mb_strtolower($collapsed);
        $normalized = trim($normalized);

        return $normalized !== '' ? $normalized : null;
    }

    public static function fromExternalId(string $policyType, ?string $subjectExternalId): ?string
    {
        if (! is_string($subjectExternalId)) {
            return null;
        }

        $normalizedId = trim(mb_strtolower($subjectExternalId));

        if ($normalizedId === '') {
            return null;
        }

        return hash('sha256', trim(mb_strtolower($policyType)).'|'.$normalizedId);
    }

    public static function workspaceSafeSubjectExternalId(string $policyType, string $subjectKey): string
    {
        return hash('sha256', $policyType.'|'.$subjectKey);
    }

    public static function workspaceSafeSubjectExternalIdForPolicy(string $policyType, ?string $displayName = null, ?string $subjectExternalId = null): ?string
    {
        $identityInput = match (InventoryPolicyTypeMeta::baselineCompareIdentityStrategy($policyType)) {
            'external_id' => is_string($subjectExternalId) ? trim(mb_strtolower($subjectExternalId)) : null,
            default => self::fromDisplayName($displayName),
        };

        if (! is_string($identityInput) || $identityInput === '') {
            return null;
        }

        return self::workspaceSafeSubjectExternalId($policyType, $identityInput);
    }
}
