<?php

namespace App\Modules\AntiTheft\Application;

use App\Modules\AntiTheft\Domain\SecuritySignal;
use App\Modules\AntiTheft\Domain\TheftRuleEngine;
use InvalidArgumentException;

final readonly class ProcessSecuritySignal
{
    public function __construct(
        private TheftRuleEngine $engine,
        private RuleProvider $rules,
        private RuleTriggerStore $triggers,
        private IncidentPublisher $incidents,
        private SignalReceiptStore $receipts,
    ) {}

    public function handle(SecuritySignal $signal, string $idempotencyKey): SignalProcessingResult
    {
        if (! preg_match('/^[A-Za-z0-9._:-]{16,128}$/', $idempotencyKey)) {
            throw new InvalidArgumentException('A valid idempotency key is required.');
        }

        if ($this->receipts->hasProcessed($idempotencyKey)) {
            return SignalProcessingResult::duplicate();
        }

        $evaluation = $this->engine->evaluate(
            $signal,
            $this->rules->forDevice($signal->deviceUuid),
            $this->triggers->lastTriggeredAt($signal->deviceUuid),
        );

        if ($evaluation->triggered()) {
            $this->triggers->record($signal, $evaluation->matchedRules);
            $this->incidents->publish($evaluation, $idempotencyKey);
        }

        $this->receipts->markProcessed($idempotencyKey);

        return SignalProcessingResult::processed($evaluation);
    }
}
