<?php
require_once '/var/www/cgi/lib/senior.php';

header("Content-Type: application/json; charset=utf-8");

$request_headers = array_change_key_case(getallheaders(), CASE_LOWER);

$auth = false;
if (
    (isset($request_headers['username']) && $request_headers['username'] == 'nettcom') &&
    (isset($request_headers['secret']) && $request_headers['secret'] == 'teste@@')
) {
    $auth = true;
}

if (!$auth) {
    echo json_encode(['error' => 'Unauthorized access'], JSON_UNESCAPED_UNICODE);
    return false;
}

$nf        = isset($_GET['nf']) ? trim($_GET['nf']) : '';
$cnpj_cpf  = isset($_GET['cnpj_cpf']) ? trim($_GET['cnpj_cpf']) : '';
$dominio   = isset($_GET['dominio']) ? trim($_GET['dominio']) : '';

if ($nf === '' || $cnpj_cpf === '' || $dominio === '') {
    echo json_encode([
        'success' => false,
        'error'   => 'Parâmetros obrigatórios: nf, cnpj_cpf e dominio.'
    ], JSON_UNESCAPED_UNICODE);
    return false;
}

$dominio_normalizado = strtolower($dominio);

/**
 * Verifica se o retorno da Senior trouxe registro.
 */
function trd_tem_registro($dados)
{
    return (
        is_array($dados) &&
        !empty($dados['totalRegistros']) &&
        (int)$dados['totalRegistros'] > 0 &&
        !empty($dados['listaTracking']) &&
        is_array($dados['listaTracking'])
    );
}

/**
 * Consulta tracking externo da TRD na Senior.
 *
 * $campo pode ser:
 * - identificadorCliente
 * - inscricaoFiscal
 */
function consulta_tracking_trd($nf, $cnpj_cpf, $campo)
{
    $url = 'https://platform.senior.com.br/t/senior.com.br/bridge/1.0/anonymous/rest/tms/tck/actions/externalTenantConsultaTracking';

    // Remove máscara do CNPJ/CPF
    $cnpj_cpf = preg_replace('/\D+/', '', $cnpj_cpf);

    $payload = [
        'documento' => $nf,
        $campo => $cnpj_cpf,

        // Retorna somente fases executadas na própria API
        'somenteFasesExecutadas' => true,

        'pageRequest' => [
            'offset' => 0,
            'size'   => 10
        ]
    ];

    $ch = curl_init();

    curl_setopt_array($ch, [
        CURLOPT_URL            => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'X-Tenant: trdtransportes',
            'X-TenantDomain: trdtransportes.com.br'
        ],
        CURLOPT_POSTFIELDS     => json_encode($payload, JSON_UNESCAPED_UNICODE),
        CURLOPT_CONNECTTIMEOUT => 15,
        CURLOPT_TIMEOUT        => 60
    ]);

    $response = curl_exec($ch);
    $curlError = curl_error($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    curl_close($ch);

    if ($response === false) {
        return [
            'success' => false,
            'error'   => 'Erro cURL: ' . $curlError
        ];
    }

    $json = json_decode($response, true);

    if (!is_array($json)) {
        return [
            'success'  => false,
            'error'    => 'Retorno inválido da API TRD.',
            'httpCode' => $httpCode,
            'raw'      => $response
        ];
    }

    if ($httpCode < 200 || $httpCode >= 300) {
        return [
            'success'  => false,
            'error'    => 'Erro na API TRD.',
            'httpCode' => $httpCode,
            'response' => $json
        ];
    }

    return $json;
}

/**
 * Consulta TRD primeiro por identificadorCliente.
 * Se não encontrar, consulta por inscricaoFiscal.
 */
function consulta_tracking_trd_com_fallback($nf, $cnpj_cpf)
{
    // 1) Primeiro tenta com identificadorCliente
    $dados = consulta_tracking_trd($nf, $cnpj_cpf, 'identificadorCliente');

    if (isset($dados['success']) && $dados['success'] === false) {
        return $dados;
    }

    if (trd_tem_registro($dados)) {
        return $dados;
    }

    // 2) Se não encontrou, tenta com inscricaoFiscal
    $dados = consulta_tracking_trd($nf, $cnpj_cpf, 'inscricaoFiscal');

    if (isset($dados['success']) && $dados['success'] === false) {
        return $dados;
    }

    return $dados;
}

/**
 * Converte valor de executada para boolean.
 */
function trd_executada_true($valor)
{
    return (
        $valor === true ||
        $valor === 'true' ||
        $valor === 1 ||
        $valor === '1'
    );
}

