<?php

require_once __DIR__ . '/../../config/bootstrap.php';

use ControleFrotas\Config\Database;
use ControleFrotas\Utils\Response;
use ControleFrotas\Utils\Logger;

header('Content-Type: application/json');

// Verificar autenticação
$user = requireAuth();

switch ($_SERVER['REQUEST_METHOD']) {
    case 'POST':
        sincronizarViagensDoApp();
        break;
    case 'GET':
        obterViagensAtualizadas();
        break;
    case 'OPTIONS':
        http_response_code(200);
        break;
    default:
        Response::error('Método não permitido', 405);
}

/**
 * Sincroniza viagens enviadas do app para o servidor
 */
function sincronizarViagensDoApp(): void {
    global $user;
    
    $input = json_decode(file_get_contents('php://input'), true);
    
    if (!$input || !isset($input['viagens']) || !is_array($input['viagens'])) {
        Response::error('Dados de viagens são obrigatórios', 400);
    }

    $viagens = $input['viagens'];
    $processadas = 0;
    $erros = [];

    try {
        Database::beginTransaction();

        foreach ($viagens as $index => $viagemData) {
            try {
                processarViagem($viagemData, $user['user_id']);
                $processadas++;
            } catch (Exception $e) {
                $erros[] = [
                    'index' => $index,
                    'error' => $e->getMessage(),
                    'viagem_id' => $viagemData['id'] ?? 'unknown'
                ];
                Logger::error('Erro ao processar viagem na sincronização', [
                    'viagem_data' => $viagemData,
                    'error' => $e->getMessage(),
                    'user_id' => $user['user_id']
                ]);
            }
        }

        Database::commit();

        Logger::syncOperation('viagens', $processadas, empty($erros));

        $response = [
            'message' => 'Sincronização concluída',
            'processadas' => $processadas,
            'total' => count($viagens)
        ];

        if (!empty($erros)) {
            $response['erros'] = $erros;
        }

        Response::success($response);

    } catch (Exception $e) {
        Database::rollback();
        Logger::error('Erro na sincronização de viagens', [
            'error' => $e->getMessage(),
            'user_id' => $user['user_id']
        ]);
        Response::error('Erro na sincronização: ' . $e->getMessage(), 500);
    }
}

/**
 * Processa uma viagem individual
 */
function processarViagem(array $viagemData, string $userId): void {
    validateRequired($viagemData, ['id', 'tecnico_id', 'veiculo_id', 'cliente', 'motivo', 'km_inicial', 'data_inicio']);

    // Verificar se a viagem já existe
    $existente = Database::queryOne(
        "SELECT id, sincronizado FROM viagens WHERE id = ?",
        [$viagemData['id']]
    );

    if ($existente) {
        // Atualizar viagem existente
        atualizarViagem($viagemData);
    } else {
        // Inserir nova viagem
        inserirViagem($viagemData);
    }

    // Processar trajeto se existir
    if (!empty($viagemData['trajeto']) && is_array($viagemData['trajeto'])) {
        processarTrajeto($viagemData['id'], $viagemData['trajeto']);
    }
}

/**
 * Insere uma nova viagem
 */
function inserirViagem(array $data): void {
    $sql = "INSERT INTO viagens (
        id, tecnico_id, veiculo_id, cliente, motivo, km_inicial, km_final, km_gps_final,
        data_inicio, data_fim, latitude_inicial, longitude_inicial, latitude_final,
        longitude_final, observacoes, justificativa_divergencia, sincronizado, trajeto
    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)";

    $trajeto = !empty($data['trajeto']) ? json_encode($data['trajeto']) : null;

    Database::execute($sql, [
        $data['id'],
        $data['tecnico_id'],
        $data['veiculo_id'],
        $data['cliente'],
        $data['motivo'],
        $data['km_inicial'],
        $data['km_final'] ?? null,
        $data['km_gps_final'] ?? null,
        $data['data_inicio'],
        $data['data_fim'] ?? null,
        $data['latitude_inicial'] ?? null,
        $data['longitude_inicial'] ?? null,
        $data['latitude_final'] ?? null,
        $data['longitude_final'] ?? null,
        $data['observacoes'] ?? null,
        $data['justificativa_divergencia'] ?? null,
        $trajeto
    ]);

    Logger::databaseOperation('insert', 'viagens', ['id' => $data['id']]);
}

