<?php

namespace PublishPress\FuturePro\Modules\Workflows\Models;

use PublishPress\Future\Core\DI\Container;
use PublishPress\Future\Framework\Database\Interfaces\DBTableSchemaInterface;
use PublishPress\FuturePro\Core\ServicesAbstract;
use PublishPress\FuturePro\Modules\Workflows\Interfaces\EventDrivenActionsModelInterface;

class EventDrivenActionsModel implements EventDrivenActionsModelInterface
{
    /**
     * @var DBTableSchemaInterface
     */
    private $dbTableSchema;

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

    /**
     * @var int
     */
    private $retentionPeriod;

    public function __construct()
    {
        $container = Container::getInstance();

        // TODO: Inject this
        $this->dbTableSchema = $container->get(ServicesAbstract::DB_TABLE_WORKFLOW_EVENT_DRIVEN_ACTIONS_SCHEMA);
        $this->tableName = $this->dbTableSchema->getTableName();
        $settingsFacade = $container->get(ServicesAbstract::SETTINGS);

        $this->retentionPeriod = $settingsFacade->getScheduledWorkflowStepsCleanupRetention();
    }

    public function getEventDrivenActions(
        int $userId,
        ?int $limit = null,
        ?int $offset = null,
        ?string $order = 'ASC'
    ): array {
        global $wpdb;

        $eventDrivenActions = $this->getResults(
            $wpdb->prepare(
                "SELECT * FROM %i WHERE user_id = %d",
                $this->tableName,
                (int) $userId
            ),
            $limit,
            $offset,
            $order
        );

        return $eventDrivenActions;
    }

    public function getEventDrivenActionsByStatus(
        string $status,
        ?int $limit = null,
        ?int $offset = null,
        ?string $order = 'ASC'
    ): array {
        global $wpdb;

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
        $eventDrivenActions = $this->getResults(
            $wpdb->prepare(
                "SELECT * FROM %i WHERE status = %s",
                $this->tableName,
                $status
            ),
            $limit,
            $offset,
            $order
        );

        return $eventDrivenActions;
    }

    private function getResults(
        string $sql,
        ?int $limit = null,
        ?int $offset = null,
        ?string $order = 'ASC'
    ): array {
        global $wpdb;

        $order = strtoupper($order) === 'ASC' ? 'ASC' : 'DESC';

        if (! $limit) {
            $limit = PHP_INT_MAX;
        }

        if (! $offset) {
            $offset = 0;
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
        return $wpdb->get_results(
            $wpdb->prepare(
                // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
                $sql . " ORDER BY created_at %s LIMIT %d OFFSET %d",
                $order,
                (int) $limit,
                (int) $offset
            )
        );
    }

    public function deleteExpiredDoneActions(): int
    {
        global $wpdb;

        $expirationDate = date('Y-m-d H:i:s', strtotime("-" . $this->retentionPeriod . " days"));

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
        $result = $wpdb->query(
            $wpdb->prepare(
                "DELETE FROM %i WHERE status IN (%s, %s, %s) AND started_at < %s",
                $this->tableName,
                'completed',
                'canceled',
                'failed',
                $expirationDate
            )
        );

        if ($result === false) {
            return 0;
        }

        return (int)$result;
    }
}
