/**
 * Portage de apps/content/views.py + urls.py (DRF ReadOnlyModelViewSet).
 * Mêmes chemins, même forme de réponse que l'API Django : le frontend
 * (lib/api.ts) n'a rien à changer.
 *
 * Toutes les listes renvoient un tableau simple (pas d'enveloppe de
 * pagination) : lib/api.ts gère déjà les deux cas
 * (`articles.results || articles || []`), donc c'est la forme la plus
 * simple qui reste 100% compatible.
 */
const express = require("express");
const router = express.Router();
const { Op } = require("sequelize");
const {
  Category, Page, Article, Event, Document, FAQ, ContactMessage,
  Stat, Partner, Person, ImportantLink, GalleryImage, Testimonial, HeroSlide,
} = require("../models");
const { localize, localizeList } = require("../utils/translate");
const { sendContactNotifications } = require("../services/emailService");

const notFound = (res) => res.status(404).json({ detail: "Not found." });

// --- /categories/ -----------------------------------------------------
router.get("/categories/", async (req, res) => {
  const items = await Category.findAll({ order: [["name_fr", "ASC"]] });
  res.json(localizeList(items, ["name"], req.lang));
});

// --- /pages/ ------------------------------------------------------------
router.get("/pages/", async (req, res) => {
  const items = await Page.findAll({
    where: { is_published: true },
    order: [["order", "ASC"], ["title_fr", "ASC"]],
  });
  res.json(localizeList(items, ["title", "body"], req.lang));
});

router.get("/pages/:slug/", async (req, res) => {
  const item = await Page.findOne({ where: { slug: req.params.slug, is_published: true } });
  if (!item) return notFound(res);
  res.json(localize(item, ["title", "body"], req.lang));
});

// --- /articles/ -----------------------------------------------------------
// Champs filtrables : category__slug, is_featured (DjangoFilterBackend)
router.get("/articles/", async (req, res) => {
  const where = { is_published: true };
  if (req.query.is_featured !== undefined) {
    where.is_featured = req.query.is_featured === "true";
  }
  const include = [{ model: Category, as: "category" }];
  if (req.query["category__slug"]) {
    include[0].where = { slug: req.query["category__slug"] };
  }

  const items = await Article.findAll({
    where,
    include,
    order: [["published_at", "DESC"], ["created_at", "DESC"]],
  });

  // Liste : pas de "body" (équivalent ArticleListSerializer)
  const data = items.map((item) => {
    const localized = localize(item, ["title", "excerpt"], req.lang);
    delete localized.body_fr;
    delete localized.body_en;
    localized.category = item.category ? localize(item.category, ["name"], req.lang) : null;
    return localized;
  });
  res.json(data);
});

router.get("/articles/:slug/", async (req, res) => {
  const item = await Article.findOne({
    where: { slug: req.params.slug, is_published: true },
    include: [{ model: Category, as: "category" }],
  });
  if (!item) return notFound(res);
  const localized = localize(item, ["title", "excerpt", "body"], req.lang);
  localized.category = item.category ? localize(item.category, ["name"], req.lang) : null;
  res.json(localized);
});

// --- /events/ ---------------------------------------------------------
router.get("/events/", async (req, res) => {
  const items = await Event.findAll({
    where: { is_published: true },
    order: [["start_date", "ASC"]],
  });
  const data = items.map((item) => {
    const localized = localize(item, ["title", "description", "location", "theme"], req.lang);
    localized.status = item.status;
    return localized;
  });
  res.json(data);
});

router.get("/events/:slug/", async (req, res) => {
  const item = await Event.findOne({ where: { slug: req.params.slug, is_published: true } });
  if (!item) return notFound(res);
  const localized = localize(item, ["title", "description", "location", "theme"], req.lang);
  localized.status = item.status;
  res.json(localized);
});

