<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreNotificationMap;
use App\Http\Requests\UpdateNotificationMap;
use App\Http\Resources\NotificationMapResource;
use App\Master\ApiUserRepository;
use App\Models\NotificationMap;
use App\Models\NotificationTemplate;
use Illuminate\Http\Response;

/**
 * Site-level CRUD for inbound notification maps. A map can be created from a published
 * system NotificationTemplate, which seeds its field_map / validation / config (the
 * "apply template to a site" flow). Distinct from NotificationMapController, which
 * serves the public inbound endpoint.
 */
class NotificationMapAdminController extends Controller
{
    public function index()
    {
        return NotificationMap::query()->paginate();
    }

    public function store(StoreNotificationMap $request): NotificationMapResource
    {
        $template = $this->resolveTemplate($request->input('template_id'));

        $map = NotificationMap::query()->create([
            'name' => $request->input('name'),
            'type' => $template->type ?? $request->input('type', 'vehicle'),
            'template_id' => $template?->id,
            'field_map' => $template->field_map ?? [],
            'validation' => $template->validation ?? [],
            'config' => $template->config ?? [],
        ]);

        return new NotificationMapResource($map);
    }

    public function show(NotificationMap $notificationMap): NotificationMapResource
    {
        return new NotificationMapResource($notificationMap);
    }

    public function update(UpdateNotificationMap $request, NotificationMap $notificationMap): NotificationMapResource
    {
        $notificationMap->fill([
            'name' => $request->input('name'),
            'active' => $request->boolean('active'),
            'type' => $request->input('type', $notificationMap->type),
            'template_id' => $request->input('template_id'),
            'field_map' => $request->input('field_map', []),
            'validation' => $request->input('validation', []),
            'config' => $request->input('config', []),
        ]);

        $notificationMap->save();

        return new NotificationMapResource($notificationMap);
    }

    public function destroy(NotificationMap $notificationMap): Response
    {
        $notificationMap->delete();

        return response('ok');
    }

    /**
     * Return the API token a site uses to authenticate its inbound webhooks. Backed by
     * a dedicated API user scoped to this tenant only (created on first use), so the
     * credential shown to a site admin can never authenticate against another site.
     * The persistent token is reused across calls and only minted when absent/expired.
     */
    public function token(ApiUserRepository $repository): array
    {
        $apiUser = $repository->firstOrCreateSiteWebhookUser(tenant('id'));
        $token = $repository->ensurePersistentToken($apiUser);

        return [
            'name' => $apiUser->name,
            'token' => $token->token,
            'expires_at' => $token->expires_at?->format('d/m/Y H:i'),
            'expires_in_days' => (int) round($token->expires_in_days),
        ];
    }

    /**
     * Resolve a published system template by id, or null when none was requested.
     * A requested-but-missing/unpublished template is a 422.
     */
    private function resolveTemplate(?int $templateId): ?NotificationTemplate
    {
        if (empty($templateId)) {
            return null;
        }

        $template = NotificationTemplate::query()->published()->find($templateId);

        abort_if($template === null, 422, 'The selected template is not available.');

        return $template;
    }
}
