<?php
namespace EasyChat\Library\Messenger;

use EasyChat\Model\Messenger as MessengerModel;
use EasyChat\Model\OutboundContact;
use EasyChat\Model\SmsJob;







class SmsDeliveryProjector {
    private $registry;

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

    public function syncFromSmsJob(array $job): void {
        $job_id = (int)($job['job_id'] ?? 0);
        if ($job_id > 0) {
             
            $fresh = (new SmsJob($this->registry))->getById($job_id);
            if ($fresh) {
                $job = $fresh;
            }
        }

        $delivery_status = (string)($job['delivery_status'] ?? 'not_requested');
        $job_status = (string)($job['status'] ?? 'pending');
        if ($delivery_status === 'delivered') {
            $status = 'sent';
        } elseif ($delivery_status === 'failed') {
            $status = 'failed';
        } elseif ($job_status === 'sent') {
            $status = 'sent';
        } elseif (in_array($job_status, ['cancelled', 'expired', 'failed', 'permission_missing', 'sim_missing'], true)) {
            $status = 'failed';
        } else {
            $status = 'pending';
        }

        $last_stage_code = trim((string)($job['last_stage_code'] ?? ''));
        $confirmed_delivered = $delivery_status === 'delivered';
        $code = $status === 'sent' ? '' : $this->safeDispatchError(
            $last_stage_code !== '' ? $last_stage_code : (string)($job['last_error'] ?? '')
        );

        $delivery_id = (int)($job['delivery_id'] ?? 0);
        if ($delivery_id > 0) {
            (new MessengerModel($this->registry))->updateSmsDeliveryMonotonic(
                $delivery_id,
                $status,
                $code,
                $confirmed_delivered
            );
        }

        $message_id = (int)($job['message_id'] ?? 0);
        if ($message_id > 0) {
            (new OutboundContact($this->registry))->updateSmsStatusByMessageId(
                $message_id,
                $status,
                $code,
                $confirmed_delivered
            );
        }
    }

     
    public function healExpired(int $limit = 200): array {
        $expired = (new SmsJob($this->registry))->expireOverdue(max(1, min(1000, $limit)));
        foreach ($expired as $job) {
            $this->syncFromSmsJob($job);
        }

        return [
            'ran' => true,
            'expired' => count($expired),
        ];
    }

    private function safeDispatchError(string $value): string {
        $value = strtolower((string)preg_replace('/[^a-z0-9._-]/i', '_', trim($value)));
        return substr($value, 0, 64);
    }
}
