<?php

declare(strict_types=1);

namespace BookiFlex\Extensions\NotificationPreview\Api\Controller;

use BookiFlex\Core\Api\Controller\AbstractController;
use BookiFlex\Core\Contract\RoleCapabilitiesInterface;
use BookiFlex\Extensions\Notification\Model\Recipient;
use BookiFlex\Extensions\Notification\Provider\NotificationContextProvider;
use BookiFlex\Extensions\Notification\Service\NotificationRenderer;
use BookiFlex\Extensions\NotificationPreview\Api\Request\TestNotificationRequest;
use Throwable;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;

defined( 'ABSPATH' ) || exit;

class NotificationPreviewController extends AbstractController
{
    public const API_ENDPOINT_NAME = 'notifications';

    public function __construct(
        private readonly NotificationRenderer $renderer,
        private readonly NotificationContextProvider $fakeNotificationDataProvider,
        string $namespace = 'bflex/v1'
    ) {
        parent::__construct($namespace);
    }

    public function registerRoutes(): void
    {
        register_rest_route($this->namespace, '/' . self::API_ENDPOINT_NAME . '/test', [
            [
                'methods'  => 'GET',
                'callback' => [$this, 'testNotification'],
                'permission_callback' => [$this, 'hasAccess'],
                'args'                => TestNotificationRequest::getValidationRules(
                    $this->fakeNotificationDataProvider->getSupportedEvents()
                ),
            ],
        ]);
    }

    /**
     * GET /notifications/test - Preview notification email template
     */
    public function testNotification(WP_REST_Request $request): string|WP_Error
    {
        $event     = $request->get_param('event');
        $recipient = $request->get_param('recipient');

        try {
            $this->fakeNotificationDataProvider
                ->setReservation('1', $event)
                ->changeReservationStatus();
            $template = $this->fakeNotificationDataProvider->getTemplate(Recipient::from($recipient));
            $context  = $this->fakeNotificationDataProvider->getContext();

            $this->renderer->renderHtmlResponse($template, $context);
        } catch (Throwable $e) {
            return $this->handleError(
                $e,
                'notification_preview_failed',
                __('Failed to preview notification.', 'bookiflex')
            );
        }
    }

    public function hasAccess(): bool|WP_Error
    {
        if (!current_user_can(RoleCapabilitiesInterface::MANAGE_CONFIGURATION)) {
            return $this->error(
                'bookiflex_forbidden',
                __('You are not allowed to manage configuration.', 'bookiflex'),
                401
            );
        }

        return true;
    }
}
