<?php

namespace AIPT\Api\Chatbot\Jobs;

use AIPT\Api\Chatbot\ChatbotLogger;
use AIPT\Api\Constants\ChatbotConstants;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class AsyncRunner {

    private static array $logged_reasons = [];

    public static function isReady(): bool {
        if ( ! function_exists( 'as_schedule_single_action' ) || ! function_exists( 'as_next_scheduled_action' ) ) {
            self::logUnavailable( 'no_action_scheduler' );
            return false;
        }

        if ( ! class_exists( 'WooCommerce' ) ) {
            self::logUnavailable( 'no_woocommerce' );
            return false;
        }

        return true;
    }

    public static function scheduleJob( string $job_uuid ): bool {

        if ( 1 !== preg_match( '/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i', $job_uuid ) ) {
            ChatbotLogger::warn(
                'async_runner_schedule_failed',
                [
                    'job_uuid' => $job_uuid,
                    'error'    => 'invalid_job_uuid',
                ]
            );
            return false;
        }

        if ( ! self::isReady() ) {
            return false;
        }

        if ( ! \function_exists( 'as_schedule_single_action' ) ) {
            ChatbotLogger::warn(
                'async_runner_schedule_failed',
                [
                    'job_uuid' => $job_uuid,
                    'error'    => 'action_scheduler_unavailable',
                ]
            );
            return false;
        }

        try {

            $action_id = as_schedule_single_action(
                time(),
                ChatbotConstants::ACTION_SCHEDULER_HOOK,
                [ $job_uuid ],
                'aipt-chatbot'
            );
        } catch ( \Throwable $throwable ) {
            ChatbotLogger::warn(
                'async_runner_schedule_failed',
                [
                    'job_uuid' => $job_uuid,
                    'error'    => $throwable->getMessage(),
                ]
            );
            return false;
        }

        if ( false === $action_id ) {
            ChatbotLogger::warn(
                'async_runner_schedule_failed',
                [
                    'job_uuid' => $job_uuid,
                    'error'    => 'empty_action_id',
                ]
            );
            return false;
        }

        return true;
    }

    private static function logUnavailable( string $reason ): void {
        if ( isset( self::$logged_reasons[ $reason ] ) ) {
            return;
        }

        self::$logged_reasons[ $reason ] = true;

        ChatbotLogger::warn( 'async_runner_unavailable', [ 'reason' => $reason ] );
    }
}
