<?php
namespace EasyChat\Library\Queue\Jobs;

use EasyChat\Library\Ai\CommerceContextReadinessService;
use EasyChat\Library\Ai\AiReplyEligibilityGuard;
use EasyChat\Library\AiResponder;
use EasyChat\Library\Messenger\MessengerLogger;
use EasyChat\Library\Messenger\ServiceNoticeClassifier;
use EasyChat\Library\Queue\RequeueWithoutAttemptException;
use EasyChat\Library\Support\OfficialProductSupportProfile;
use EasyChat\Model\Message;
use Exception;

class MessengerAiTickJob {

    private $registry;

    public function __construct($registry) {
        $this->registry = $registry;
    }

    public function handle(array $payload): void {
        $chat_id = (int)($payload['chat_id'] ?? 0);
        if ($chat_id <= 0) {
            throw new Exception('chat_id_required');
        }

        $message_id = (int)($payload['message_id'] ?? 0);
        if ($this->skipIneligibleReplyTarget($chat_id, $message_id, (string)($payload['source_provider'] ?? ''))) {
            return;
        }

        $context_readiness = (new CommerceContextReadinessService($this->registry))->checkAiPayload($payload);
        if (empty($context_readiness['ready'])) {
            throw new RequeueWithoutAttemptException(
                'commerce_context_wait:' . (string)($context_readiness['reason'] ?? 'not_ready'),
                (int)($context_readiness['delay'] ?? 15),
                is_array($context_readiness['payload'] ?? null) ? $context_readiness['payload'] : $payload
            );
        }

        if ($message_id > 0 && $this->skipServiceNotice($chat_id, $message_id, (string)($payload['source_provider'] ?? ''))) {
            return;
        }

        $support_profile = null;
        $official_claim = trim((string)($payload['official_support_claim'] ?? ''));
        if ($official_claim !== '') {
            $support_profile = (new OfficialProductSupportProfile($this->registry))
                ->resolveQueueClaim($chat_id, $message_id, $official_claim);
            if ($support_profile === null) {
                throw new Exception('official_support_claim_invalid');
            }
        }

        $ai = new AiResponder($this->registry);
        $success = $message_id > 0
            ? $ai->answerCustomerMessage($chat_id, $message_id, true, $support_profile)
            : $ai->tick($chat_id);
        if ($success) {
            return;
        }

        $result = $ai->getLastTickResult();
        $reason = (string)($result['reason'] ?? 'unknown');

         
         
         
        if ($reason === 'ai_delay_not_elapsed') {
            $retry_after = max(1, min(300, (int)($result['retry_after'] ?? 60)));
            throw new RequeueWithoutAttemptException('ai_tick_retryable:' . $reason, $retry_after);
        }

         
         
        if (!empty($result['retryable'])) {
            throw new Exception('ai_tick_retryable:' . $reason);
        }
    }

    private function skipServiceNotice(int $chat_id, int $message_id, string $payload_provider): bool {
        $message = (new Message($this->registry))->getMessageById($message_id);
        if (!$message || (int)($message['chat_id'] ?? 0) !== $chat_id || (int)($message['author'] ?? 0) !== 1) {
            return false;
        }

        $provider = strtolower(trim((string)($message['source_provider'] ?? '')));
        if ($provider === '') {
            $provider = strtolower(trim($payload_provider));
        }

        $result = (new ServiceNoticeClassifier())->classify($provider, urldecode((string)($message['text'] ?? '')), $message);
        if (empty($result['blocked'])) {
            return false;
        }

        (new MessengerLogger($this->registry, $provider))->info('ai_skip_service_notice', [
            'provider' => $provider,
            'chat_id' => $chat_id,
            'message_id' => $message_id,
            'reason' => (string)($result['reason'] ?? 'service_notice'),
            'layer' => 'queue',
        ]);
        return true;
    }

    private function skipIneligibleReplyTarget(int $chat_id, int $message_id, string $payload_provider): bool {
        $guard = new AiReplyEligibilityGuard($this->registry);
        $eligibility = $guard->checkChatId($chat_id);
        if (!empty($eligibility['allowed'])) {
            return false;
        }

        $guard->logSkip($chat_id, $message_id, $payload_provider, 'queue', $eligibility);
        return true;
    }
}
