const express = require("express");
const mysql = require("mysql2");

const app = express();
const PORT = 3000;
app.use(express.json());

// ============================
// DB CONFIG
// ============================
const dbConfig = {
  host: "db",          // docker service name
  user: "leman",
  password: "leman123",
  database: "air_quality"
};

let db;

// ============================
// CONNECT WITH RETRY
// ============================
function connectDB() {
  db = mysql.createConnection(dbConfig);

  db.connect(err => {
    if (err) {
      console.error("❌ DB connection failed:", err.message);
      console.log("🔄 Retrying in 5 seconds...");
      setTimeout(connectDB, 5000);
    } else {
      console.log("✅ Connected to MariaDB");
    }
  });

  db.on("error", err => {
    console.error("⚠️ DB error:", err.message);

    if (err.code === "PROTOCOL_CONNECTION_LOST") {
      console.log("🔄 Reconnecting...");
      connectDB();
    } else {
      throw err;
    }
  });
}

connectDB();

// ============================
// ROOT CHECK
// ============================
app.get("/", (req, res) => {
  res.send("API is running 🚀");
});

// ============================
// GET LATEST DATA
// ============================
app.get("/data", (req, res) => {
  const sql = `
    SELECT * FROM air_data
    ORDER BY updated_at DESC
    LIMIT 1
  `;

  db.query(sql, (err, results) => {
    if (err) {
      console.error(err);
      return res.status(500).json({ error: "DB error" });
    }

    res.json(results[0] || {});
  });
});

// ============================
// INSERT DATA
// ============================
app.get("/update", (req, res) => {
  const { co2, co, bz, aq, id } = req.query;

  if (!co2 || !co || !bz || !aq || !id) {
    return res.status(400).json({
      error: "Parameter wajib: co2, co, bz, aq, id"
    });
  }

  const sql = `
    INSERT INTO air_data (co2, co, bz, aq, id)
    VALUES (?, ?, ?, ?, ?)
  `;

  db.query(
    sql,
    [
      Number(co2),
      Number(co),
      Number(bz),
      Number(aq),
      String(id)   // sensor id
    ],
    (err, result) => {
      if (err) {
        console.error(err);
        return res.status(500).json({ error: "DB error" });
      }

      res.json({
        message: "Data berhasil disimpan",
        insertId: result.insertId
      });
    }
  );
});

app.get("/sensordata/:id", (req, res) => {
  const sensorId = req.params.id;

  const sql = `
    SELECT 
      air_data.co2,
      air_data.co,
      air_data.bz,
      air_data.aq,
      air_data.updated_at,

      sensor_data.alamat,

      kelurahan.nama AS kelurahan,
      kecamatan.nama AS kecamatan

    FROM air_data

    JOIN sensor_data 
      ON air_data.id = sensor_data.id

    JOIN kelurahan 
      ON sensor_data.kelurahan = kelurahan.id

    JOIN kecamatan 
      ON kelurahan.kecamatan_id = kecamatan.id

    WHERE air_data.id = ?
    ORDER BY air_data.updated_at DESC
    LIMIT 1
  `;

  db.query(sql, [sensorId], (err, results) => {
    if (err) {
      console.error(err);
      return res.status(500).json({ error: "DB error" });
    }

    if (results.length === 0) {
      return res.status(404).json({
        error: "Sensor not found"
      });
    }

    res.json(results[0]);
  });
});

app.get("/sensors", (req, res) => {
  const sql = `SELECT id FROM sensor_data ORDER BY id ASC`;

  db.query(sql, (err, results) => {
    if (err) {
      return res.status(500).json({ error: "DB error" });
    }

    res.json(results);
  });
});

// ============================
// ADD SENSOR
// ============================
app.post("/addSensor", (req, res) => {
  const { kelurahan, alamat } = req.body;

  // ============================
  // VALIDATION
  // ============================
  if (!kelurahan || !alamat) {
    return res.status(400).json({
      error: "kelurahan dan alamat wajib diisi"
    });
  }

  // ============================
  // VALIDATE KELURAHAN EXISTS
  // ============================
  const checkSql = `SELECT id FROM kelurahan WHERE id = ?`;

  db.query(checkSql, [kelurahan], (err, rows) => {
    if (err) {
      console.error(err);
      return res.status(500).json({ error: "DB error" });
    }

    if (rows.length === 0) {
      return res.status(400).json({
        error: "Kelurahan tidak valid"
      });
    }

    // ============================
    // INSERT SENSOR
    // ============================
    const insertSql = `
      INSERT INTO sensor_data (kelurahan, alamat)
      VALUES (?, ?)
    `;

    db.query(insertSql, [kelurahan, alamat], (err, result) => {
      if (err) {
        console.error(err);
        return res.status(500).json({
          error: "DB error saat insert"
        });
      }

      res.json({
        message: "Sensor berhasil ditambahkan",
        sensor_id: result.insertId
      });
    });
  });
});

// ============================
// GET ALL DATA (OPTIONAL)
// ============================
app.get("/history", (req, res) => {
  const sql = `
    SELECT * FROM air_data
    ORDER BY updated_at DESC
    LIMIT 100
  `;

  db.query(sql, (err, results) => {
    if (err) {
      return res.status(500).json({ error: "DB error" });
    }

    res.json(results);
  });
});



// get kecamatan
app.get("/kecamatan", (req, res) => {
  const sql = `SELECT id, nama FROM kecamatan ORDER BY nama ASC`;

  db.query(sql, (err, results) => {
    if (err) {
      console.error(err);
      return res.status(500).json({ error: "DB error" });
    }

    res.json(results);
  });
});


// get kelurahan by kecamatan_id
app.get("/kelurahan", (req, res) => {
  const { kecamatan_id } = req.query;

  let sql = `
    SELECT 
      kelurahan.id,
      kelurahan.nama,
      kecamatan.nama AS kecamatan
    FROM kelurahan
    JOIN kecamatan ON kelurahan.kecamatan_id = kecamatan.id
  `;

  let params = [];

  if (kecamatan_id) {
    sql += ` WHERE kelurahan.kecamatan_id = ?`;
    params.push(kecamatan_id);
  }

  sql += ` ORDER BY kelurahan.nama ASC`;

  db.query(sql, params, (err, results) => {
    if (err) {
      console.error(err);
      return res.status(500).json({ error: "DB error" });
    }

    res.json(results);
  });
});

// ============================
// START SERVER
// ============================
app.listen(PORT, () => {
  console.log(`🚀 API running on port ${PORT}`);
});