// config/passport.js
const passport = require("passport");
const JwtStrategy = require("passport-jwt").Strategy;
const ExtractJwt = require("passport-jwt").ExtractJwt;
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const FacebookStrategy = require("passport-facebook").Strategy;
const TwitterStrategy = require("passport-twitter").Strategy;
const Admin = require("../models/Admin");
const dotenv = require("dotenv");

dotenv.config();

// JWT Options
const opts = {
  jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
  secretOrKey: process.env.JWT_SECRET,
};

// JWT Strategy
passport.use(
  new JwtStrategy(opts, async (jwt_payload, done) => {
    try {
      const admin = await Admin.findById(jwt_payload._id);
      if (admin) {
        return done(null, admin);
      }
      return done(null, false);
    } catch (err) {
      return done(err, false);
    }
  })
);

// Google Strategy
passport.use(
  new GoogleStrategy(
    {
      clientID: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      callbackURL: "/auth/google/callback",
    },
    async (accessToken, refreshToken, profile, done) => {
      try {
        // Check if admin with this Google ID exists
        let admin = await Admin.findOne({ googleId: profile.id });

        if (admin) {
          return done(null, admin);
        }

        // If not, check if an admin with the same email exists
        admin = await Admin.findOne({ email: profile.emails[0].value });

        if (admin) {
          // Link Google account
          admin.googleId = profile.id;
          admin.profilePicture = profile.photos[0].value;
          await admin.save();
          return done(null, admin);
        }

        // If no admin exists, create a new one
        const newAdmin = new Admin({
          username: profile.displayName,
          email: profile.emails[0].value,
          googleId: profile.id,
          profilePicture: profile.photos[0].value,
        });

        await newAdmin.save();
        return done(null, newAdmin);
      } catch (error) {
        return done(error, false);
      }
    }
  )
);

// Facebook Strategy
passport.use(
  new FacebookStrategy(
    {
      clientID: process.env.FACEBOOK_APP_ID,
      clientSecret: process.env.FACEBOOK_APP_SECRET,
      callbackURL: "/auth/facebook/callback",
      profileFields: ["id", "displayName", "emails", "photos"],
    },
    async (accessToken, refreshToken, profile, done) => {
      try {
        let admin = await Admin.findOne({ facebookId: profile.id });

        if (admin) {
          return done(null, admin);
        }

        // Check if admin with the same email exists
        const email = profile.emails ? profile.emails[0].value : null;
        if (email) {
          admin = await Admin.findOne({ email });

          if (admin) {
            // Link Facebook account
            admin.facebookId = profile.id;
            admin.profilePicture = profile.photos[0].value;
            await admin.save();
            return done(null, admin);
          }
        }

        // Create a new admin
        const newAdmin = new Admin({
          username: profile.displayName,
          email: email,
          facebookId: profile.id,
          profilePicture: profile.photos[0].value,
        });

        await newAdmin.save();
        return done(null, newAdmin);
      } catch (error) {
        return done(error, false);
      }
    }
  )
);

// Twitter Strategy
passport.use(
  new TwitterStrategy(
    {
      consumerKey: process.env.TWITTER_CONSUMER_KEY,
      consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
      callbackURL: "/auth/twitter/callback",
      includeEmail: true,
    },
    async (token, tokenSecret, profile, done) => {
      try {
        let admin = await Admin.findOne({ twitterId: profile.id });

        if (admin) {
          return done(null, admin);
        }

        // Note: Twitter may not always provide email
        const email = profile.emails ? profile.emails[0].value : null;
        if (email) {
          admin = await Admin.findOne({ email });

          if (admin) {
            // Link Twitter account
            admin.twitterId = profile.id;
            admin.profilePicture = profile.photos[0].value;
            await admin.save();
            return done(null, admin);
          }
        }

        // Create a new admin
        const newAdmin = new Admin({
          username: profile.displayName,
          email: email, // May be undefined
          twitterId: profile.id,
          profilePicture: profile.photos[0].value,
        });

        await newAdmin.save();
        return done(null, newAdmin);
      } catch (error) {
        return done(error, false);
      }
    }
  )
);


// 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,
};


const Article = require("../models/Article");
const { handleControllerError } = require("../utils/errorHandler");

// Function to handle uploading 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,
    });

    await newArticle.save();

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

