const Brand = require("../../models/admin/brandModel");
const { errorResponse } = require("../../utils/errorResponseHandler");
const { logUserAction } = require("../../utils/userActionLogger");
const getRelativePath = require("../../utils/getRelativePath");

const createBrand = async (req, res) => {
  try {
    const { brandName, orgId } = req.body;

    if (!brandName) return errorResponse(res, "Brand name is required", 400);
    if (!orgId) return errorResponse(res, "Organization ID is required", 400);

    // Logo required
    if (!req.file) return errorResponse(res, "Brand image is required", 400);

    const userId = req.user?._id;

    // Prevent duplicate brand per org
    const existingBrand = await Brand.findOne({ brandName, orgId, isDeleted: false });
    if (existingBrand) {
      return errorResponse(
        res,
        "Brand name already exists in this organization",
        409
      );
    }

    const brand = await Brand.create({
      brandName,
      orgId,
      image: getRelativePath(req.file.path),
      createdBy: userId || null,
      updatedBy: userId || null,
    });
    const populatedBrand = await Brand.findById(brand._id)
      .populate("createdBy", "firstName lastName email")
      .populate("updatedBy", "firstName lastName email")
      .populate("orgId", "orgName");

    await logUserAction({
      userId,
      orgId,
      action: "CREATE",
      model: "Brand",
      details: { brandId: brand._id, brandName },
      req,
    });

    return res.status(201).json({
      success: true,
      data: populatedBrand,
    });
  } catch (error) {
    return errorResponse(res, "Failed to create brand", 400, error);
  }
};

const getBrands = async (req, res) => {
  try {
    let { page = 1, limit = 10 } = req.query;
    page = parseInt(page);
    limit = parseInt(limit);
    const skip = (page - 1) * limit;

    const query = { isDeleted: false };

    const [brands, total] = await Promise.all([
      Brand.find(query)
        .populate("createdBy", "firstName lastName email")
        .populate("updatedBy", "firstName lastName email")
        .populate("orgId", "orgName")
        .skip(skip)
        .limit(limit)
        .sort({ createdAt: -1 }),
      Brand.countDocuments(query),
    ]);

    await logUserAction({
      userId: req.user?._id,
      orgId: req.user?.orgId || null,
      action: "READ",
      model: "Brand",
      details: { page, limit, count: brands.length },
      req,
    });

    return res.status(200).json({
      success: true,
      page,
      totalPages: Math.ceil(total / limit),
      totalRecords: total,
      brands,
    });
  } catch (error) {
    return errorResponse(res, "Failed to fetch brands", 500, error);
  }
};

const getBrandById = async (req, res) => {
  try {
    const brand = await Brand.findById(req.params.id)
      .populate("createdBy", "firstName lastName email")
      .populate("updatedBy", "firstName lastName email")
      .populate("orgId", "orgName");

    if (!brand) return errorResponse(res, "Brand not found", 404);

    await logUserAction({
      userId: req.user?._id,
      orgId: brand.orgId?._id || null,
      action: "READ",
      model: "Brand",
      details: { brandId: brand._id },
      req,
    });

    return res.status(200).json({
      success: true,
      data: brand,
    });
  } catch (error) {
    return errorResponse(res, "Error fetching brand", 500, error);
  }
};

// const updateBrand = async (req, res) => {
//   try {
//     const { brandName, status, orgId } = req.body;
//     const userId = req.user?._id;

//     const updateData = {
//       updatedBy: userId || null,
//     };

//     if (brandName) updateData.brandName = brandName;
//     if (orgId) updateData.orgId = orgId;

//     if (status !== undefined) {
//       updateData.status = status === "true" || status === true;
//     }

//     // Logo re-upload
//     if (req.file) {
//       updateData.image = getRelativePath(req.file.path);
//     }

//     const brand = await Brand.findByIdAndUpdate(
//       req.params.id,
//       updateData,
//       { new: true, runValidators: true }
//     )
//       .populate("createdBy", "firstName lastName email")
//       .populate("updatedBy", "firstName lastName email")
//       .populate("orgId", "orgName");

//     if (!brand) return errorResponse(res, "Brand not found", 404);

//     await logUserAction({
//       userId,
//       orgId: brand.orgId?._id || orgId || null,
//       action: "UPDATE",
//       model: "Brand",
//       details: { brandId: brand._id, updatedFields: updateData },
//       req,
//     });

//     return res.status(200).json({
//       success: true,
//       data: brand,
//     });
//   } catch (error) {
//     return errorResponse(res, "Failed to update brand", 400, error);
//   }
// };
const updateBrand = async (req, res) => {
  try {
    const { brandName, status, orgId } = req.body;
    const userId = req.user?._id;

    // 🔴 DUPLICATE BRAND CHECK (exclude current brand)
    if (brandName) {
      const duplicate = await Brand.findOne({
        _id: { $ne: req.params.id }, // exclude current brand
        brandName: {
          $regex: `^${brandName}$`,
          $options: "i", // case-insensitive
        },
        orgId,
        isDeleted: false,
      });

      if (duplicate) {
        return errorResponse(
          res,
          "Brand already exists in this organization",
          409
        );
      }
    }

    const updateData = {
      updatedBy: userId || null,
      updatedAt: new Date(), // ✅ always update timestamp
    };

    if (brandName) updateData.brandName = brandName;
    if (orgId) updateData.orgId = orgId;

    if (status !== undefined) {
      updateData.status = status === "true" || status === true;
    }

    // Logo re-upload
    if (req.file) {
      updateData.image = getRelativePath(req.file.path);
    }

    const brand = await Brand.findByIdAndUpdate(
      req.params.id,
      updateData,
      { new: true, runValidators: true }
    )
      .populate("createdBy", "firstName lastName email")
      .populate("updatedBy", "firstName lastName email")
      .populate("orgId", "orgName");

    if (!brand) return errorResponse(res, "Brand not found", 404);

    await logUserAction({
      userId,
      orgId: brand.orgId?._id || orgId || null,
      action: "UPDATE",
      model: "Brand",
      details: { brandId: brand._id, updatedFields: updateData },
      req,
    });

    return res.status(200).json({
      success: true,
      data: brand,
    });
  } catch (error) {
    return errorResponse(res, "Failed to update brand", 400, error);
  }
};


const deleteBrand = async (req, res) => {
  try {
    const userId = req.user?._id;

    const brand = await Brand.findByIdAndUpdate(
      req.params.id,
      { isDeleted: true, updatedBy: userId || null },
      { new: true }
    );

    if (!brand) return errorResponse(res, "Brand not found", 404);

    await logUserAction({
      userId,
      orgId: brand.orgId?._id || null,
      action: "DELETE",
      model: "Brand",
      details: { brandId: brand._id },
      req,
    });

    return res.status(200).json({
      success: true,
      message: "Brand deleted successfully",
      data: brand,
    });
  } catch (error) {
    return errorResponse(res, "Failed to delete brand", 500, error);
  }
};

module.exports = {
  createBrand,
  getBrands,
  getBrandById,
  updateBrand,
  deleteBrand,
};
