/**
 * controllers/calendar.controller.js
 */

const db = require("../db");
const Holidays = require("date-holidays");

// ── Hilfsfunktionen ──────────────────────────────────────────────────────────

function pad(n) {
  return String(n).padStart(2, "0");
}

function toISO(d) {
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
}

// ── Hauptseite (EJS rendern) ─────────────────────────────────────────────────

exports.index = async (req, res) => {
  try {
    // Alle aktiven Ärzte (users mit role = 'arzt')
    const [doctors] = await db.promise().query(`
      SELECT id, username AS name, doctor_color AS color
      FROM users
      WHERE role = 'arzt' AND active = 1
      ORDER BY username
    `);

    const today = toISO(new Date());

    return res.render("calendar/index", {
      active: "calendar",
      doctors,
      today,
      user: req.session.user,
    });
  } catch (err) {
    console.error("❌ calendar.index:", err.message);
    return res.status(500).send("Interner Serverfehler");
  }
};

// ── API: Termine eines Tages ─────────────────────────────────────────────────

exports.getAppointments = async (req, res) => {
  try {
    const { date } = req.params; // YYYY-MM-DD

    const [rows] = await db.promise().query(
      `SELECT
         a.id, a.doctor_id, a.date,
         TIME_FORMAT(a.time, '%H:%i') AS time,
         a.duration, a.patient_name, a.notes, a.status,
         u.username         AS doctor_name,
         u.doctor_color     AS doctor_color
       FROM appointments a
       JOIN users u ON u.id = a.doctor_id
       WHERE a.date = ?
       ORDER BY a.time, u.username`,
      [date]
    );

    return res.json(rows);
  } catch (err) {
    console.error("❌ getAppointments:", err.message);
    return res.status(500).json({ error: "Datenbankfehler" });
  }
};

// ── API: Termin erstellen ────────────────────────────────────────────────────

exports.createAppointment = async (req, res) => {
  try {
    const { doctor_id, date, time, duration = 15, patient_name, notes = "" } =
      req.body;

    if (!doctor_id || !date || !time || !patient_name?.trim()) {
      return res
        .status(400)
        .json({ error: "doctor_id, date, time und patient_name sind Pflicht" });
    }

    // Kollisionsprüfung
    const [conflict] = await db.promise().query(
      `SELECT id FROM appointments
       WHERE doctor_id = ? AND date = ? AND time = ? AND status != 'cancelled'`,
      [doctor_id, date, time]
    );

    if (conflict.length > 0) {
      return res.status(409).json({ error: "Dieser Zeitslot ist bereits belegt" });
    }

    const [result] = await db.promise().query(
      `INSERT INTO appointments (doctor_id, date, time, duration, patient_name, notes)
       VALUES (?, ?, ?, ?, ?, ?)`,
      [doctor_id, date, time, duration, patient_name.trim(), notes]
    );

    return res.status(201).json({ id: result.insertId });
  } catch (err) {
    console.error("❌ createAppointment:", err.message);
    return res.status(500).json({ error: "Datenbankfehler" });
  }
};

// ── API: Termin aktualisieren ────────────────────────────────────────────────

exports.updateAppointment = async (req, res) => {
  try {
    const { id } = req.params;
    const { doctor_id, date, time, duration, patient_name, notes, status } =
      req.body;

    await db.promise().query(
      `UPDATE appointments
       SET doctor_id = ?, date = ?, time = ?, duration = ?,
           patient_name = ?, notes = ?, status = ?
       WHERE id = ?`,
      [doctor_id, date, time, duration, patient_name, notes, status, id]
    );

    return res.json({ success: true });
  } catch (err) {
    console.error("❌ updateAppointment:", err.message);
    return res.status(500).json({ error: "Datenbankfehler" });
  }
};

// ── API: Termin löschen ──────────────────────────────────────────────────────

exports.deleteAppointment = async (req, res) => {
  try {
    await db.promise().query("DELETE FROM appointments WHERE id = ?", [
      req.params.id,
    ]);
    return res.json({ success: true });
  } catch (err) {
    console.error("❌ deleteAppointment:", err.message);
    return res.status(500).json({ error: "Datenbankfehler" });
  }
};

// ── API: Status ändern ───────────────────────────────────────────────────────

exports.patchStatus = async (req, res) => {
  try {
    const allowed = ["scheduled", "completed", "cancelled"];
    const { status } = req.body;

    if (!allowed.includes(status)) {
      return res.status(400).json({ error: "Ungültiger Status" });
    }

    await db
      .promise()
      .query("UPDATE appointments SET status = ? WHERE id = ?", [
        status,
        req.params.id,
      ]);

    return res.json({ success: true });
  } catch (err) {
    console.error("❌ patchStatus:", err.message);
    return res.status(500).json({ error: "Datenbankfehler" });
  }
};

// ── API: Feiertage eines Jahres ──────────────────────────────────────────────

exports.getHolidays = (req, res) => {
  try {
    const year    = parseInt(req.params.year);
    const country = (req.query.country || process.env.HOLIDAY_COUNTRY || "DE").toUpperCase();
    const state   = (req.query.state   || process.env.HOLIDAY_STATE   || "").toUpperCase();

    if (isNaN(year) || year < 1900 || year > 2100) {
      return res.status(400).json({ error: "Ungültiges Jahr" });
    }

    const hd     = new Holidays();
    const inited = state ? hd.init(country, state) : hd.init(country);

    if (!inited) {
      return res.status(400).json({ error: `Unbekanntes Land/Bundesland: ${country}/${state}` });
    }

    const holidays = hd
      .getHolidays(year)
      .filter((h) => ["public", "bank"].includes(h.type))
      .map((h) => ({
        date: h.date.substring(0, 10),
        name: h.name,
        type: h.type,
      }));

    return res.json({ country, state, year, holidays });
  } catch (err) {
    console.error("❌ getHolidays:", err.message);
    return res.status(500).json({ error: "Fehler beim Laden der Feiertage" });
  }
};

// ── API: Patienten-Suche (Autocomplete) ─────────────────────────────────────

exports.searchPatients = async (req, res) => {
  try {
    const q = (req.query.q || "").trim();

    if (q.length < 1) return res.json([]);

    const like = `%${q}%`;

    const [rows] = await db.promise().query(
      `SELECT
         id,
         firstname,
         lastname,
         birthdate,
         CONCAT(firstname, ' ', lastname) AS full_name
       FROM patients
       WHERE active = 1
         AND (
           firstname  LIKE ? OR
           lastname   LIKE ? OR
           CONCAT(firstname, ' ', lastname) LIKE ?
         )
       ORDER BY lastname, firstname
       LIMIT 10`,
      [like, like, like]
    );

    return res.json(rows);
  } catch (err) {
    console.error("❌ searchPatients:", err.message);
    return res.status(500).json({ error: "Datenbankfehler" });
  }
};

// ── API: Arzt-Farbe speichern ────────────────────────────────────────────────

exports.updateDoctorColor = async (req, res) => {
  try {
    const { color } = req.body;
    await db
      .promise()
      .query("UPDATE users SET doctor_color = ? WHERE id = ?", [
        color,
        req.params.id,
      ]);
    return res.json({ success: true });
  } catch (err) {
    console.error("❌ updateDoctorColor:", err.message);
    return res.status(500).json({ error: "Datenbankfehler" });
  }
};
