const {
  Projects,
  Companies,
  Reports,
  UserProjects,
  Users,
  Subscriptions,
} = require("../models");

const getProjects = async (req, res) => {
  const { list } = req.query;

  try {
    if (list == "") {
      const projects = await Projects.findAll({
        where: {
          CompanyId: req.user.companyId,
        },
        include: [
          {
            model: Users,
            attributes: {
              exclude: ["password"],
            },
          },
        ],
      });

      return res.json(
        projects.map((p) => ({ ...p, users: JSON.stringify(p.Users) })),
      );
    }
    const projects = await Users.findByPk(req.user.id, {
      include: [
        {
          model: Projects,
          include: [
            {
              model: Users,
              attributes: {
                exclude: ["password"],
              },
            },
          ],
        },
      ],
    });

    res.json(
      projects.Projects.map((p) => ({ ...p, users: JSON.stringify(p.Users) })),
    );
  } catch (err) {
    console.log(err);

    res.status(500).json({ message: "Failed to fetch" });
  }
};

const createProject = async (req, res) => {
  console.log("🔍 createProject function started");
  console.log("🔍 req.user:", req.user);
  
  const permissions = ["admin", "super-admin"];
  if (!permissions.includes(req.user?.role)) {
    console.log("❌ Permission denied, user role:", req.user?.role);
    return res.status(403).json({ message: "Forbidden" });
  }

  const { name, location } = req.body;
  console.log("🔍 Request data - name:", name, "location:", location);
  
  if (!name) {
    console.log("❌ Name is missing");
    return res.status(400).json({ message: "Name is required" });
  }
  if (!location) {
    console.log("❌ Location is missing");
    return res.status(400).json({ message: "Location is required" });
  }

  try {
    console.log("🔍 Looking for company with ID:", req.user.companyId);
    const company = await Companies.findByPk(req.user.companyId);
    console.log("🔍 Company found:", company ? "Yes" : "No");

    if (!company) {
      console.log("❌ Company not found");
      return res.status(404).json({ message: "Something went wrong" });
    }

    console.log("🔍 Looking for latest subscription for company:", company.id);
    let latestSubscription = await Subscriptions.findOne({
      where: {
        CompanyId: company.id,
      },
      order: [["createdAt", "DESC"]],
    });
    console.log("🔍 Latest subscription found:", latestSubscription ? "Yes" : "No");

    if (!latestSubscription) {
      console.log("🔍 No subscription found, creating default trial subscription...");
      // Create a default trial subscription for companies that don't have one
      latestSubscription = await Subscriptions.create({
        CompanyId: company.id,
        subscriptionType: "free trial",
        subscriptionEndsAt: company.subscriptionEndsAt || new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days from now
        usersCount: 5,
        projectsCount: 1,
        monthlySDSSearchCount: 20,
        monthlySDSSaveCount: 0,
      });
      console.log("✅ Default subscription created with ID:", latestSubscription.id);
    }
    
    console.log("🔍 Counting existing projects for company:", company.id);
    const companyProjectsCount = await Projects.count({
      where: {
        CompanyId: company.id,
      },
    });
    console.log("🔍 Current projects count:", companyProjectsCount);

    const subProjectsCount = latestSubscription.projectsCount;
    console.log("🔍 Subscription allows projects:", subProjectsCount);
    
    if (companyProjectsCount >= subProjectsCount) {
      console.log("❌ Project limit reached");
      return res.status(400).json({
        message:
          `You can only have ${subProjectsCount} project` +
          (subProjectsCount === 1 ? "" : "s"),
      });
    }

    console.log("🔍 Creating new project...");
    const newProject = await Projects.create({
      name,
      location,
      CompanyId: company.id,
    });
    console.log("✅ Project created with ID:", newProject.id);
    
    console.log("🔍 Creating user-project association...");
    await UserProjects.create({
      UserId: req.user.id,
      ProjectId: newProject.id,
    });
    console.log("✅ User-project association created");

    console.log("✅ Sending success response");
    res.status(201).json({
      message: "Project created successfully",
      createdProjectId: newProject.id,
    });
  } catch (err) {
    console.log("❌ Error in createProject:", err);
    res.status(500).json({ message: "Failed to create" });
  }
};

const deleteProject = async (req, res) => {
  const permissions = ["admin", "super-admin"];
  if (!permissions.includes(req.user?.role))
    return res.status(403).json({ message: "Forbidden" });

  const { id } = req.query;
  if (!id) return res.status(400).json({ message: "ID is required" });

  try {
    const project = await Projects.findByPk(id);
    if (!project) return res.status(404).json({ message: "Project not found" });

    const report = await Reports.findOne({
      where: {
        ProjectId: project.id,
      },
    });
    if (report)
      return res.status(400).json({
        message: "You can't delete a project that is connected to a report ",
      });

    await Projects.destroy({ where: { id } });

    res.status(200).json({ message: "Project deleted successfully" });
  } catch (err) {
    console.log(err);
    res.status(500).json({ message: "Failed to delete" });
  }
};

const users = async (req, res) => {
  const permissions = ["admin", "super-admin"];
  if (!permissions.includes(req.user?.role))
    return res.status(403).json({ message: "Forbidden" });

  const { users, projectId } = req.body;

  if (!projectId)
    return res.status(404).json({ message: "Invalid project id" });

  try {
    const project = await Projects.findByPk(projectId);
    if (!project) return res.status(404).json({ message: "Project not found" });

    const { Op } = require("sequelize");

    const existingUserProjects = await UserProjects.findAll({
      where: { ProjectId: projectId },
    });

    const existingUserIds = existingUserProjects.map((up) => up.UserId);

    const usersToRemove = existingUserIds.filter(
      (userId) => !users.includes(userId),
    );
    const usersToAdd = users.filter(
      (userId) => !existingUserIds.includes(userId),
    );

    if (usersToRemove.length > 0)
      await UserProjects.destroy({
        where: {
          ProjectId: projectId,
          UserId: {
            [Op.in]: usersToRemove,
          },
        },
      });

    if (usersToAdd.length > 0) {
      const recordsToCreate = usersToAdd.map((userId) => ({
        ProjectId: projectId,
        UserId: userId,
      }));

      await UserProjects.bulkCreate(recordsToCreate);
    }

    res.status(200).json({ message: "Project users updated successfully" });
  } catch (err) {
    console.log(err);
    res.status(500).json({ message: "Failed to update" });
  }
};

module.exports = { getProjects, createProject, deleteProject, users };
