const db = require("../db");
const bcrypt = require("bcrypt");
const {
  createUser,
  getAllUsers,
  updateUserById,
} = require("../services/admin.service");

async function listUsers(req, res) {
  const { q } = req.query;

  try {
    let users;

    if (q) {
      users = await getAllUsers(db, q);
    } else {
      users = await getAllUsers(db);
    }

    res.render("admin_users", {
      title: "Benutzer",
      sidebarPartial: "partials/admin-sidebar",
      active: "users",

      user: req.session.user,
      lang: req.session.lang || "de",

      users,
      currentUser: req.session.user,
      query: { q },
    });
  } catch (err) {
    console.error(err);
    res.send("Datenbankfehler");
  }
}

function showCreateUser(req, res) {
  res.render("admin_create_user", {
    error: null,
    user: req.session.user,
  });
}

async function postCreateUser(req, res) {
  let {
    title,
    first_name,
    last_name,
    username,
    password,
    role,
    fachrichtung,
    arztnummer,
  } = req.body;

  title = title?.trim();
  first_name = first_name?.trim();
  last_name = last_name?.trim();
  username = username?.trim();
  fachrichtung = fachrichtung?.trim();
  arztnummer = arztnummer?.trim();

  // 🔴 Grundvalidierung
  if (!first_name || !last_name || !username || !password || !role) {
    return res.render("admin_create_user", {
      error: "Alle Pflichtfelder müssen ausgefüllt sein",
      user: req.session.user,
    });
  }

  // 🔴 Arzt-spezifische Validierung
  if (role === "arzt") {
    if (!fachrichtung || !arztnummer) {
      return res.render("admin_create_user", {
        error: "Für Ärzte sind Fachrichtung und Arztnummer Pflicht",
        user: req.session.user,
      });
    }
  } else {
    // Sicherheit: Mitarbeiter dürfen keine Arzt-Daten haben
    fachrichtung = null;
    arztnummer = null;
    title = null;
  }

  try {
    await createUser(
      db,
      title,
      first_name,
      last_name,
      username,
      password,
      role,
      fachrichtung,
      arztnummer,
    );

    req.session.flash = {
      type: "success",
      message: "Benutzer erfolgreich angelegt",
    };

    res.redirect("/admin/users");
  } catch (error) {
    res.render("admin_create_user", {
      error,
      user: req.session.user,
    });
  }
}

async function changeUserRole(req, res) {
  const userId = req.params.id;
  const { role } = req.body;

  if (!["arzt", "mitarbeiter"].includes(role)) {
    req.session.flash = { type: "danger", message: "Ungültige Rolle" };
    return res.redirect("/admin/users");
  }

  db.query("UPDATE users SET role = ? WHERE id = ?", [role, userId], (err) => {
    if (err) {
      console.error(err);
      req.session.flash = {
        type: "danger",
        message: "Fehler beim Ändern der Rolle",
      };
    } else {
      req.session.flash = {
        type: "success",
        message: "Rolle erfolgreich geändert",
      };
    }
    res.redirect("/admin/users");
  });
}

async function resetUserPassword(req, res) {
  const userId = req.params.id;
  const { password } = req.body;

  if (!password || password.length < 4) {
    req.session.flash = { type: "warning", message: "Passwort zu kurz" };
    return res.redirect("/admin/users");
  }

  const hash = await bcrypt.hash(password, 10);

  db.query(
    "UPDATE users SET password = ? WHERE id = ?",
    [hash, userId],
    (err) => {
      if (err) {
        console.error(err);
        req.session.flash = {
          type: "danger",
          message: "Fehler beim Zurücksetzen",
        };
      } else {
        req.session.flash = {
          type: "success",
          message: "Passwort zurückgesetzt",
        };
      }
      res.redirect("/admin/users");
    },
  );
}

function activateUser(req, res) {
  const userId = req.params.id;

  db.query("UPDATE users SET active = 1 WHERE id = ?", [userId], (err) => {
    if (err) {
      console.error(err);
      req.session.flash = {
        type: "danger",
        message: "Benutzer konnte nicht aktiviert werden",
      };
    } else {
      req.session.flash = {
        type: "success",
        message: "Benutzer wurde aktiviert",
      };
    }
    res.redirect("/admin/users");
  });
}

