TransWar File Browser

Path: C:\

<?php
header('Content-Type: application/json; charset=utf-8');

// Tenta requerer o autoload (se rodaram composer install localmente)
if (file_exists(__DIR__ . '/vendor/autoload.php')) {
    require __DIR__ . '/vendor/autoload.php';
} else {
    // Se não encontrou, confiar que o servidor carrega globalmente ou lançar aviso claro
    if (!class_exists('\PhpOffice\PhpSpreadsheet\IOFactory')) {
        echo json_encode(['status' => 'error', 'message' => "ERRO DO SERVIDOR: PhpSpreadsheet não foi carregado.\nRode 'composer install' na pasta Transvoyant-manual ou verifique a instalação global."]);
        exit;
    }
}

use PhpOffice\PhpSpreadsheet\IOFactory;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    echo json_encode(['status' => 'error', 'message' => 'Requisição inválida.']);
    exit;
}

if (!isset($_FILES['csv_file']) || $_FILES['csv_file']['error'] !== UPLOAD_ERR_OK) {
    echo json_encode(['status' => 'error', 'message' => 'Erro no upload do arquivo.']);
    exit;
}

$tempPath = $_FILES['csv_file']['tmp_name'];
$originalName = $_FILES['csv_file']['name'];

try {
    // 1. LÊ as linhas do CSV manualmente para ter mais controle igual ao Pandas
    $fileData = file_get_contents($tempPath);
    // Tenta arrumar encoding se vier em ANSI (Windows-1252/latin1)
    if (!mb_check_encoding($fileData, 'UTF-8')) {
        $fileData = utf8_encode($fileData); // Fallback legado suportado
    }

    // Identificar Delimitador pela primeira linha
    $lines = explode("\n", str_replace("\r", "", trim($fileData)));
    if (count($lines) == 0) {
        throw new Exception("O arquivo CSV está vazio.");
    }

    $headerLine = $lines[0];
    $delimiter = ';';
    if (substr_count($headerLine, ';') < substr_count($headerLine, ',')) {
        $delimiter = ',';
    }

    $headers = str_getcsv($headerLine, $delimiter);
    // Mapeamento de índices do cabeçalho
    $idx = [];
    foreach ($headers as $i => $col) {
        $idx[trim($col)] = $i;
    }

    // Regras e verificações de colunas vitais
    $hasCte = isset($idx['Tomador CT-e']);
    $hasMin = isset($idx['Tomador Minuta']);

    if (!$hasCte && !$hasMin) {
        throw new Exception("Nenhuma das colunas de Tomador ('Tomador CT-e' ou 'Tomador Minuta') foi encontrada no CSV.");
    }

    // Processamento linha a linha
    $linhasValidas = [];
    $notasDescartadas = 0;

    for ($i = 1; $i < count($lines); $i++) {
        if (trim($lines[$i]) === '')
            continue; // linha em branco

        $row = str_getcsv($lines[$i], $delimiter);

        // Completa as colunas faltantes com vazio se a linha estiver quebrada
        while (count($row) < count($headers)) {
            $row[] = '';
        }

        $passouFirmenich = false;
        $temDSM = false;

        // Verifica FIRMENICH
        if ($hasCte && stripos($row[$idx['Tomador CT-e']], 'FIRMENICH') !== false)
            $passouFirmenich = true;
        if ($hasMin && stripos($row[$idx['Tomador Minuta']], 'FIRMENICH') !== false)
            $passouFirmenich = true;

        // Verifica se possui DSM
        if ($hasCte && stripos($row[$idx['Tomador CT-e']], 'DSM') !== false)
            $temDSM = true;
        if ($hasMin && stripos($row[$idx['Tomador Minuta']], 'DSM') !== false)
            $temDSM = true;

        if ($passouFirmenich) {
            // Verifica as Datas
            $dtSaidaCte = isset($idx['Dt. Saída - CTE']) ? trim($row[$idx['Dt. Saída - CTE']]) : '';
            $dtSaidaMin = isset($idx['Dt. Saída - Minuta']) ? trim($row[$idx['Dt. Saída - Minuta']]) : '';

            $validCteDate = ($dtSaidaCte !== '' && strtolower($dtSaidaCte) !== 'nan');
            $validMinDate = ($dtSaidaMin !== '' && strtolower($dtSaidaMin) !== 'nan');

            if (!$validCteDate && !$validMinDate && (isset($idx['Dt. Saída - CTE']) || isset($idx['Dt. Saída - Minuta']))) {
                $notasDescartadas++;
                continue; // Linha descartada
            }

            // Monta o objeto que vai pro excel
            $linhasValidas[] = [
                'Numero_pedido' => isset($idx['Número do pedido']) ? trim($row[$idx['Número do pedido']]) : '',
                'Saida_CTE' => $dtSaidaCte,
                'Saida_Minuta' => $dtSaidaMin,
                'Entrega_CTE' => isset($idx['Dt. Entrega - CTE']) ? trim($row[$idx['Dt. Entrega - CTE']]) : '',
                'Entrega_Minuta' => isset($idx['Dt. Entrega - Minuta']) ? trim($row[$idx['Dt. Entrega - Minuta']]) : '',
                'Copia_Pedido_Remessa' => !$temDSM
            ];
        }
    }

    // Checa se há dados
    if (count($linhasValidas) === 0) {
        $msg = "Nenhuma linha atendeu a todos os critérios (Tomador com Firmenich e possuir Data).";
        if ($notasDescartadas > 0)
            $msg .= "\n\nNota: Foram descartadas $notasDescartadas linhas com Firmenich por não terem Data de Saída.";
        echo json_encode(['status' => 'warning', 'message' => $msg]);
        exit;
    }

    // 2. ABRIR E PREENCHER O FORMATO DO TRANSVOYANT
    $modeloPath = __DIR__ . '/Modelo-Transvoyant.xlsx';
    if (!file_exists($modeloPath)) {
        throw new Exception("Arquivo modelo não encontrado: Modelo-Transvoyant.xlsx não está na pasta no servidor.");
    }

    $spreadsheet = IOFactory::load($modeloPath);
    $sheet = $spreadsheet->getActiveSheet();

    // Limpa linhas após o cabeçalho se houver (o original já costumava vir limpo, max_row no phpSpreadsheet éHighestRow)
    $highestRow = $sheet->getHighestRow();
    if ($highestRow > 2) {
        // Remover linhas seria complexo para as formatações nativas, então sobrescrevemos
        // Nesse caso de uso prático, o openpyxl deletava. PhpSpreadsheet deleteRow:
        $sheet->removeRow(3, $highestRow - 2);
    }

    $linhaDestino = 3;
    $linhasEscritas = 0;

    foreach ($linhasValidas as $dado) {
        // A: Compañía
        $sheet->setCellValue('A' . $linhaDestino, 'TRANS WAR TRANSPORTES LTDA');

        // B: Número de entrega
        $pedido = $dado['Numero_pedido'];
        if (substr($pedido, -2) === '.0') {
            $pedido = substr($pedido, 0, -2);
        }
        
        $pedidoFormatado = '';
        if ($pedido !== '') {
            // Preenche com zeros à esquerda até 10 dígitos
            $pedidoFormatado = str_pad($pedido, 10, "0", STR_PAD_LEFT);
            // Salva como texto explícito para o Excel manter os zeros
            $sheet->setCellValueExplicit('B' . $linhaDestino, $pedidoFormatado, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);
        }

        // D: Numero de Remessa (Shipment Number)
        if ($dado['Copia_Pedido_Remessa'] && $pedidoFormatado !== '') {
            $sheet->setCellValueExplicit('D' . $linhaDestino, $pedidoFormatado, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);
        }

        // M: Momento da Coleta (Dt Saída - Minuta ou CTE)
        $saida = ($dado['Saida_Minuta'] !== '' && strtolower($dado['Saida_Minuta']) !== 'nan') ? $dado['Saida_Minuta'] : $dado['Saida_CTE'];
        if ($saida !== '' && strtolower($saida) !== 'nan')
            $sheet->setCellValue('M' . $linhaDestino, $saida);

        // U: Finalização (Dt Entrega - Minuta ou CTE)
        $entrega = ($dado['Entrega_Minuta'] !== '' && strtolower($dado['Entrega_Minuta']) !== 'nan') ? $dado['Entrega_Minuta'] : $dado['Entrega_CTE'];
        if ($entrega !== '' && strtolower($entrega) !== 'nan')
            $sheet->setCellValue('U' . $linhaDestino, $entrega);

        $linhaDestino++;
        $linhasEscritas++;
    }

    // Gerar arquivo final formatado
    $dataAtual = date("d-m-Y_H\hi");
    $outputName = "Envio_Transvoyant_$dataAtual.xlsx";
    $outputPath = __DIR__ . '/' . $outputName;

    $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
    $writer->save($outputPath);

    // 3. ENVIO DO E-MAIL VIA SMTP DE ACORDO COM O CÓDIGO PYTHON
    $emailSucesso = false;
    $emailErroMsg = "";

    try {
        $mail = new PHPMailer(true);
        $mail->isSMTP();
        $mail->Host = 'smtplw.com.br';
        $mail->SMTPAuth = true;
        $mail->Username = 'transwartransportes'; // Conforme o python original
        $mail->Password = 'zvtsyiJL8214';       // Conforme o python original
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Equivalente a .starttls() na porta 587
        $mail->Port = 587;
        $mail->CharSet = 'UTF-8';

        $mail->setFrom('envioautomatico@transwar.com.br', 'Automação Transwar');

        // Destinatários baseados no original
        $destinatarios = [
            //    'andressa.marozi@transwar.com.br',
            //    'eliane.rodrigues@transwar.com.br',
            'danilo.faria@transwar.com.br'
        ];
        foreach ($destinatarios as $dest) {
            $mail->addAddress($dest);
        }

        $mail->Subject = 'Relatório Transvoyant Processado';
        $mail->Body = "Olá,\n\nSegue em anexo o arquivo para integração Transvoyant.\n\nAtenciosamente,\nAutomação Transwar";

        // Anexo Excel
        $mail->addAttachment($outputPath, $outputName);

        $mail->send();
        $emailSucesso = true;
    } catch (Exception $e) {
        $emailErroMsg = $mail->ErrorInfo ?: $e->getMessage();
    }

    // Retorno do resultado Final
    $sucesso_msg = "SISTEMA CONCLUÍDO COM SUCESSO!\n\nArquivo configurado: $outputName\nLinhas Preenchidas: $linhasEscritas.\n";
    if ($notasDescartadas > 0) {
        $sucesso_msg .= "Aviso: $notasDescartadas Notas foram detectadas porém descartadas devido à falta de Data de Saída.\n";
    }

    if ($emailSucesso) {
        $sucesso_msg .= "\n[✓] O E-MAIL FOI ENVIADO para os destinatários cadastrados!";
    } else {
        $sucesso_msg .= "\n[x] ALERTA DE E-MAIL: O Excel foi criado e salvo no servidor, mas falhamos ao enviar o e-mail.\nErro: $emailErroMsg";
    }

    echo json_encode(['status' => 'success', 'message' => $sucesso_msg]);

} catch (Exception $e) {
    echo json_encode(['status' => 'error', 'message' => 'Erro Crítico no Servidor: ' . $e->getMessage()]);
}
?>