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

use EasyChat\Library\AndroidPushNotifier;
use EasyChat\Library\Queue\JobInterface;
use EasyChat\Model\ChatAssignment;
use EasyChat\Model\Manager;







class ChatAssignmentPushJob implements JobInterface {
    private $registry;

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

    public function handle(array $payload): void {
        $chat_id = (int)($payload['chat_id'] ?? 0);
        $target_manager_id = (int)($payload['target_manager_id'] ?? 0);
        $mode = strtolower(trim((string)($payload['mode'] ?? '')));
        $channel = strtolower(trim((string)($payload['channel'] ?? '')));
        if ($chat_id <= 0
            || $target_manager_id <= 0
            || !in_array($mode, ['assigned', 'unassigned'], true)
            || !in_array($channel, ['fcm', 'webpush'], true)
            || ($mode === 'unassigned' && $channel !== 'fcm')
        ) {
            throw new \InvalidArgumentException('chat_assignment_push_payload_invalid');
        }

        $manager = (new Manager($this->registry))->getManagerById($target_manager_id);
        if (!$manager || (int)($manager['status'] ?? 0) !== 1) {
            return;
        }

        $assignments = new ChatAssignment($this->registry);
        $currently_assigned = $assignments->isAssigned($chat_id, $target_manager_id, true);
        if (!$this->eventStillCurrent($mode, $currently_assigned)) {
            return;
        }

        $result = (new AndroidPushNotifier($this->registry))->notifyChatAssignment(
            $chat_id,
            $target_manager_id,
            $mode === 'assigned',
            [$channel]
        );
        if (!$this->deliveryAccepted($result, $channel)) {
            $code = preg_replace(
                '/[^a-z0-9._-]/i',
                '_',
                (string)($result['error'] ?? 'chat_assignment_push_failed')
            );
            throw new \RuntimeException(substr($code, 0, 80));
        }
    }

    private function eventStillCurrent(string $mode, bool $currently_assigned): bool {
         
         
         
        return $mode === 'assigned' ? $currently_assigned : !$currently_assigned;
    }

    private function deliveryAccepted(array $result, string $channel): bool {
        if (!empty($result['policy_blocked'])) {
             
             
            return true;
        }
        if (!empty($result['fanout'])) {
            if ((int)($result[$channel . '_sent'] ?? 0) > 0) {
                return true;
            }
             
             
             
            return !empty($result['success'])
                && (int)($result['target_count'] ?? -1) === 0
                && (int)($result['failed'] ?? 0) === 0
                && (int)($result[$channel . '_failed'] ?? 0) === 0;
        }
        return $channel === 'fcm' && (int)($result['sent'] ?? 0) > 0;
    }
}