// Function to fetch all articles
const getArticles = async (req, res) => {
  try {
    const articles = await Article.find().sort({ createdAt: -1 });
    res.json(articles);
  } catch (error) {
    handleControllerError(error, res, "getArticles");
  }
};

// Function to fetch a single article by ID
const getArticleById = async (req, res) => {
  try {
    const { id } = req.params;
    const article = await Article.findById(id);

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

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

module.exports = {
  getArticles,
  addArticle,
  getArticleById,
};

// controllers/authController.js

const Admin = require("../models/Admin");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");

// Helper function to generate JWT
const generateToken = (admin) => {
  return jwt.sign(
    { _id: admin._id, role: admin.role },
    process.env.JWT_SECRET,
    { expiresIn: "1h" }
  );
};

// Register Controller
exports.register = async (req, res) => {
  try {
    const { username, email, password } = req.body;

    // Validate input
    if (!username || !email || !password) {
      return res.status(400).json({ error: "All fields are required." });
    }

    // Check if email or username already exists
    const existingAdmin = await Admin.findOne({
      $or: [{ email }, { username }],
    });

    if (existingAdmin) {
      return res.status(400).json({ error: "Admin already exists." });
    }

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

    // Create new admin
    const newAdmin = new Admin({
      username,
      email,
      password: hashedPassword,
    });

    await newAdmin.save();

    res.status(201).json({ message: "Admin registered successfully." });
  } catch (error) {
    console.error("Registration Error:", error);
    res.status(500).json({ error: "Server error during registration." });
  }
};

// Login Controller
exports.login = async (req, res) => {
  try {
    const { email, password } = req.body;

    // Validate input
    if (!email || !password) {
      return res.status(400).json({ error: "All fields are required." });
    }

    // Find admin by email
    const admin = await Admin.findOne({ email });

    if (!admin) {
      return res.status(400).json({ error: "Invalid credentials." });
    }

    // Compare passwords
    if (!admin.password) {
      // Handle users without passwords (e.g., social logins)
      return res
        .status(400)
        .json({ error: "Please log in using a social account." });
    }

    const isMatch = await bcrypt.compare(password, admin.password);

    if (!isMatch) {
      return res.status(400).json({ error: "Invalid credentials." });
    }

    // Generate JWT
    const token = generateToken(admin);

    // Determine if the user is a superuser
    if (admin.role === "superuser") {
      res.json({ token, role: "superuser" });
    } else {
      res.json({ token, role: admin.role });
    }
  } catch (error) {
    console.error("Login Error:", error);
    res.status(500).json({ error: "Server error during login." });
  }
};

// Logout Controller
exports.logout = (req, res) => {
  // Since JWT is stateless, logout can be handled on the client by deleting the token.
  // To implement server-side logout (like token blacklisting), additional setup is required.
  res.json({
    message: "Logout successful. Please delete the token on client side.",
  });
};

// Verify Token Controller
exports.verifyToken = async (req, res) => {
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith("Bearer ")) {
    return res
      .status(401)
      .json({ message: "Authorization header missing or malformed." });
  }
  const token = authHeader.split(" ")[1];

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    const admin = await Admin.findById(decoded._id);
    if (!admin) {
      return res.status(401).json({ message: "Invalid token." });
    }
    res.json({ _id: admin._id, role: admin.role });
  } catch (err) {
    return res.status(401).json({ message: "Invalid token." });
  }
};

// Social Login Callback Controller
exports.socialLoginCallback = async (req, res) => {
  try {
    const admin = req.user;

    // Generate JWT
    const token = generateToken(admin);

    // Redirect or respond with token
    // For APIs, it's common to send the token in the response or set it as a query parameter
    // For simplicity, we'll redirect to a front-end route with the token as a query param
    res.redirect(
      `${process.env.FRONTEND_URL}/social-login-success?token=${token}`
    );
  } catch (error) {
    console.error("Social Login Callback Error:", error);
    res.status(500).json({ error: "Server error during social login." });
  }
};



const Admin = require("../models/Admin");
const bcrypt = require("bcryptjs");
const { handleControllerError } = require("../utils/errorHandler");