/**
 * Retorna prioridade quando a dataExecucao for igual.
 * Transbordo precisa vir antes de Destino.
 */
function trd_prioridade_descricao($descricao)
{
    $descricao = strtolower((string)$descricao);

    if (strpos($descricao, 'transbordo') !== false) {
        return 10;
    }

    if (strpos($descricao, 'destino') !== false) {
        return 20;
    }

    return 99;
}

/**
 * Monta o mesmo retorno do PHP antigo:
 * cte, previsao_entrega, descricao e createdDate.
 *
 * CORRIGIDO:
 * Ordena pela dataExecucao real da TRD, e não pela sequencia.
 * Assim:
 * Manifestado p/ Transbordo 2026-06-07
 * vem antes de:
 * Manifestado p/ Destino 2026-06-08
 */
function montar_retorno_tracking_trd(array $dados)
{
    if (
        empty($dados['totalRegistros']) ||
        empty($dados['listaTracking']) ||
        !is_array($dados['listaTracking'])
    ) {
        return [
            'success' => false,
            'error'   => 'Nenhum registro encontrado para o CNPJ/CPF informado.'
        ];
    }

    $item = $dados['listaTracking'][0];

    $tracking = isset($item['tracking']) ? $item['tracking'] : [];

    $previsao_entrega = isset($tracking['dataPrevisaoEntrega'])
        ? $tracking['dataPrevisaoEntrega']
        : null;

    // Busca o CTe dentro de listaTrackingDocumento
    $cte = null;

    if (!empty($item['listaTrackingDocumento']) && is_array($item['listaTrackingDocumento'])) {
        foreach ($item['listaTrackingDocumento'] as $docItem) {
            $doc = isset($docItem['documento']) ? $docItem['documento'] : [];

            if (
                isset($doc['tipoDocumento']['codigo']) &&
                $doc['tipoDocumento']['codigo'] === 'CTe'
            ) {
                $cte = isset($doc['numero']) ? $doc['numero'] : null;
                break;
            }
        }
    }

    $fases = isset($item['listaTrackingFase']) && is_array($item['listaTrackingFase'])
        ? $item['listaTrackingFase']
        : [];

    /**
     * Ordenação correta:
     * 1 - dataExecucao menor primeiro
     * 2 - se mesma data, Transbordo antes de Destino
     * 3 - se ainda empatar, usa sequencia
     */
    usort($fases, function ($a, $b) {
        $dataA = isset($a['dataExecucao']) ? strtotime($a['dataExecucao']) : false;
        $dataB = isset($b['dataExecucao']) ? strtotime($b['dataExecucao']) : false;

        $timeA = ($dataA !== false) ? $dataA : PHP_INT_MAX;
        $timeB = ($dataB !== false) ? $dataB : PHP_INT_MAX;

        if ($timeA != $timeB) {
            return ($timeA < $timeB) ? -1 : 1;
        }

        $descA = isset($a['fase']['descricao']) ? $a['fase']['descricao'] : '';
        $descB = isset($b['fase']['descricao']) ? $b['fase']['descricao'] : '';

        $prioA = trd_prioridade_descricao($descA);
        $prioB = trd_prioridade_descricao($descB);

        if ($prioA != $prioB) {
            return ($prioA < $prioB) ? -1 : 1;
        }

        $seqA = isset($a['sequencia']) ? (int)$a['sequencia'] : 999999;
        $seqB = isset($b['sequencia']) ? (int)$b['sequencia'] : 999999;

        if ($seqA == $seqB) {
            return 0;
        }

        return ($seqA < $seqB) ? -1 : 1;
    });

    $result = [];

    foreach ($fases as $faseItem) {

        // Só retorna fases executadas
        $executada = isset($faseItem['executada']) ? $faseItem['executada'] : false;

        if (!trd_executada_true($executada)) {
            continue;
        }

        $descricao = isset($faseItem['fase']['descricao'])
            ? $faseItem['fase']['descricao']
            : null;

        if ($descricao === null || $descricao === '') {
            continue;
        }

        // Mantém o mesmo filtro do PHP antigo
        $ignore = ["Plano padrão", "Encerrado", "Aberto"];

        if (in_array($descricao, $ignore, true)) {
            continue;
        }

        $result[] = [
            'cte'              => $cte,
            'previsao_entrega' => $previsao_entrega,
            'descricao'        => $descricao,
            'createdDate'      => isset($faseItem['dataExecucao']) ? $faseItem['dataExecucao'] : null
        ];
    }

    if (empty($result)) {
        return [
            'success' => false,
            'error'   => 'Nenhuma fase executada encontrada para essa NF.'
        ];
    }

    // Reindexa a partir de 1 igual seu código antigo
    $final = [];

    foreach ($result as $i => $item) {
        $final[$i + 1] = $item;
    }

    return $final;
}

