import express from "express";
import fetch from "node-fetch";
import fs from "fs";
import "dotenv/config";

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

const PORT = process.env.PORT || 3000;
const SESSIONS_FILE = "./sessions.json";
const BOOKINGS_FILE = "./bookings.json";

// ---------------- HELPERS ----------------
const load = (f, d) => fs.existsSync(f) ? JSON.parse(fs.readFileSync(f)) : d;
const save = (f, d) => fs.writeFileSync(f, JSON.stringify(d, null, 2));

function calcCheckout(checkIn, nights) {
  const d = new Date(checkIn);
  d.setDate(d.getDate() + nights);
  return d.toISOString().split("T")[0];
}

async function sendText(to, text) {
  await fetch(
    `https://graph.facebook.com/v19.0/${process.env.PHONE_NUMBER_ID}/messages`,
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        messaging_product: "whatsapp",
        to,
        text: { body: text }
      })
    }
  );
}

async function sendButtons(to, text, buttons) {
  await fetch(
    `https://graph.facebook.com/v19.0/${process.env.PHONE_NUMBER_ID}/messages`,
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        messaging_product: "whatsapp",
        to,
        type: "interactive",
        interactive: {
          type: "button",
          body: { text },
          action: {
            buttons: buttons.map((b, i) => ({
              type: "reply",
              reply: { id: `btn_${i}`, title: b }
            }))
          }
        }
      })
    }
  );
}

// ---------------- WEBHOOK VERIFY ----------------
app.get("/webhook", (req, res) => {
  const mode = req.query["hub.mode"];
  const token = req.query["hub.verify_token"];
  const challenge = req.query["hub.challenge"];

  if (mode === "subscribe" && token === process.env.VERIFY_TOKEN) {
    return res.status(200).send(challenge);
  }
  res.sendStatus(403);
});

// ---------------- WEBHOOK RECEIVE ----------------
app.post("/webhook", async (req, res) => {
  const msg =
    req.body.entry?.[0]?.changes?.[0]?.value?.messages?.[0];

  if (!msg) return res.sendStatus(200);

  const from = msg.from;
  const text =
    msg.text?.body ||
    msg.interactive?.button_reply?.title;

  const sessions = load(SESSIONS_FILE, {});
  const bookings = load(BOOKINGS_FILE, []);

  if (!sessions[from]) {
    sessions[from] = { step: "ROOM", data: {} };
    save(SESSIONS_FILE, sessions);

    await sendButtons(from, "Welcome to Safari Lodge ???\nSelect room type:", [
      "Chalet",
      "Safari Tent",
      "Family Room"
    ]);
    return res.sendStatus(200);
  }

  const s = sessions[from];

  switch (s.step) {
    case "ROOM":
      s.data.room = text;
      s.step = "CHECKIN";
      await sendText(from, "Enter check-in date (YYYY-MM-DD)");
      break;

    case "CHECKIN":
      s.data.check_in = text;
      s.step = "NIGHTS";
      await sendButtons(from, "How many nights?", [
        "1", "2", "3", "4"
      ]);
      break;

    case "NIGHTS":
      s.data.nights = parseInt(text);
      s.data.check_out = calcCheckout(
        s.data.check_in,
        s.data.nights
      );
      s.step = "NAME";
      await sendText(from, "Enter full name for booking:");
      break;

    case "NAME":
      s.data.name = text;
      s.step = "CONFIRM";
      await sendButtons(
        from,
`Please confirm your booking:

?? ${s.data.name}
?? ${s.data.room}
?? Check-in: ${s.data.check_in}
?? Nights: ${s.data.nights}
?? Check-out: ${s.data.check_out}`,
        ["Confirm"]
      );
      break;

    case "CONFIRM":
      if (text === "Confirm") {
        bookings.push({
          phone: from,
          ...s.data
        });
        save(BOOKINGS_FILE, bookings);
        delete sessions[from];
        save(SESSIONS_FILE, sessions);

        await sendText(
          from,
          "? Booking received! We’ll contact you shortly."
        );
      }
      break;
  }

  save(SESSIONS_FILE, sessions);
  res.sendStatus(200);
});

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