// routes/admin.js
const express = require("express");
const router = express.Router();
const adminController = require("../controllers/adminController");
const { verifyToken } = require("../middlewares/auth");
const authorizeRoles = require("../middlewares/authorizeRoles");
const upload = require("../middlewares/upload");

// Protect all admin routes
router.use(verifyToken);
router.use(authorizeRoles("admin", "superuser"));

// --- Article Routes ---

// Publishers can create and update articles
router.post(
  "/articles",
  authorizeRoles("publisher", "admin", "superuser"),
  upload.single("headingImage"),
  adminController.addArticle
);

// Publishers and Admins can update articles
router.put(
  "/articles/:id",
  authorizeRoles("publisher", "admin", "superuser"),
  upload.single("headingImage"),
  adminController.updateArticle
);

// SuperUsers and Admins can delete any article
router.delete(
  "/articles/:id",
  authorizeRoles("admin", "superuser"),
  adminController.deleteArticle
);

// Reviewers can review articles
router.post(
  "/articles/:id/review",
  authorizeRoles("reviewer", "admin", "superuser"),
  adminController.reviewArticle
);

// Users can read articles
router.get(
  "/articles",
  authorizeRoles("user", "reviewer", "publisher", "admin", "superuser"),
  adminController.getAllArticles
);
router.get(
  "/articles/:id",
  authorizeRoles("user", "reviewer", "publisher", "admin", "superuser"),
  adminController.getArticleById
);

router.post(
  "/articles/:id/review",
  authorizeRoles("reviewer", "admin", "superuser"),
  adminController.reviewArticle
);
// --- News Routes ---

// Similar role-based access can be applied to news routes

module.exports = router;


// controllers/adminController.js
const Article = require("../models/Article");
const News = require("../models/News");
const { handleControllerError } = require("../utils/errorHandler");
const fs = require("fs");
const path = require("path");

// Helper function to delete files
const deleteFile = (filePath) => {
  fs.unlink(path.join(__dirname, "..", filePath), (err) => {
    if (err) console.error(`Failed to delete file ${filePath}:`, err);
  });
};

// --- Articles CRUD Operations ---

// Create a new article
const addArticle = async (req, res) => {
  try {
    const { title, content, author } = req.body;
    const headingImage = req.file ? `/uploads/${req.file.filename}` : null;

    if (!title || !content || !author) {
      return res.status(400).json({ message: "All fields are required." });
    }

    const newArticle = new Article({
      title,
      content,
      author,
      headingImage,
      createdBy: req.admin._id,
    });

    await newArticle.save();

    res.status(201).json({
      message: "Article created successfully.",
      article: newArticle,
    });
  } catch (error) {
    handleControllerError(error, res, "addArticle");
  }
};

// Get all articles
const getAllArticles = async (req, res) => {
  try {
    const articles = await Article.find()
      .populate("createdBy", "username")
      .sort({ createdAt: -1 });
    res.json(articles);
  } catch (error) {
    handleControllerError(error, res, "getAllArticles");
  }
};

// Get a single article by ID
const getArticleById = async (req, res) => {
  try {
    const { id } = req.params;
    const article = await Article.findById(id).populate(
      "createdBy",
      "username"
    );

    if (!article) {
      return res.status(404).json({ message: "Article not found." });
    }

    res.json(article);
  } catch (error) {
    handleControllerError(error, res, "getArticleById");
  }
};

// Update an existing article
const updateArticle = async (req, res) => {
  try {
    const { id } = req.params;
    const { title, content, author } = req.body;
    let headingImage;

    const article = await Article.findById(id);
    if (!article) {
      return res.status(404).json({ message: "Article not found." });
    }

    if (req.file) {
      // Delete the old image if it exists
      if (article.headingImage) {
        deleteFile(article.headingImage);
      }
      headingImage = `/uploads/${req.file.filename}`;
      article.headingImage = headingImage;
    }

    // Update fields if provided
    if (title) article.title = title;
    if (content) article.content = content;
    if (author) article.author = author;

    await article.save();

    res.json({ message: "Article updated successfully.", article });
  } catch (error) {
    handleControllerError(error, res, "updateArticle");
  }
};

// Delete an article
const deleteArticle = async (req, res) => {
  try {
    const { id } = req.params;

    const article = await Article.findByIdAndDelete(id);
    if (!article) {
      return res.status(404).json({ message: "Article not found." });
    }

    // Delete the heading image if it exists
    if (article.headingImage) {
      deleteFile(article.headingImage);
    }

    res.json({ message: "Article deleted successfully." });
  } catch (error) {
    handleControllerError(error, res, "deleteArticle");
  }
};