/**
 * IF NOVO PARA TRD
 */
if ($dominio_normalizado === 'trd') {
    $dados_trd = consulta_tracking_trd_com_fallback($nf, $cnpj_cpf);

    if (isset($dados_trd['success']) && $dados_trd['success'] === false) {
        echo json_encode($dados_trd, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
        return false;
    }

    $final_trd = montar_retorno_tracking_trd($dados_trd);

    echo json_encode($final_trd, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    return true;
}

/**
 * FLUXO ANTIGO PARA OUTROS DOMÍNIOS
 */

// 1) Tenta buscar como REMETENTE
$dados = get_cnpj_emitente($nf, $cnpj_cpf, 'REMETENTE', $dominio);

// 2) Se não veio nenhum registro, tenta como DESTINATÁRIO
if (empty($dados['totalRegistros']) || $dados['totalRegistros'] === 0) {
    $dados = get_cnpj_emitente($nf, $cnpj_cpf, 'DESTINATARIO', $dominio);

    // 3) Se ainda assim não vier nada, retorna erro e sai
    if (empty($dados['totalRegistros']) || $dados['totalRegistros'] === 0) {
        echo json_encode([
            'success' => false,
            'error'   => 'Nenhum registro encontrado para o CNPJ/CPF informado.'
        ], JSON_UNESCAPED_UNICODE);
        return false;
    }
}

$cnpj_remetente = $dados['documentos'][0]['emitentenotafiscalInscricaoFiscal'];

$dados = get_rastreio($nf, $cnpj_remetente, $dominio);

// pega a previsão de entrega do retorno
$previsao_entrega = isset($dados['previsao_entrega']) ? $dados['previsao_entrega'] : null;

$dataDocumentos = isset($dados['documentosEEnvolvidos'])
    ? $dados['documentosEEnvolvidos']
    : ['documentosEEnvolvidos' => []];

$cte = null;

if (!empty($dataDocumentos['documentosEEnvolvidos']) && is_array($dataDocumentos['documentosEEnvolvidos'])) {
    foreach ($dataDocumentos['documentosEEnvolvidos'] as $doc) {
        if (isset($doc['tipoDocumento']['codigo']) && $doc['tipoDocumento']['codigo'] === 'CTe') {
            $cte = $doc['numero'];
            break;
        }
    }
}

// pega o array de fases que veio de get_rastreio()
$dataFase = isset($dados['trackingFase'])
    ? $dados['trackingFase']
    : ['contents' => []];

// extrai o número do CTE
if (isset($dataFase['errorCode'])) {
    echo json_encode('NF NAO ENCONTRADA', JSON_UNESCAPED_UNICODE);
    return false;
}

// função recursiva
function findDescricaoAndCreatedDate(array $array, $cte, $previsao_entrega, $parentDataExec = null)
{
    $found = [];

    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $nextParent = isset($array['dataExecucao']) ? $array['dataExecucao'] : $parentDataExec;

            $found = array_merge(
                $found,
                findDescricaoAndCreatedDate($value, $cte, $previsao_entrega, $nextParent)
            );
        } elseif ($key === 'descricao') {
            $found[] = [
                'cte'              => $cte,
                'previsao_entrega' => $previsao_entrega,
                'descricao'        => $value,
                'createdDate'      => $parentDataExec,
            ];
        }
    }

    return $found;
}

// percorre cada fase em trackingFase['contents']
$result = [];

if (!empty($dataFase['contents']) && is_array($dataFase['contents'])) {
    foreach ($dataFase['contents'] as $content) {
        $initialExec = isset($content['dataExecucao']) ? $content['dataExecucao'] : null;

        $result = array_merge(
            $result,
            findDescricaoAndCreatedDate($content, $cte, $previsao_entrega, $initialExec)
        );
    }
}

// filtra descrições indesejadas
$result = array_values(array_filter($result, function ($item) {
    $ignore = ["Plano padrão", "Encerrado", "Aberto"];
    return !in_array($item['descricao'], $ignore, true);
}));

// reindexa a partir de 1
$final = [];

foreach ($result as $i => $item) {
    $final[$i + 1] = $item;
}

// retorna o JSON final
echo json_encode($final, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
return true;