<?php

declare(strict_types=1);

namespace App\Support\Audit;

enum AuditActorType: string
{
    case Human = 'human';
    case System = 'system';
    case Scheduled = 'scheduled';
    case Integration = 'integration';
    case Platform = 'platform';

    public static function normalize(mixed $value): self
    {
        $normalized = is_string($value) ? strtolower(trim($value)) : null;

        return match ($normalized) {
            self::Human->value => self::Human,
            self::Scheduled->value, 'scheduler', 'cron' => self::Scheduled,
            self::Integration->value => self::Integration,
            self::Platform->value => self::Platform,
            default => self::System,
        };
    }

    public static function infer(
        ?string $action,
        ?int $actorId,
        ?string $actorEmail,
        ?string $actorName,
        array $context = [],
    ): self {
        if ($actorId !== null || filled($actorEmail) || filled($actorName)) {
            return self::Human;
        }

        $declared = $context['_actor_type'] ?? null;

        if (is_string($declared) && trim($declared) !== '') {
            return self::normalize($declared);
        }

        $normalizedAction = strtolower(trim((string) $action));

        if (str_starts_with($normalizedAction, 'platform.')) {
            return self::Platform;
        }

        if (str_contains($normalizedAction, 'schedule') || array_key_exists('backup_schedule_id', $context)) {
            return self::Scheduled;
        }

        return self::System;
    }

    public function label(): string
    {
        return match ($this) {
            self::Human => 'Human',
            self::System => 'System',
            self::Scheduled => 'Scheduled job',
            self::Integration => 'Integration',
            self::Platform => 'Platform',
        };
    }
}
