<?php

namespace PublishPress\FuturePro\Modules\Notifications\Controllers;

use PublishPress\Future\Core\HookableInterface;
use PublishPress\Future\Framework\InitializableInterface;
use PublishPress\FuturePro\Core\Utils;
use PublishPress\FuturePro\Modules\Notifications\HooksAbstract;
use PublishPress\FuturePro\Modules\Notifications\Models\NotificationModel;
use PublishPress\FuturePro\Modules\Notifications\Models\NotificationUserModel;
use PublishPress\FuturePro\Modules\Workflows\HooksAbstract as WorkflowsHooksAbstract;

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

    /**
     * @var string
     */
    private $restApiV1BasePath;

    /**
     * @var string
     */
    private $pluginVersion;

    /**
     * @var NotificationUserModel
     */
    private $notificationUserModel;

    public function __construct(
        string $pluginVersion,
        string $restApiV1BasePath,
        HookableInterface $hooks,
        NotificationUserModel $notificationUserModel
    ) {
        $this->pluginVersion = $pluginVersion;
        $this->restApiV1BasePath = $restApiV1BasePath;
        $this->hooks = $hooks;
        $this->notificationUserModel = $notificationUserModel;
    }

    public function initialize()
    {
        $this->hooks->addAction(
            HooksAbstract::ACTION_ADMIN_ENQUEUE_SCRIPTS,
            [$this, 'enqueueScripts']
        );

        $this->hooks->addAction(
            WorkflowsHooksAbstract::ACTION_CREATED_NOTIFICATION,
            [$this, 'setUserLastNotificationTime'],
            10,
            1
        );

        $this->hooks->addFilter(
            HooksAbstract::FILTER_HEARTBEAT_RECEIVED,
            [$this, 'heartbeatReceived'],
            10,
            2
        );

        $this->hooks->addAction(
            WorkflowsHooksAbstract::ACTION_MARKED_ALL_NOTIFICATIONS_AS_READ,
            [$this, 'setUserLastNotificationTime']
        );

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

    public function enqueueScripts()
    {
        wp_enqueue_script(
            'ppfuture-admin-notifications',
            Utils::getScriptUrl('adminNotifications'),
            [
                'wp-element',
                'wp-components',
                'wp-i18n',
                'wp-api-fetch',
                'wp-data',
                'wp-notices',
            ],
            $this->pluginVersion,
            true
        );

        wp_localize_script(
            'ppfuture-admin-notifications',
            'ppfutureAdminNotifications',
            [
                "nonce" => wp_create_nonce("wp_rest"),
                "apiUrl" => rest_url($this->restApiV1BasePath),
            ]
        );
    }

    /**
     * Add a flag to the heartbeat response to indicate that the notifications should be fetched.
     *
     * @since 4.6.0
     */
    public function heartbeatReceived($response, $data)
    {
        if (isset($data['publishpress_notifications_request'])) {
            $clientLastFetchTime = intval($data['publishpress_notifications_request']);

            $latestNotificationTime = $this->notificationUserModel->getLastNotificationTime();

            // Only send timestamp if there are new notifications
            if ($latestNotificationTime && $latestNotificationTime > $clientLastFetchTime) {
                $response['publishpress_notifications_timestamp'] = $latestNotificationTime;
            }
        }
        return $response;
    }

    public function setUserLastNotificationTime()
    {
        $this->notificationUserModel->setLastNotificationTime();
    }
}