// --- News CRUD Operations ---

// Create a new news item
const addNews = async (req, res) => {
  try {
    const { title, content } = req.body;
    const headingImage = req.files["headingImage"]
      ? `/uploads/${req.files["headingImage"][0].filename}`
      : null;
    const images = req.files["images"]
      ? req.files["images"].map((file) => `/uploads/${file.filename}`)
      : [];

    if (!title || !content) {
      return res
        .status(400)
        .json({ message: "Title and content are required." });
    }

    const newNews = new News({
      title,
      content,
      headingImage,
      images,
      createdBy: req.admin._id,
    });

    await newNews.save();

    res.status(201).json({
      message: "News created successfully.",
      news: newNews,
    });
  } catch (error) {
    handleControllerError(error, res, "addNews");
  }
};

// Get all news
const getAllNews = async (req, res) => {
  try {
    const newsList = await News.find()
      .populate("createdBy", "username")
      .sort({ createdAt: -1 });
    res.json(newsList);
  } catch (error) {
    handleControllerError(error, res, "getAllNews");
  }
};

// Get a single news item by ID
const getNewsById = async (req, res) => {
  try {
    const { id } = req.params;
    const news = await News.findById(id).populate("createdBy", "username");

    if (!news) {
      return res.status(404).json({ message: "News not found." });
    }

    res.json(news);
  } catch (error) {
    handleControllerError(error, res, "getNewsById");
  }
};

// Update an existing news item
const updateNews = async (req, res) => {
  try {
    const { id } = req.params;
    const { title, content } = req.body;
    let headingImage;
    let images;

    const news = await News.findById(id);
    if (!news) {
      return res.status(404).json({ message: "News not found." });
    }

    if (req.files["headingImage"]) {
      // Delete the old heading image if it exists
      if (news.headingImage) {
        deleteFile(news.headingImage);
      }
      headingImage = `/uploads/${req.files["headingImage"][0].filename}`;
      news.headingImage = headingImage;
    }

    if (req.files["images"] && req.files["images"].length > 0) {
      // Optionally delete old carousel images
      news.images.forEach((img) => deleteFile(img));
      images = req.files["images"].map((file) => `/uploads/${file.filename}`);
      news.images = images;
    }

    // Update fields if provided
    if (title) news.title = title;
    if (content) news.content = content;

    await news.save();

    res.json({ message: "News updated successfully.", news });
  } catch (error) {
    handleControllerError(error, res, "updateNews");
  }
};

// Delete a news item
const deleteNews = async (req, res) => {
  try {
    const { id } = req.params;

    const news = await News.findByIdAndDelete(id);
    if (!news) {
      return res.status(404).json({ message: "News not found." });
    }

    // Delete heading and carousel images if they exist
    if (news.headingImage) {
      deleteFile(news.headingImage);
    }
    news.images.forEach((img) => deleteFile(img));

    res.json({ message: "News deleted successfully." });
  } catch (error) {
    handleControllerError(error, res, "deleteNews");
  }
};

module.exports = {
  // Articles
  addArticle,
  getAllArticles,
  getArticleById,
  updateArticle,
  deleteArticle,

  // News
  addNews,
  getAllNews,
  getNewsById,
  updateNews,
  deleteNews,
};

C:\Development\Node js programs\Football App\football-app-backend\node_modules\express\lib\router\route.js:216
        throw new Error(msg);
        ^

Error: Route.post() requires a callback function but got a [object Undefined]
    at Route.<computed> [as post] (C:\Development\Node js programs\Football App\football-app-backend\node_modules\express\lib\router\route.js:216:15)
    at proto.<computed> [as post] (C:\Development\Node js programs\Football App\football-app-backend\node_modules\express\lib\router\index.js:521:19)
    at Object.<anonymous> (C:\Development\Node js programs\Football App\football-app-backend\routes\admin.js:39:8)
    at Module._compile (node:internal/modules/cjs/loader:1358:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
    at Module.load (node:internal/modules/cjs/loader:1208:32)
    at Module._load (node:internal/modules/cjs/loader:1024:12)
    at Module.require (node:internal/modules/cjs/loader:1233:19)
    at require (node:internal/modules/helpers:179:18)
    at Object.<anonymous> (C:\Development\Node js programs\Football App\football-app-backend\server.js:16:21)

Node.js v20.13.1
Can you remove this error