// View all admins
const getAllAdmins = async (req, res) => {
  try {
    const admins = await Admin.find().select("-password");
    res.json(admins);
  } catch (error) {
    handleControllerError(error, res, "getAllAdmins");
  }
};

// Assign role to an admin
const assignRole = async (req, res) => {
  try {
    const { adminId, role } = req.body;

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

    const validRoles = ["publisher", "reviewer", "admin"];
    if (!validRoles.includes(role)) {
      return res
        .status(400)
        .json({ message: `Role must be one of: ${validRoles.join(", ")}` });
    }

    const admin = await Admin.findById(adminId);
    if (!admin) {
      return res.status(404).json({ message: "Admin not found." });
    }

    admin.role = role;
    await admin.save();

    res.json({ message: `Role updated to ${role} successfully.`, admin });
  } catch (error) {
    handleControllerError(error, res, "assignRole");
  }
};

// Delete an admin
const deleteAdmin = async (req, res) => {
  try {
    const { adminId } = req.params;

    if (!adminId) {
      return res.status(400).json({ message: "adminId is required." });
    }

    const admin = await Admin.findByIdAndDelete(adminId);
    if (!admin) {
      return res.status(404).json({ message: "Admin not found." });
    }

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

// Update Super User's own profile (optional)
const updateSuperUserProfile = async (req, res) => {
  try {
    const { username, email, password } = req.body;

    const superUser = await Admin.findById(req.admin._id);
    if (!superUser) {
      return res.status(404).json({ message: "Super User not found." });
    }

    if (username) superUser.username = username;
    if (email) superUser.email = email;
    if (password) {
      const hashedPassword = await bcrypt.hash(password, 10);
      superUser.password = hashedPassword;
    }

    await superUser.save();

    res.json({ message: "Profile updated successfully.", superUser });
  } catch (error) {
    handleControllerError(error, res, "updateSuperUserProfile");
  }
};

module.exports = {
  getAllAdmins,
  assignRole,
  deleteAdmin,
  updateSuperUserProfile,
};

// middlewares/auth.js
const jwt = require("jsonwebtoken");
const Admin = require("../models/Admin");

const verifyToken = async (req, res, next) => {
  const authHeader = req.headers.authorization || req.headers.Authorization;

  if (!authHeader || !authHeader.startsWith("Bearer ")) {
    return res
      .status(401)
      .json({ message: "Access denied. No token provided." });
  }

  const token = authHeader.split(" ")[1];

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);

    // Fetch admin from DB
    const admin = await Admin.findById(decoded._id);
    if (!admin || admin.role !== "admin") {
      return res.status(403).json({ message: "Access denied. Not an admin." });
    }

    req.admin = admin; // Attach admin to the request object
    next();
  } catch (error) {
    console.error("Token verification failed:", error);
    res.status(400).json({ message: "Invalid token." });
  }
};

module.exports = { verifyToken };

// middlewares/authMiddleware.js
const jwt = require("jsonwebtoken");

const authenticateToken = (req, res, next) => {
  const token = req.header("Authorization");
  if (!token) return res.status(401).json({ error: "Access Denied" });

  try {
    const verified = jwt.verify(token, process.env.JWT_SECRET);
    req.user = verified;
    next();
  } catch (err) {
    res.status(400).json({ error: "Invalid Token" });
  }
};

module.exports = authenticateToken;


const Admin = require("../models/Admin");

const authorizeRoles = (...roles) => {
  return async (req, res, next) => {
    try {
      const admin = await Admin.findById(req.admin._id);
      if (!admin) {
        return res.status(401).json({ message: "Unauthorized" });
      }

      if (!roles.includes(admin.role)) {
        return res.status(403).json({ message: "Forbidden: Access denied" });
      }

      next();
    } catch (error) {
      console.error("Role Authorization Error:", error);
      res.status(500).json({ message: "Server Error" });
    }
  };
};

module.exports = authorizeRoles;

// middlewares/upload.js
const multer = require("multer");
const path = require("path");

// Define storage for uploaded files
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "uploads/"); // Ensure this directory exists
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
    cb(null, uniqueSuffix + path.extname(file.originalname));
  },
});

// File filter to accept only images
const fileFilter = (req, file, cb) => {
  const allowedTypes = /jpeg|jpg|png|gif/;
  const extname = allowedTypes.test(
    path.extname(file.originalname).toLowerCase()
  );
  const mimetype = allowedTypes.test(file.mimetype);

  if (mimetype && extname) {
    return cb(null, true);
  }
  cb(new Error("Only images are allowed"));
};

