<?php

declare(strict_types=1);

namespace App\Services\Intune;

use App\Models\ManagedEnvironment;
use App\Services\Audit\AuditRecorder;
use App\Support\Audit\AuditActionId;
use App\Support\Audit\AuditActorSnapshot;
use App\Support\Audit\AuditActorType;
use App\Support\Audit\AuditTargetSnapshot;
use Carbon\CarbonImmutable;
use InvalidArgumentException;

class AuditLogger
{
    public function __construct(
        private readonly AuditRecorder $auditRecorder,
    ) {}

    public function log(
        ManagedEnvironment $tenant,
        string|AuditActionId $action,
        array $context = [],
        ?int $actorId = null,
        ?string $actorEmail = null,
        ?string $actorName = null,
        string $status = 'success',
        ?string $resourceType = null,
        ?string $resourceId = null,
        ?AuditActorType $actorType = null,
        ?string $targetLabel = null,
        ?string $summary = null,
        ?int $operationRunId = null,
    ): \App\Models\AuditLog {
        $workspaceId = is_numeric($tenant->workspace_id) ? (int) $tenant->workspace_id : null;

        $metadata = is_array($context['metadata'] ?? null) ? $context['metadata'] : [];

        if ($actorType instanceof AuditActorType) {
            $metadata['_actor_type'] = $actorType->value;
        }

        $context['metadata'] = $metadata;

        if ($workspaceId === null) {
            throw new InvalidArgumentException('ManagedEnvironment-scoped audit events require tenant workspace_id.');
        }

        return $this->auditRecorder->record(
            action: $action,
            context: $context,
            workspace: $tenant->workspace,
            tenant: $tenant,
            actor: AuditActorSnapshot::fromLegacy(
                type: $actorType ?? AuditActorType::infer($action instanceof AuditActionId ? $action->value : $action, $actorId, $actorEmail, $actorName, $context),
                id: $actorId,
                email: $actorEmail,
                label: $actorName,
            ),
            target: new AuditTargetSnapshot(
                type: $resourceType,
                id: $resourceId,
                label: $targetLabel,
            ),
            outcome: $status,
            recordedAt: CarbonImmutable::now(),
            summary: $summary ?? AuditActionId::summaryFor(
                action: $action,
                targetLabel: $targetLabel,
                targetType: $resourceType,
                context: $metadata,
            ),
            operationRunId: $operationRunId,
        );
    }
}
