<?php

namespace App\Modules\Integrations\Platform\Controllers\V1;

use App\Modules\Integrations\Platform\Repositories\IntegrationWebhookRepository;
use App\Modules\Integrations\Platform\Requests\StoreIntegrationWebhookRequest;
use App\Modules\Integrations\Platform\Requests\ToggleWebhookEnabledRequest;
use App\Modules\Integrations\Platform\Requests\UpdateIntegrationWebhookRequest;
use App\Modules\Integrations\Platform\Resources\IntegrationWebhookResource;
use App\Modules\Integrations\Platform\Services\WebhookManagementService;
use App\Modules\Integrations\Platform\Support\ApiErrorResponse;
use App\Modules\Integrations\Platform\Support\ApiResponseFactory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

final class IntegrationWebhookController
{
    public function index(
        Request $request,
        IntegrationWebhookRepository $repo,
        ApiResponseFactory $responses,
    ): JsonResponse {
        $tid = $this->tenantId($request);
        $per = min(100, max(1, (int) $request->query('per_page', 25)));
        $p = $repo->paginateForTenant($tid, $per);
        $items = collect($p->items())->map(fn ($w) => (new IntegrationWebhookResource($w))->resolve())->all();

        return $responses->ok([
            'items' => $items,
            'pagination' => [
                'current_page' => $p->currentPage(),
                'last_page' => $p->lastPage(),
                'per_page' => $p->perPage(),
                'total' => $p->total(),
            ],
        ]);
    }

    public function store(
        Request $request,
        StoreIntegrationWebhookRequest $httpRequest,
        WebhookManagementService $svc,
        ApiResponseFactory $responses,
    ): JsonResponse {
        $tid = $this->tenantId($request);
        $res = $svc->create($tid, $httpRequest->validated('name'), $httpRequest->validated('url'), $httpRequest->validated('topics'));

        return $responses->ok([
            'webhook' => (new IntegrationWebhookResource($res['webhook']))->resolve(),
            'plain_secret' => $res['plain_secret'],
            'secret_note' => 'Store this secret once; it cannot be retrieved later.',
        ], [], 201);
    }

    public function show(Request $request, int $webhook, WebhookManagementService $svc, ApiResponseFactory $responses): JsonResponse
    {
        $w = $svc->findForTenant($this->tenantId($request), $webhook);
        if ($w === null) {
            return $responses->error(new ApiErrorResponse('webhook.not_found', 'Webhook not found.'), 404);
        }

        return $responses->ok((new IntegrationWebhookResource($w))->resolve());
    }

    public function update(
        Request $request,
        int $webhook,
        UpdateIntegrationWebhookRequest $httpRequest,
        WebhookManagementService $svc,
        ApiResponseFactory $responses,
    ): JsonResponse {
        $w = $svc->findForTenant($this->tenantId($request), $webhook);
        if ($w === null) {
            return $responses->error(new ApiErrorResponse('webhook.not_found', 'Webhook not found.'), 404);
        }
        $v = $httpRequest->validated();
        $svc->update($w, $v['name'] ?? null, $v['url'] ?? null, $v['topics'] ?? null);

        return $responses->ok((new IntegrationWebhookResource($w->refresh()))->resolve());
    }

    public function destroy(Request $request, int $webhook, WebhookManagementService $svc, ApiResponseFactory $responses): JsonResponse
    {
        $w = $svc->findForTenant($this->tenantId($request), $webhook);
        if ($w === null) {
            return $responses->error(new ApiErrorResponse('webhook.not_found', 'Webhook not found.'), 404);
        }
        $svc->delete($w);

        return $responses->ok(['deleted' => true]);
    }

    public function rotateSecret(Request $request, int $webhook, WebhookManagementService $svc, ApiResponseFactory $responses): JsonResponse
    {
        $w = $svc->findForTenant($this->tenantId($request), $webhook);
        if ($w === null) {
            return $responses->error(new ApiErrorResponse('webhook.not_found', 'Webhook not found.'), 404);
        }
        $res = $svc->rotateSecret($w);

        return $responses->ok([
            'webhook' => (new IntegrationWebhookResource($res['webhook']))->resolve(),
            'plain_secret' => $res['plain_secret'],
            'secret_note' => 'Store this secret once; it cannot be retrieved later.',
        ]);
    }

    public function test(Request $request, int $webhook, WebhookManagementService $svc, ApiResponseFactory $responses): JsonResponse
    {
        $w = $svc->findForTenant($this->tenantId($request), $webhook);
        if ($w === null) {
            return $responses->error(new ApiErrorResponse('webhook.not_found', 'Webhook not found.'), 404);
        }

        return $responses->ok($svc->test($w));
    }

    public function toggle(
        Request $request,
        int $webhook,
        ToggleWebhookEnabledRequest $httpRequest,
        WebhookManagementService $svc,
        ApiResponseFactory $responses,
    ): JsonResponse {
        $w = $svc->findForTenant($this->tenantId($request), $webhook);
        if ($w === null) {
            return $responses->error(new ApiErrorResponse('webhook.not_found', 'Webhook not found.'), 404);
        }
        $svc->setEnabled($w, (bool) $httpRequest->validated('enabled'));

        return $responses->ok((new IntegrationWebhookResource($w->refresh()))->resolve());
    }

    private function tenantId(Request $request): int
    {
        return (int) $request->attributes->get('tenant_id');
    }
}