// Initialize multer
const upload = multer({
  storage,
  fileFilter,
  limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit
});

module.exports = upload;


const mongoose = require("mongoose");

const AdminSchema = new mongoose.Schema(
  {
    username: {
      type: String,
      required: true,
      unique: true,
    },
    email: {
      type: String,
      required: true,
      unique: true,
    },
    password: {
      type: String,
      // Not required for social logins
    },
    googleId: {
      type: String,
    },
    facebookId: {
      type: String,
    },
    twitterId: {
      type: String,
    },
    profilePicture: {
      type: String,
    },
    role: {
      type: String,
      enum: ["superuser", "publisher", "reviewer", "admin"],
      default: "admin",
    },
  },
  { timestamps: true }
);

module.exports = mongoose.model("Admin", AdminSchema);


// 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/roleMiddleware");
const upload = require("../middlewares/upload");

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

// --- Article Routes ---

// Create a new article
router.post(
  "/articles",
  upload.single("headingImage"),
  adminController.addArticle
);

// Get all articles
router.get("/articles", adminController.getAllArticles);

// Get a single article by ID
router.get("/articles/:id", adminController.getArticleById);

// Update an article
router.put(
  "/articles/:id",
  upload.single("headingImage"),
  adminController.updateArticle
);

// Delete an article
router.delete("/articles/:id", adminController.deleteArticle);

// --- News Routes ---

// Create a new news item
router.post(
  "/news",
  upload.fields([
    { name: "headingImage", maxCount: 1 },
    { name: "images", maxCount: 10 }, // For carousel images
  ]),
  adminController.addNews
);

// Get all news
router.get("/news", adminController.getAllNews);

// Get a single news item by ID
router.get("/news/:id", adminController.getNewsById);

// Update a news item
router.put(
  "/news/:id",
  upload.fields([
    { name: "headingImage", maxCount: 1 },
    { name: "images", maxCount: 10 },
  ]),
  adminController.updateNews
);

// Delete a news item
router.delete("/news/:id", adminController.deleteNews);

module.exports = router;

// routes/auth.js

const express = require("express");
const router = express.Router();
const passport = require("passport");
const authController = require("../controllers/authController");

// Local Registration
router.post("/register", authController.register);

// Local Login
router.post("/login", authController.login);

// Logout
router.post("/logout", authController.logout);

// Verify Token
router.post("/verify-token", authController.verifyToken);

// Google OAuth Routes
router.get(
  "/google",
  passport.authenticate("google", { scope: ["profile", "email"] })
);

router.get(
  "/google/callback",
  passport.authenticate("google", {
    session: false,
    failureRedirect: "/login",
  }),
  authController.socialLoginCallback
);

// Facebook OAuth Routes
router.get(
  "/facebook",
  passport.authenticate("facebook", { scope: ["email"] })
);

router.get(
  "/facebook/callback",
  passport.authenticate("facebook", {
    session: false,
    failureRedirect: "/login",
  }),
  authController.socialLoginCallback
);

// Twitter OAuth Routes
router.get("/twitter", passport.authenticate("twitter"));

router.get(
  "/twitter/callback",
  passport.authenticate("twitter", {
    session: false,
    failureRedirect: "/login",
  }),
  authController.socialLoginCallback
);

module.exports = router;

const express = require("express");
const router = express.Router();
const superUserController = require("../controllers/superUserController");
const { verifyToken } = require("../middlewares/auth");
const authorizeRoles = require("../middlewares/roleMiddleware");

// Protect routes: only superusers can access
router.use(verifyToken);
router.use(authorizeRoles("superuser"));

// GET /api/superuser/admins - View all admins
router.get("/admins", superUserController.getAllAdmins);

// PUT /api/superuser/assign-role - Assign role to admin
router.put("/assign-role", superUserController.assignRole);

// DELETE /api/superuser/delete/:adminId - Delete an admin
router.delete("/delete/:adminId", superUserController.deleteAdmin);

// PUT /api/superuser/profile - Update Super User profile (optional)
router.put("/profile", superUserController.updateSuperUserProfile);