/**
 * Atualiza uma viagem existente
 */
function atualizarViagem(array $data): void {
    $sql = "UPDATE viagens SET 
        tecnico_id = ?, veiculo_id = ?, cliente = ?, motivo = ?, km_inicial = ?,
        km_final = ?, km_gps_final = ?, data_inicio = ?, data_fim = ?,
        latitude_inicial = ?, longitude_inicial = ?, latitude_final = ?,
        longitude_final = ?, observacoes = ?, justificativa_divergencia = ?, sincronizado = 1, trajeto = ?,
        updated_at = NOW()
        WHERE id = ?";

    $trajeto = !empty($data['trajeto']) ? json_encode($data['trajeto']) : null;

    Database::execute($sql, [
        $data['tecnico_id'],
        $data['veiculo_id'],
        $data['cliente'],
        $data['motivo'],
        $data['km_inicial'],
        $data['km_final'] ?? null,
        $data['km_gps_final'] ?? null,
        $data['data_inicio'],
        $data['data_fim'] ?? null,
        $data['latitude_inicial'] ?? null,
        $data['longitude_inicial'] ?? null,
        $data['latitude_final'] ?? null,
        $data['longitude_final'] ?? null,
        $data['observacoes'] ?? null,
        $data['justificativa_divergencia'] ?? null,
        $trajeto,
        $data['id']
    ]);

    Logger::databaseOperation('update', 'viagens', ['id' => $data['id']]);
}

/**
 * Processa trajeto detalhado
 */
function processarTrajeto(int $viagemId, array $trajeto): void {
    // Remover pontos existentes
    Database::execute("DELETE FROM trajeto_pontos WHERE viagem_id = ?", [$viagemId]);

    // Inserir novos pontos
    $sql = "INSERT INTO trajeto_pontos (viagem_id, latitude, longitude, timestamp_ponto, velocidade, precisao) 
            VALUES (?, ?, ?, ?, ?, ?)";

    foreach ($trajeto as $ponto) {
        if (isset($ponto['latitude']) && isset($ponto['longitude'])) {
            Database::execute($sql, [
                $viagemId,
                $ponto['latitude'],
                $ponto['longitude'],
                $ponto['timestamp'] ?? date('Y-m-d H:i:s'),
                $ponto['velocidade'] ?? null,
                $ponto['precisao'] ?? null
            ]);
        }
    }
}

/**
 * Obtém viagens atualizadas para sincronização
 */
function obterViagensAtualizadas(): void {
    global $user;

    $ultimaSync = $_GET['ultima_sync'] ?? null;
    $tecnicoId = $_GET['tecnico_id'] ?? $user['user_id'];

    $whereConditions = ['tecnico_id = ?'];
    $params = [$tecnicoId];

    if ($ultimaSync) {
        $whereConditions[] = 'updated_at > ?';
        $params[] = $ultimaSync;
    }

    $sql = "SELECT 
        v.*,
        u.nome as tecnico_nome,
        ve.modelo as veiculo_modelo,
        ve.placa as veiculo_placa
        FROM viagens v
        LEFT JOIN usuarios u ON v.tecnico_id = u.id
        LEFT JOIN veiculos ve ON v.veiculo_id = ve.id
        WHERE " . implode(' AND ', $whereConditions) . "
        ORDER BY v.updated_at DESC
        LIMIT 100";

    $viagens = Database::queryAll($sql, $params);

    // Adicionar trajeto detalhado para cada viagem
    foreach ($viagens as &$viagem) {
        $trajeto = Database::queryAll(
            "SELECT latitude, longitude, timestamp_ponto, velocidade, precisao 
             FROM trajeto_pontos 
             WHERE viagem_id = ? 
             ORDER BY timestamp_ponto",
            [$viagem['id']]
        );
        
        $viagem['trajeto_detalhado'] = $trajeto;
        
        // Decodificar trajeto JSON se existir
        if ($viagem['trajeto']) {
            $viagem['trajeto'] = json_decode($viagem['trajeto'], true);
        }
    }

    Response::success([
        'viagens' => $viagens,
        'total' => count($viagens),
        'ultima_atualizacao' => date('Y-m-d H:i:s')
    ]);
} 
