<?php
defined('BASEPATH') or exit('No direct script access allowed');

class RodTicketWebhook extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
    }

    private function respondSuccessAndContinue()
    {
        ignore_user_abort(true);
        @set_time_limit(0);

        $response = json_encode(array('success' => true));
        if (!headers_sent()) {
            header('Content-Type: application/json');
            header('Connection: close');
            header('Content-Length: ' . strlen($response));
            echo $response;
        }

        if (function_exists('fastcgi_finish_request')) {
            @fastcgi_finish_request();
            return;
        }

        @ob_flush();
        @flush();
    }

    private function waitMessageIdWithRetry($wbModel, $messageId, $maxAttempts = 3, $waitSeconds = 10)
    {
        $lookup = array(
            'success' => false,
            'exists' => false,
            'qtdPend' => 0,
            'qtdNota' => 0,
            'messageId' => $messageId
        );

        for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
            $lookup = $wbModel->buscarMessageIdNoBanco($messageId);
            if (isset($lookup['exists']) && $lookup['exists']) {
                return $lookup;
            }

            if ($attempt < $maxAttempts) {
                sleep($waitSeconds);
            }
        }

        return $lookup;
    }

    public function cobranca()
    {
        $rawBody = file_get_contents('php://input');
        $json = json_decode($rawBody, true);

        $payload = is_array($json) ? $json : array();
        $data = isset($payload['data']) ? $payload['data'] : array();

        $rawType = isset($payload['type']) ? $payload['type'] : '';
        $eventType = $rawType;
        switch ($rawType) {
            case 'new_message':
                $eventType = 'message.new';
                break;
            case 'reply_message':
                $eventType = 'message.reply';
                break;
            case 'update_message':
            case 'message_update':
                $eventType = 'message.update';
                break;
            case 'deleted_message':
            case 'message_deleted':
                $eventType = 'message.deleted';
                break;
            case 'reaction':
            case 'message_reaction':
                $eventType = 'message.reaction';
                break;
            case 'message_edited':
                $eventType = 'message.edited';
                break;
            case 'message_delivered':
                $eventType = 'message.delivered';
                break;
            case 'message_read':
                $eventType = 'message.read';
                break;
            case 'ticket_created':
                $eventType = 'ticket.created';
                break;
            case 'ticket_updated':
                $eventType = 'ticket.updated';
                break;
        }

        $key = isset($data['key']) ? $data['key'] : array();
        $fromMe = isset($key['fromMe']) ? (bool)$key['fromMe'] : false;
        $direction = $fromMe ? 'outbound' : 'inbound';

        $messageId = isset($data['messageId']) && $data['messageId'] !== ''
            ? $data['messageId']
            : (isset($key['id']) ? $key['id'] : '');

        $this->respondSuccessAndContinue();

        $this->load->model('Webhook_model');
        $wbModel = new Webhook_model();

        if (($eventType === 'message.delivered' || $eventType === 'message.read') && !empty($messageId)) {
            $lookup = $this->waitMessageIdWithRetry($wbModel, $messageId, 3, 10);
            if (!isset($lookup['exists']) || !$lookup['exists']) {
                return;
            }
        }

        if ($eventType === 'message.new' || $eventType === 'message.reply') {
            if ($direction === 'inbound' && !empty($messageId)) {
                $wbModel->marcarRespondidoPorMessageId($messageId);
                $wbModel->marcarRecebidoPorMessageId($messageId);
            }
            return;
        }

        if ($eventType === 'message.delivered') {
            if (!empty($messageId)) {
                $wbModel->marcarRecebidoPorMessageId($messageId);
            }
            return;
        }

        if ($eventType === 'message.read') {
            if (!empty($messageId)) {
                $wbModel->marcarRecebidoPorMessageId($messageId);
                $wbModel->marcarLidoPorMessageId($messageId);
            }
        }
    }
}