module.exports = router;

require("dotenv").config();
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const Admin = require("../models/Admin");

const seedSuperUser = async () => {
  await mongoose.connect(process.env.MONGO_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  });

  const existingSuperUser = await Admin.findOne({ role: "superuser" });
  if (existingSuperUser) {
    console.log("Super User already exists.");
    process.exit(0);
  }

  const username = "dfbjdfkv h"; // Change as needed
  const email = "smndf@gmail.com"; // Change as needed
  const password = "alkjdfbh"; // Change as needed

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

  const superUser = new Admin({
    username,
    email,
    password: hashedPassword,
    role: "superuser",
  });

  await superUser.save();
  console.log("Super User seeded successfully.");
  process.exit(0);
};

seedSuperUser().catch((err) => {
  console.error("Error seeding Super User:", err);
  process.exit(1);
});

seedSuperUser();
require("dotenv").config();
const express = require("express");
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const newsRoutes = require("./routes/newsRoutes");
const scoreRoutes = require("./routes/scoreRoutes");
const { startCronJob } = require("./taskQueue/taskQueueWorker");
const standingsRoutes = require("./routes/standingsRoutes");
const fixturesRouter = require("./routes/fixturesRouter");
const leagueRoutes = require("./routes/leagueRoutes");
const leaguesRoutes = require("./routes/leaguesRoutes");
const articleRoutes = require("./routes/articleRoutes");
const playerSearchRoutes = require("./routes/playerSearchRoutes");
const videoRoutes = require("./routes/videoRoutes");
const adminRoutes = require("./routes/admin"); // Existing admin routes
const authRoutes = require("./routes/auth");
const superUserRoutes = require("./routes/superUserRoutes"); // New superuser routes
const session = require("express-session");
const cors = require("cors");
const path = require("path");
const passport = require("passport");

const app = express();

// Passport configuration
require("./config/passport");

// CORS configuration
app.use(
  cors({
    origin: "http://localhost:3000", // Replace with your frontend URL
    methods: ["GET", "POST", "PUT", "DELETE"],
    allowedHeaders: ["Content-Type", "Authorization"],
  })
);
app.use(
  session({
    secret: process.env.SESSION_SECRET || "your_session_secret",
    resave: false,
    saveUninitialized: false,
  })
);

// Initialize Passport and restore authentication state, if any, from the session
app.use(passport.initialize());
app.use(passport.session());

const PORT = process.env.PORT || 5000;

// Connect to MongoDB
mongoose
  .connect(process.env.MONGO_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
  .then(() => console.log("Connected to MongoDB"))
  .catch((err) => console.error("MongoDB connection error:", err));

// Middleware
app.use(express.json());

// Routes
app.use("/api/auth", authRoutes);
app.use("/api/admin", adminRoutes);
app.use("/api/superuser", superUserRoutes); // Include superuser routes
app.use("/assets", express.static(path.join(__dirname, "assets")));
app.use("/uploads", express.static(path.join(__dirname, "uploads")));
app.use("/api/players", playerSearchRoutes);
app.use("/api/news", newsRoutes);
app.use("/api/scores", scoreRoutes);
app.use("/api/articles", articleRoutes);
app.use("/api", standingsRoutes);
app.use("/api", fixturesRouter);
app.use("/api/leagues", leaguesRoutes);
app.use("/api/league", leagueRoutes);
app.use("/api/videos", videoRoutes);

// Error handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send("Something broke!");
});

// Test route
app.get("/api/test", (req, res) => {
  res.json({ message: "Test route working" });
});

// Start server
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

// Start task queue worker (for fetching live scores)
startCronJob();

module.exports = app; // Export for testing purposes



This is my backend code which you to correct it also 

Correct it like this that SuperUser can delete ID of any admin  which have three roles - publisher, reviewer and user 
So it is role based access publisher can do any publishing writing and article    and reviewer can review article and make improvement but cannot publish and user can read articles and news but cannot do anything other than suggestions

Now what I want is that you correct my code and I want you to make me backend of article writing such that there's whole lot of stuff while writing article 
You got para graph type H1 H2 H3 and H4 tags and also images, carousel and GIF  for lines like 1 2 3 and one is bullet points on clicking that and one is adding link and other is writing in block code I will give you front end too but update it later for now only backend