<?php

namespace App\Http\Controllers;

use App\Actions\Subscription\SubmitSubscriptionForm;
use App\Actions\Support\ApiConflictException;
use App\Actions\Support\ApiRateLimitedException;
use App\Actions\Support\ApiServiceUnavailableException;
use App\Actions\Support\ApiValidationException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Throwable;

/**
 * Port of the legacy `api/submit-subscription.php` endpoint.
 *
 * Kept thin: all validation, storage, and notification logic lives in
 * {@see SubmitSubscriptionForm}. This controller's only job is decoding the
 * raw JSON body and translating the action's outcome into the exact legacy
 * `{success, message, data}` envelope, with `data` always `null` on failure.
 */
class SubscriptionController extends Controller
{
    public function __construct(private readonly SubmitSubscriptionForm $submitSubscriptionForm)
    {
        //
    }

    public function __invoke(Request $request): JsonResponse
    {
        $decoded = json_decode($request->getContent(), true);

        if (! is_array($decoded)) {
            return $this->failure('Invalid JSON data', 400);
        }

        try {
            $result = $this->submitSubscriptionForm->handle($decoded, $request);

            return response()->json([
                'success' => true,
                'message' => 'Subscription created successfully!',
                'data' => $result,
            ]);
        } catch (ApiValidationException $e) {
            return $this->failure($e->getMessage(), 422);
        } catch (ApiRateLimitedException $e) {
            return $this->failure($e->getMessage(), 429);
        } catch (ApiConflictException $e) {
            return $this->failure($e->getMessage(), 409);
        } catch (ApiServiceUnavailableException $e) {
            return $this->failure($e->getMessage(), 503);
        } catch (Throwable $e) {
            Log::error('Subscription submission failed', ['exception' => $e->getMessage()]);

            return $this->failure('Failed to create subscription. Please try again.', 500);
        }
    }

    private function failure(string $message, int $status): JsonResponse
    {
        return response()->json([
            'success' => false,
            'message' => $message,
            'data' => null,
        ], $status);
    }
}