function deactivateUser(req, res) {
  const userId = req.params.id;

  db.query("UPDATE users SET active = 0 WHERE id = ?", [userId], (err) => {
    if (err) {
      console.error(err);
      req.session.flash = {
        type: "danger",
        message: "Benutzer konnte nicht deaktiviert werden",
      };
    } else {
      req.session.flash = {
        type: "success",
        message: "Benutzer wurde deaktiviert",
      };
    }
    res.redirect("/admin/users");
  });
}

async function showInvoiceOverview(req, res) {
  const search = req.query.q || "";
  const view = req.query.view || "year";
  const currentYear = new Date().getFullYear();
  const fromYear = req.query.fromYear || currentYear;
  const toYear = req.query.toYear || currentYear;

  try {
    const [yearly] = await db.promise().query(`
      SELECT 
        YEAR(invoice_date) AS year,
        SUM(total_amount) AS total
      FROM invoices
      WHERE status IN ('paid','open')
      GROUP BY YEAR(invoice_date)
      ORDER BY year DESC
    `);

    const [quarterly] = await db.promise().query(`
      SELECT 
        YEAR(invoice_date) AS year,
        QUARTER(invoice_date) AS quarter,
        SUM(total_amount) AS total
      FROM invoices
      WHERE status IN ('paid','open')
      GROUP BY YEAR(invoice_date), QUARTER(invoice_date)
      ORDER BY year DESC, quarter DESC
    `);

    const [monthly] = await db.promise().query(`
      SELECT 
        DATE_FORMAT(invoice_date, '%Y-%m') AS month,
        SUM(total_amount) AS total
      FROM invoices
      WHERE status IN ('paid','open')
      GROUP BY month
      ORDER BY month DESC
    `);

    const [patients] = await db.promise().query(
      `
      SELECT 
        CONCAT(p.firstname, ' ', p.lastname) AS patient,
        SUM(i.total_amount) AS total
      FROM invoices i
      JOIN patients p ON p.id = i.patient_id
      WHERE i.status IN ('paid','open')
        AND CONCAT(p.firstname, ' ', p.lastname) LIKE ?
      GROUP BY p.id
      ORDER BY total DESC
      `,
      [`%${search}%`],
    );

    res.render("admin/admin_invoice_overview", {
      title: "Rechnungsübersicht",
      sidebarPartial: "partials/admin-sidebar", // ✅ keine Sidebar
      active: "invoices",

      user: req.session.user,
      lang: req.session.lang || "de",

      yearly,
      quarterly,
      monthly,
      patients,
      search,
      fromYear,
      toYear,
    });
  } catch (err) {
    console.error(err);
    res.status(500).send("Fehler beim Laden der Rechnungsübersicht");
  }
}

async function updateUser(req, res) {
  const userId = req.params.id;

  let { title, first_name, last_name, username, role } = req.body;

  title = title?.trim() || null;
  first_name = first_name?.trim();
  last_name = last_name?.trim();
  username = username?.trim();
  role = role?.trim();

  try {
    // ✅ Fehlende Felder aus DB holen (weil disabled inputs nicht gesendet werden)
    const [rows] = await db
      .promise()
      .query("SELECT * FROM users WHERE id = ?", [userId]);

    if (!rows.length) {
      req.session.flash = { type: "danger", message: "User nicht gefunden" };
      return res.redirect("/admin/users");
    }

    const current = rows[0];

    // ✅ Fallback: wenn Felder nicht gesendet wurden -> alte Werte behalten
    const updatedData = {
      title: title ?? current.title,
      first_name: first_name ?? current.first_name,
      last_name: last_name ?? current.last_name,
      username: username ?? current.username,
      role: role ?? current.role,
    };

    await updateUserById(db, userId, updatedData);

    req.session.flash = { type: "success", message: "User aktualisiert ✅" };
    return res.redirect("/admin/users");
  } catch (err) {
    console.error(err);
    req.session.flash = { type: "danger", message: "Fehler beim Speichern" };
    return res.redirect("/admin/users");
  }
}

module.exports = {
  listUsers,
  showCreateUser,
  postCreateUser,
  changeUserRole,
  resetUserPassword,
  activateUser,
  deactivateUser,
  showInvoiceOverview,
  updateUser,
};
