<?php

declare(strict_types=1);

namespace App\Support\Audit;

use App\Models\PlatformUser;
use App\Models\User;

final readonly class AuditActorSnapshot
{
    public function __construct(
        public AuditActorType $type,
        public int|string|null $id = null,
        public ?string $label = null,
        public ?string $email = null,
    ) {}

    public static function human(User $user): self
    {
        return new self(
            type: AuditActorType::Human,
            id: (int) $user->getKey(),
            label: filled($user->name) ? (string) $user->name : (filled($user->email) ? (string) $user->email : null),
            email: filled($user->email) ? (string) $user->email : null,
        );
    }

    public static function platform(PlatformUser $user): self
    {
        return new self(
            type: AuditActorType::Platform,
            id: (int) $user->getKey(),
            label: filled($user->name) ? (string) $user->name : (filled($user->email) ? (string) $user->email : null),
            email: filled($user->email) ? (string) $user->email : null,
        );
    }

    public static function fromLegacy(
        AuditActorType $type,
        ?int $id = null,
        ?string $email = null,
        ?string $label = null,
    ): self {
        return new self(
            type: $type,
            id: $id,
            label: filled($label) ? trim((string) $label) : (filled($email) ? trim((string) $email) : null),
            email: filled($email) ? trim((string) $email) : null,
        );
    }

    public function labelOrFallback(): string
    {
        if (filled($this->label)) {
            return (string) $this->label;
        }

        if (filled($this->email)) {
            return (string) $this->email;
        }

        return $this->type->label();
    }

    /**
     * @return array{actor_type: string, actor_id: int|string|null, actor_label: string, actor_email: ?string}
     */
    public function toArray(): array
    {
        return [
            'actor_type' => $this->type->value,
            'actor_id' => $this->id,
            'actor_label' => $this->labelOrFallback(),
            'actor_email' => $this->email,
        ];
    }
}
