const admin = require("firebase-admin");
const db = admin.firestore();
const logger = require("firebase-functions/logger");
const auth = require("../utils/auth");
const helpers = require("../utils/helpers");

// Récupérer toutes les options (public pour utilisateurs authentifiés)
exports.getOptions = async (req, res) => {
  try {
    await auth.authenticateUser(req);

    const snapshot = await db.collection("options").get();
    const options = snapshot.docs.map((doc) => ({
      id: doc.id,
      ...helpers.serializeTimestamps(doc.data()),
    }));

    res.status(200).json({options});
  } catch (error) {
    logger.error("Error fetching options:", error);
    res.status(500).json({error: error.message});
  }
};

// Récupérer tous les types d'événements (public pour utilisateurs authentifiés)
exports.getEventTypes = async (req, res) => {
  try {
    await auth.authenticateUser(req);

    const snapshot = await db.collection("eventTypes").get();
    const eventTypes = snapshot.docs.map((doc) => ({
      id: doc.id,
      ...helpers.serializeTimestamps(doc.data()),
    }));

    res.status(200).json({eventTypes});
  } catch (error) {
    logger.error("Error fetching event types:", error);
    res.status(500).json({error: error.message});
  }
};

// Créer une option
exports.createOption = async (req, res) => {
  try {
    const decodedToken = await auth.authenticateUser(req);
    const isAdminUser = await auth.isAdmin(decodedToken.uid);

    if (!isAdminUser) {
      res.status(403).json({error: "Forbidden: Admin access required"});
      return;
    }

    const optionData = req.body.data;
    const optionId = optionData.id;

    if (!optionId) {
      res.status(400).json({error: "Option ID is required"});
      return;
    }

    await db.collection("options").doc(optionId).set(optionData);

    res.status(201).json({id: optionId, message: "Option created successfully"});
  } catch (error) {
    logger.error("Error creating option:", error);
    res.status(500).json({error: error.message});
  }
};

// Mettre à jour une option
exports.updateOption = async (req, res) => {
  try {
    const decodedToken = await auth.authenticateUser(req);
    const isAdminUser = await auth.isAdmin(decodedToken.uid);

    if (!isAdminUser) {
      res.status(403).json({error: "Forbidden: Admin access required"});
      return;
    }

    const {optionId, data} = req.body.data;

    if (!optionId) {
      res.status(400).json({error: "Option ID is required"});
      return;
    }

    delete data.id;

    await db.collection("options").doc(optionId).update(data);

    res.status(200).json({message: "Option updated successfully"});
  } catch (error) {
    logger.error("Error updating option:", error);
    res.status(500).json({error: error.message});
  }
};

// Supprimer une option
exports.deleteOption = async (req, res) => {
  try {
    const decodedToken = await auth.authenticateUser(req);
    const isAdminUser = await auth.isAdmin(decodedToken.uid);

    if (!isAdminUser) {
      res.status(403).json({error: "Forbidden: Admin access required"});
      return;
    }

    const {optionId} = req.body.data;

    if (!optionId) {
      res.status(400).json({error: "Option ID is required"});
      return;
    }

    await db.collection("options").doc(optionId).delete();

    res.status(200).json({message: "Option deleted successfully"});
  } catch (error) {
    logger.error("Error deleting option:", error);
    res.status(500).json({error: error.message});
  }
};

// Créer un type d'événement
exports.createEventType = async (req, res) => {
  try {
    const decodedToken = await auth.authenticateUser(req);
    const isAdmin = await auth.hasPermission(decodedToken.uid, "edit_data");

    if (!isAdmin) {
      res.status(403).json({error: "Forbidden: Admin permission required"});
      return;
    }

    const {name, defaultPrice} = req.body.data;

    if (!name || defaultPrice === undefined) {
      res.status(400).json({error: "Name and defaultPrice are required"});
      return;
    }

    const existingSnapshot = await db.collection("eventTypes")
        .where("name", "==", name)
        .get();

    if (!existingSnapshot.empty) {
      res.status(409).json({error: "Event type name already exists"});
      return;
    }

    const eventTypeData = {
      name,
      defaultPrice,
      createdAt: admin.firestore.Timestamp.now(),
    };

    const docRef = await db.collection("eventTypes").add(eventTypeData);

    res.status(201).json({id: docRef.id, message: "Event type created successfully"});
  } catch (error) {
    logger.error("Error creating event type:", error);
    res.status(500).json({error: error.message});
  }
};

// Mettre à jour un type d'événement
exports.updateEventType = async (req, res) => {
  try {
    const decodedToken = await auth.authenticateUser(req);
    const isAdmin = await auth.hasPermission(decodedToken.uid, "edit_data");

    if (!isAdmin) {
      res.status(403).json({error: "Forbidden: Admin permission required"});
      return;
    }

    const {eventTypeId, name, defaultPrice} = req.body.data;

    if (!eventTypeId) {
      res.status(400).json({error: "Event type ID is required"});
      return;
    }

    const docRef = db.collection("eventTypes").doc(eventTypeId);
    const doc = await docRef.get();

    if (!doc.exists) {
      res.status(404).json({error: "Event type not found"});
      return;
    }

    if (name) {
      const existingSnapshot = await db.collection("eventTypes")
          .where("name", "==", name)
          .get();

      const hasDuplicate = existingSnapshot.docs.some((d) => d.id !== eventTypeId);
      if (hasDuplicate) {
        res.status(409).json({error: "Event type name already exists"});
        return;
      }
    }

    const updateData = {};
    if (name) updateData.name = name;
    if (defaultPrice !== undefined) updateData.defaultPrice = defaultPrice;

    await docRef.update(updateData);

    res.status(200).json({message: "Event type updated successfully"});
  } catch (error) {
    logger.error("Error updating event type:", error);
    res.status(500).json({error: error.message});
  }
};

// Supprimer un type d'événement
exports.deleteEventType = async (req, res) => {
  try {
    const decodedToken = await auth.authenticateUser(req);
    const isAdmin = await auth.hasPermission(decodedToken.uid, "edit_data");

    if (!isAdmin) {
      res.status(403).json({error: "Forbidden: Admin permission required"});
      return;
    }

    const {eventTypeId} = req.body.data;

    if (!eventTypeId) {
      res.status(400).json({error: "Event type ID is required"});
      return;
    }

    const eventsSnapshot = await db.collection("events")
        .where("eventTypeId", "==", eventTypeId)
        .get();

    const now = admin.firestore.Timestamp.now();
    const futureEvents = eventsSnapshot.docs.filter((doc) => {
      const startDate = doc.data().StartDateTime;
      return startDate && startDate > now;
    });

    if (futureEvents.length > 0) {
      res.status(409).json({
        error: "Cannot delete event type with future events",
        futureEventsCount: futureEvents.length,
      });
      return;
    }

    await db.collection("eventTypes").doc(eventTypeId).delete();

    res.status(200).json({message: "Event type deleted successfully"});
  } catch (error) {
    logger.error("Error deleting event type:", error);
    res.status(500).json({error: error.message});
  }
};