// --- /documents/ ------------------------------------------------------
router.get("/documents/", async (req, res) => {
  const items = await Document.findAll({ where: { is_public: true }, order: [["created_at", "DESC"]] });
  res.json(items.map((i) => i.toJSON()));
});

// --- /faq/ ------------------------------------------------------------
router.get("/faq/", async (req, res) => {
  const items = await FAQ.findAll({ order: [["order", "ASC"]] });
  res.json(localizeList(items, ["question", "answer"], req.lang));
});

// --- /stats/ ------------------------------------------------------------
router.get("/stats/", async (req, res) => {
  const items = await Stat.findAll({ order: [["order", "ASC"]] });
  res.json(localizeList(items, ["label"], req.lang));
});

// --- /partners/ -------------------------------------------------------
router.get("/partners/", async (req, res) => {
  const where = {};
  if (req.query.partner_type) where.partner_type = req.query.partner_type;
  const items = await Partner.findAll({ where, order: [["order", "ASC"], ["name", "ASC"]] });
  res.json(items.map((i) => i.toJSON()));
});

// --- /people/ -----------------------------------------------------------
router.get("/people/", async (req, res) => {
  const where = {};
  if (req.query.role_type) where.role_type = req.query.role_type;
  if (req.query.event) where.event_id = req.query.event;
  const items = await Person.findAll({ where, order: [["order", "ASC"], ["full_name", "ASC"]] });
  res.json(localizeList(items, ["title", "bio"], req.lang));
});

// --- /important-links/ -------------------------------------------------
router.get("/important-links/", async (req, res) => {
  const items = await ImportantLink.findAll({ order: [["order", "ASC"]] });
  res.json(localizeList(items, ["label"], req.lang));
});

// --- /gallery/ ----------------------------------------------------------
router.get("/gallery/", async (req, res) => {
  const where = {};
  if (req.query.event) where.event_id = req.query.event;
  const items = await GalleryImage.findAll({
    where,
    include: [{ model: Event, as: "event" }],
    order: [["order", "ASC"], ["created_at", "DESC"]],
  });
  const data = items.map((item) => {
    const localized = localize(item, ["caption"], req.lang);
    localized.event_title = item.event ? item.event.title_fr : null;
    localized.event_date = item.event ? item.event.start_date : null;
    delete localized.event;
    return localized;
  });
  res.json(data);
});

// --- /testimonials/ ------------------------------------------------------
router.get("/testimonials/", async (req, res) => {
  const items = await Testimonial.findAll({
    where: { is_published: true },
    order: [["order", "ASC"], ["created_at", "DESC"]],
  });
  res.json(localizeList(items, ["quote", "author_role"], req.lang));
});

// --- /hero-slides/ -------------------------------------------------------
router.get("/hero-slides/", async (req, res) => {
  const items = await HeroSlide.findAll({
    where: { is_published: true },
    order: [["order", "ASC"], ["created_at", "DESC"]],
  });
  res.json(items.map((i) => i.toJSON()));
});

// --- /contact/ (écriture seule côté public) -----------------------------
router.post("/contact/", async (req, res) => {
  const { name, email, subject, message, language } = req.body || {};
  if (!name || !email || !message) {
    return res.status(400).json({ detail: "name, email et message sont requis." });
  }
  const contactMessage = await ContactMessage.create({
    name, email, subject: subject || "", message,
    language: language === "en" ? "en" : "fr",
  });

  try {
    await sendContactNotifications(contactMessage);
  } catch (err) {
    // On ne fait pas échouer la requête si l'envoi d'email échoue (le
    // message reste bien enregistré) — même logique que la vue Django.
    // eslint-disable-next-line no-console
    console.error("Échec de l'envoi des emails de contact :", err.message);
  }

  res.status(201).json({
    id: contactMessage.id,
    name: contactMessage.name,
    email: contactMessage.email,
    subject: contactMessage.subject,
    message: contactMessage.message,
    language: contactMessage.language,
  });
});

module.exports = router;
