<?php
declare(strict_types=1);

namespace App\Modules\Sms;

use App\Core\Http\Request;
use App\Core\Http\Response;
use Throwable;

final class SmsplanetWebhookController
{
    public function __construct(private readonly SmsConversationService $service)
    {
    }

    public function inbound(Request $request): Response
    {
        $payload = $this->payloadFromRequest($request);

        try {
            $this->service->receiveSmsplanetWebhook($payload);

            return Response::html('OK');
        } catch (Throwable $exception) {
            return Response::json([
                'ok' => false,
                'message' => $exception->getMessage(),
            ], 422);
        }
    }

    /**
     * @return array<string, mixed>
     */
    private function payloadFromRequest(Request $request): array
    {
        $payload = $request->all();
        $message = $this->decodeMessagePayload($payload['message'] ?? null);
        if ($message !== null) {
            $payload = array_merge($payload, $message);
        }

        $rawBody = file_get_contents('php://input');
        if (is_string($rawBody) && trim($rawBody) !== '') {
            $decoded = json_decode($rawBody, true);
            if (is_array($decoded)) {
                $payload = array_merge($payload, $decoded);
            }
        }

        if (is_string($rawBody) && trim($rawBody) !== '') {
            $payload['_raw_body'] = $rawBody;
        }

        return $payload;
    }

    /**
     * @return array<string, mixed>|null
     */
    private function decodeMessagePayload(mixed $message): ?array
    {
        if (!is_string($message) || trim($message) === '') {
            return null;
        }

        $decoded = json_decode($message, true);

        return is_array($decoded) ? $decoded : null;
    }
}
