const express = require("express");
const mysql = require("mysql2/promise");
const cors = require("cors");
const bodyParser = require("body-parser");
require("dotenv").config();

const app = express();
const PORT = process.env.PORT || 3000;

// Middlewares
app.use(cors());
app.use(bodyParser.json({ limit: "50mb" }));
app.use(bodyParser.urlencoded({ extended: true, limit: "50mb" }));
app.use(express.static("public"));

// Configuração do pool de conexões MySQL
const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  port: process.env.DB_PORT || 3306,
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0,
});

// Função para converter data do formato brasileiro para MySQL
function converterDataBrasileira(dataStr) {
  // Formato: DD/MM/YYYY HH:MM:SS
  const [datePart, timePart] = dataStr.split(" ");
  const [dia, mes, ano] = datePart.split("/");
  return `${ano}-${mes}-${dia} ${timePart}`;
}

// Rota principal
app.get("/", (req, res) => {
  res.sendFile(__dirname + "/public/index.html");
});

// Rota para receber dados dos veículos (API)
app.post("/api/veiculos", async (req, res) => {
  try {
    const { timestamp, total_veiculos, veiculos } = req.body;

    if (!veiculos || !Array.isArray(veiculos)) {
      return res.status(400).json({
        sucesso: false,
        mensagem: "Dados inválidos. É necessário enviar um array de veículos.",
      });
    }

    const connection = await pool.getConnection();

    try {
      await connection.beginTransaction();

      // Registrar atualização
      await connection.execute(
        "INSERT INTO atualizacoes (timestamp, total_veiculos) VALUES (?, ?)",
        [timestamp || new Date(), total_veiculos || veiculos.length],
      );

      // Inserir ou atualizar veículos
      for (const veiculo of veiculos) {
        const gruposStr = Array.isArray(veiculo.grupos)
          ? veiculo.grupos.join(",")
          : veiculo.grupos || "";

        const dataHoraMySQL = converterDataBrasileira(veiculo.data_hora);

        await connection.execute(
          `
                    INSERT INTO veiculos 
                    (placa, identificacao_completa, data_hora, icone, velocidade, status, 
                     endereco, latitude, longitude, grupos, modelo_rastreador, id_sistema, operadora)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                    ON DUPLICATE KEY UPDATE
                        identificacao_completa = VALUES(identificacao_completa),
                        data_hora = VALUES(data_hora),
                        icone = VALUES(icone),
                        velocidade = VALUES(velocidade),
                        status = VALUES(status),
                        endereco = VALUES(endereco),
                        latitude = VALUES(latitude),
                        longitude = VALUES(longitude),
                        grupos = VALUES(grupos),
                        modelo_rastreador = VALUES(modelo_rastreador),
                        id_sistema = VALUES(id_sistema),
                        operadora = VALUES(operadora)
                `,
          [
            veiculo.placa,
            veiculo.identificacao_completa,
            dataHoraMySQL,
            veiculo.icone,
            veiculo.velocidade,
            veiculo.status,
            veiculo.endereco,
            veiculo.latitude,
            veiculo.longitude,
            gruposStr,
            veiculo.modelo_rastreador,
            veiculo.id_sistema,
            veiculo.operadora,
          ],
        );
      }

      await connection.commit();

      res.json({
        sucesso: true,
        mensagem: `${veiculos.length} veículos processados com sucesso`,
        total: veiculos.length,
      });
    } catch (error) {
      await connection.rollback();
      throw error;
    } finally {
      connection.release();
    }
  } catch (error) {
    console.error("Erro ao processar veículos:", error);
    res.status(500).json({
      sucesso: false,
      mensagem: "Erro ao processar dados dos veículos",
      erro: error.message,
    });
  }
});

// Rota para obter todos os veículos
app.get("/api/veiculos", async (req, res) => {
  try {
    const [veiculos] = await pool.execute(`
            SELECT * FROM veiculos ORDER BY data_hora DESC
        `);

    // Converter grupos de volta para array
    const veiculosFormatados = veiculos.map((v) => ({
      ...v,
      grupos: v.grupos ? v.grupos.split(",") : [],
      latitude: parseFloat(v.latitude),
      longitude: parseFloat(v.longitude),
    }));

    // Buscar última atualização
    const [ultimaAtualizacao] = await pool.execute(`
            SELECT timestamp, total_veiculos 
            FROM atualizacoes 
            ORDER BY criado_em DESC 
            LIMIT 1
        `);

    res.json({
      sucesso: true,
      timestamp: ultimaAtualizacao[0]?.timestamp || new Date(),
      total_veiculos: veiculosFormatados.length,
      veiculos: veiculosFormatados,
    });
  } catch (error) {
    console.error("Erro ao buscar veículos:", error);
    res.status(500).json({
      sucesso: false,
      mensagem: "Erro ao buscar veículos",
      erro: error.message,
    });
  }
});

// Rota para buscar veículo por placa
app.get("/api/veiculos/:placa", async (req, res) => {
  try {
    const { placa } = req.params;

    const [veiculos] = await pool.execute(
      "SELECT * FROM veiculos WHERE placa = ?",
      [placa],
    );

    if (veiculos.length === 0) {
      return res.status(404).json({
        sucesso: false,
        mensagem: "Veículo não encontrado",
      });
    }

    const veiculo = veiculos[0];
    veiculo.grupos = veiculo.grupos ? veiculo.grupos.split(",") : [];
    veiculo.latitude = parseFloat(veiculo.latitude);
    veiculo.longitude = parseFloat(veiculo.longitude);

    res.json({
      sucesso: true,
      veiculo,
    });
  } catch (error) {
    console.error("Erro ao buscar veículo:", error);
    res.status(500).json({
      sucesso: false,
      mensagem: "Erro ao buscar veículo",
      erro: error.message,
    });
  }
});

// Testar conexão com o banco de dados
pool
  .getConnection()
  .then((connection) => {
    console.log("✓ Conectado ao MySQL com sucesso!");
    connection.release();

    // Iniciar servidor
    app.listen(PORT, () => {
      console.log(`✓ Servidor rodando na porta ${PORT}`);
      console.log(`✓ Acesse: http://localhost:${PORT}`);
    });
  })
  .catch((err) => {
    console.error("✗ Erro ao conectar ao MySQL:", err.message);
    console.error("  Verifique as configurações no arquivo .env");
    process.exit(1);
  });
