<?php

namespace PublishPress\FuturePro\Modules\Workflows\Controllers;

use PublishPress\Future\Core\HookableInterface;
use PublishPress\Future\Framework\InitializableInterface;
use PublishPress\Future\Framework\Logger\LoggerInterface;
use PublishPress\FuturePro\Modules\Notifications\Models\NotificationModel;
use PublishPress\FuturePro\Modules\Notifications\Models\NotificationsModel;
use PublishPress\FuturePro\Modules\Workflows\HooksAbstract;
use PublishPress\FuturePro\Modules\Workflows\Models\EventDrivenActionModel;
use PublishPress\FuturePro\Modules\Workflows\Models\EventDrivenActionsModel;

class Notifications implements InitializableInterface
{
    /**
     * @var HookableInterface
     */
    private $hooks;

    /**
     * @var LoggerInterface
     */
    private $logger;

    public function __construct(HookableInterface $hooks, LoggerInterface $logger)
    {
        $this->hooks = $hooks;
        $this->logger = $logger;
    }

    public function initialize()
    {
        $this->hooks->addAction(
            HooksAbstract::ACTION_EXECUTE_NOTIFICATION_OPTION,
            [$this, 'onExecuteNotificationOption'],
            10,
            2
        );

        $this->hooks->addAction(
            HooksAbstract::ACTION_DELETE_EXPIRED_DONE_ACTIONS,
            [$this, 'onDeleteExpiredDoneActions']
        );
    }

    public function onExecuteNotificationOption(array $notificationIds, string $optionName): void
    {
        foreach ($notificationIds as $notificationId) {
            $notificationModel = new NotificationModel();
            $notificationModel->load($notificationId);

            if (! $notificationModel->actionId) {
                return;
            }

            if (! $notificationModel->belongsToCurrentUser()) {
                $this->logDebugMessage('Notification %1$s is not owned by the current user', $notificationId);
                return;
            }

            $eventDrivenActionModel = new EventDrivenActionModel();
            $loaded = $eventDrivenActionModel->load($notificationModel->actionId);

            if (! $loaded) {
                $this->logDebugMessage('Event driven action not found for notification %1$s', $notificationId);
                return;
            }

            // Any option selected from the notification will mark it as read.
            $notificationModel->markAsRead();

            // Here we can pass additional arguments later, like input from a form data, etc.
            $this->hooks->doAction(
                HooksAbstract::ACTION_EVENT_DRIVEN_STEP_EXECUTE,
                $eventDrivenActionModel->id,
                [
                    'notificationId' => $notificationId,
                    'optionName' => $optionName,
                ]
            );
        }
    }

    public function onDeleteExpiredDoneActions(): void
    {
        $eventDrivenActionsModel = new EventDrivenActionsModel();
        $eventDrivenActionsModel->deleteExpiredDoneActions();
    }

    private function logDebugMessage(string $message, ...$args): void
    {
        $this->logger->debug(sprintf($message, ...$args));
    }
}
