<?php

namespace App\Modules\AntiTheft\Http;

use App\Http\Controllers\Controller;
use App\Modules\AntiTheft\Application\ProcessSecuritySignal;
use App\Modules\AntiTheft\Domain\SecuritySignal;
use App\Modules\AntiTheft\Domain\SignalType;
use DateTimeImmutable;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;

class SecuritySignalController extends Controller
{
    public function __invoke(SecuritySignalRequest $request, ProcessSecuritySignal $processor): JsonResponse
    {
        $idempotencyKey = $request->idempotencyKey();
        if (! preg_match('/^[A-Za-z0-9._:-]{16,128}$/', $idempotencyKey)) {
            return $this->response(false, 'A valid Idempotency-Key header is required.', null, 422, [
                'idempotency_key' => ['Use 16-128 letters, numbers, dots, underscores, colons or hyphens.'],
            ]);
        }

        $owned = DB::table('devices')->where('uuid', $request->string('device_uuid')->toString())
            ->where('user_id', $request->user()->getAuthIdentifier())->exists();
        if (! $owned) {
            return $this->response(false, 'You do not own this device.', null, 403, [
                'device_uuid' => ['Device ownership validation failed.'],
            ]);
        }

        $validated = $request->validated();
        $signal = new SecuritySignal(
            type: SignalType::from($validated['signal_type']),
            deviceUuid: $validated['device_uuid'],
            occurredAt: new DateTimeImmutable($validated['occurred_at']),
            confidence: (float) $validated['confidence'],
            magnitude: (float) ($validated['magnitude'] ?? 0.0),
            context: $validated['context'] ?? [],
        );
        $result = $processor->handle($signal, $idempotencyKey);
        $evaluation = $result->evaluation;

        return $this->response(true, $result->status === 'duplicate' ? 'Signal was already processed.' : 'Security signal accepted.', [
            'status' => $result->status,
            'incident_triggered' => $evaluation?->triggered() ?? false,
            'risk_score' => $evaluation?->riskScore,
            'risk_level' => $evaluation?->riskLevel->value,
            'matched_rules' => $evaluation === null ? [] : array_map(fn ($rule): string => $rule->code, $evaluation->matchedRules),
        ], $result->status === 'duplicate' ? 200 : 202);
    }

    private function response(bool $success, string $message, ?array $data, int $status, array $errors = []): JsonResponse
    {
        return response()->json([
            'success' => $success, 'message' => $message, 'data' => $data, 'errors' => $errors,
            'meta' => [], 'timestamp' => now()->toIso8601String(), 'version' => 'v1',
        ], $status);
    }
}
