// controllers/admin/productController.js
const Product = require("../../models/admin/productModel");
const { errorResponse } = require("../../utils/errorResponseHandler");
const { logUserAction } = require("../../utils/userActionLogger");

const {pool} = require("../../config/db")


// const createProduct = async (req, res) => {
//   try {
//     const userId = req.session?.user?.id;

//     const {
//       productName,
//       // category,
//       // subcategory,
//       // stock,
//       // price,
//       // description,
//       // brand,
//       // model,
//       // variant,
//       orgId
//       ,
//     } = req.body;

//     // if (req.files && req.files.length > 5) {
//     //   return res.status(400).json({
//     //     success: false,
//     //     message: "Maximum 5 images are allowed per product",
//     //   });
//     // }

//     // const images =
//     //   req.files && req.files.length > 0
//     //     ? req.files.map((file) => `/uploads/images/${file.filename}`)
//     //     : [];

//     const product = await Product.create({
//       productName,
//       // category,
//       // subcategory,
//       // brand,
//       // model,
//       // variant: variant ? [variant] : [],
//       // stock: stock || 0,
//       // price,
//       // description,
//       // images: images,
//       // status: true,
//       orgId,
//       createdBy: userId,
//       updatedBy: userId,
//     });

//     await logUserAction({
//       userId,
//       action: "CREATE",
//       model: "Product",
//       details: {
//         productId: product._id,
//         productName: product.productName,
//       },
//       req,
//     });

//     return res.status(201).json({
//       success: true,
//       message: "Product created successfully",
//       data: product,
//     });
//   } catch (err) {
//     console.error("Create Product Error:", err);
//     return errorResponse(res, "Failed to create product", 500, err);
//   }
// };


// GET Product by ID
const createProduct = async (req, res) => {
  const client = await pool.connect();

  try {
    const userId = req.session?.user?.id || null;
    const orgId = req.session?.user?.orgId;

    const { productName, description, } = req.body;

    //  Validation
    if (!productName) {
      return errorResponse(res, "Product name is required", 400);
    }

    // if (!orgId || isNaN(parseInt(orgId))) {
    //   return errorResponse(res, "Valid orgId is required", 400);
    // }

    const parsedOrgId = parseInt(orgId, 10);

    await client.query("BEGIN");

    //  Optional: check org exists (recommended if FK not strict)
    // const orgCheck = await client.query(
    //   `SELECT id FROM organizations WHERE id = $1`,
    //   [parsedOrgId]
    // );
    // if (orgCheck.rowCount === 0) {
    //   await client.query("ROLLBACK");
    //   return errorResponse(res, "Organization not found", 404);
    // }

    //  Insert product
    const result = await client.query(
      `
      INSERT INTO products
        (product_name, description, org_id, status, is_deleted, created_by, updated_by, created_at)
      VALUES
        ($1, $2, $3, TRUE, FALSE, $4, $4, NOW())
      RETURNING *;
      `,
      [productName.trim(), description || null, parsedOrgId, userId]
    );

    const product = result.rows[0];

    //  Log action
    await logUserAction({
      userId,
      action: "CREATE",
      model: "Product",
      details: {
        productId: product.id,
        productName: product.product_name,
      },
      req,
    });

    await client.query("COMMIT");

    return res.status(201).json({
      success: true,
      message: "Product created successfully",
      data: product,
    });
  } catch (err) {
    await client.query("ROLLBACK");
    console.error("Create Product Error:", err);
    return errorResponse(res, "Failed to create product", 500, err);
  } finally {
    client.release();
  }
};




const getProductById = async (req, res) => {
  try {
    const product = await Product.findById(req.params.id)
      .populate("category", "name")
      .populate("subcategory", "name")
      .populate("variant", "variantName values")
      .populate("brand", "brandName")
      .populate("createdBy", "firstName lastName role")
      .populate("updatedBy", "firstName lastName role")

    if (!product) return errorResponse(res, "Product not found", 404);

    await logUserAction({
      // userId: req.user?._id,
      userId: req.user?.id,
      action: "READ",
      model: "Product",
      details: { productId: product._id },
      req
    });

    return res.json({
      success: true,
      message: "Product fetched successfully",
      data: product,
    });
  } catch (err) {
    return errorResponse(res, "Failed to fetch product", 500, err);
  }
};

// GET all Products (with pagination)
// const getProducts = 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 [products, total] = await Promise.all([
//       Product.find(query)
//         .populate("category", "categoryName")
//         .populate("subcategory", "subCategoryName")
//         .populate("variant", "variantName values")
//         .skip(skip)
//         .limit(limit)
//         .sort({ createdAt: -1 }),
//       Product.countDocuments(query),
//     ]);

//     await logUserAction({
//       userId: req.user?._id,
//       action: "READ",
//       model: "Product",
//       details: { page, limit, count: products.length },
//       req
//     });

//     return res.json({
//       success: true,
//       total,
//       page,
//       totalPages: Math.ceil(total / limit),
//       data: products,
//     });
//   } catch (err) {
//     return errorResponse(res, "Failed to fetch products", 500, err);
//   }
// };
// const getProducts = 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 [products, total] = await Promise.all([
//       Product.find(query)
//         // .populate("category", "categoryName")
//         // .populate("subcategory", "subCategoryName")
//         // .populate("variant", "variantName values")
//         .populate("createdBy", "firstName lastName role")
//         .populate("updatedBy", "firstName lastName role")
//         .skip(skip)
//         .limit(limit)
//         .sort({ createdAt: -1 })
//         .lean(), // 🔥 IMPORTANT
//       Product.countDocuments(query),
//     ]);

//     // 🔥 FIX: Convert image paths to public URLs
//     const formattedProducts = products.map((product) => {
//       const images = Array.isArray(product.images)
//         ? product.images.map((img) => {
//           const cleanPath = img.startsWith("/")
//             ? img.slice(1)
//             : img;

//           return `${req.protocol}://${req.get("host")}/${cleanPath}`;
//         })
//         : [];

//       return {
//         ...product,
//         images,
//         category: product.category
//           ? { id: product.category._id, name: product.category.categoryName }
//           : null,
//         subcategory: product.subcategory
//           ? { id: product.subcategory._id, name: product.subcategory.subCategoryName }
//           : null,
//       };
//     });


//     await logUserAction({
//       // userId: req.user?._id,
//       userId: req.user?.id,
//       action: "READ",
//       model: "Product",
//       details: { page, limit, count: formattedProducts.length },
//       req,
//     });

//     return res.json({
//       success: true,
//       // total,
//       page,
//       totalPages: Math.ceil(total / limit),
//       totalRecords: total,
//       data: formattedProducts, // ✅ SEND FORMATTED DATA
//     });
//   } catch (err) {
//     console.error("Get products error:", err);
//     return errorResponse(res, "Failed to fetch products", 500, err);
//   }
// };


// UPDATE Product
const getProducts = async (req, res) => {
  const client = await pool.connect();

  try {
    let { page = 1, limit = 10 } = req.query;

    page = parseInt(page, 10);
    limit = parseInt(limit, 10);

    if (isNaN(page) || page < 1) page = 1;
    if (isNaN(limit) || limit < 1) limit = 10;

    const offset = (page - 1) * limit;

    // Main Query (populate replacement using JOIN)
    const dataQuery = `
      SELECT 
        p.id,
        p.product_name AS "productName",
        p.description,
        p.status,
        p.created_at AS "createdAt",
        p.updated_at AS "updatedAt",

        -- Created By
        json_build_object(
          'id', cu.id,
          'firstName', cu.first_name,
          'lastName', cu.last_name,
          'role', cu.role
        ) AS "createdBy",

        -- Updated By
        json_build_object(
          'id', uu.id,
          'firstName', uu.first_name,
          'lastName', uu.last_name,
          'role', uu.role
        ) AS "updatedBy"

      FROM products p
      LEFT JOIN users cu ON p.created_by = cu.id
      LEFT JOIN users uu ON p.updated_by = uu.id

      WHERE p.is_deleted = FALSE

      ORDER BY p.created_at DESC
      LIMIT $1 OFFSET $2;
    `;

    // Count Query
    const countQuery = `
      SELECT COUNT(*) FROM products WHERE is_deleted = FALSE;
    `;

    const [dataResult, countResult] = await Promise.all([
      client.query(dataQuery, [limit, offset]),
      client.query(countQuery),
    ]);

    const total = parseInt(countResult.rows[0].count, 10);
    const products = dataResult.rows;

    // (Optional) Images formatting — only if you store images
    const formattedProducts = products.map((product) => {
      let images = [];

      if (Array.isArray(product.images)) {
        images = product.images.map((img) => {
          const cleanPath = img.startsWith("/") ? img.slice(1) : img;
          return `${req.protocol}://${req.get("host")}/${cleanPath}`;
        });
      }

      return {
        ...product,
        images,
      };
    });

    // Log action
    await logUserAction({
      userId: req.user?.id,
      action: "READ",
      model: "Product",
      details: { page, limit, count: formattedProducts.length },
      req,
    });

    return res.json({
      success: true,
      page,
      totalPages: Math.ceil(total / limit),
      totalRecords: total,
      data: formattedProducts,
    });
  } catch (err) {
    console.error("Get products error:", err);
    return errorResponse(res, "Failed to fetch products", 500, err);
  } finally {
    client.release();
  }
};

// const updateProduct = async (req, res) => {
//   try {
//     const updatedData = { ...req.body, updatedBy: req.user?._id };

//     // added later
    
//     if (req.body.status !== undefined) {
//       updatedData.status =
//         req.body.status === "true" || req.body.status === true;
//     }

//     const product = await Product.findByIdAndUpdate(req.params.id, updatedData, { new: true, runValidators: true })
//       // .populate("category", "name")
//       // .populate("subcategory", "name")
//       // .populate("variant", "variantName values")
//       // .populate("brand", "brandName")

//     if (!product) return errorResponse(res, "Product not found", 404);

//     await logUserAction({
//       // userId: req.user?._id,
//       userId: req.user?._id,
//       action: "UPDATE",
//       model: "Product",
//       details: { productId: product._id, updatedFields: req.body },
//       req
//     });

//     return res.json({
//       success: true,
//       message: "Product updated successfully",
//       data: product,
//     });
//   } catch (err) {
//     return errorResponse(res, "Failed to update product", 500, err);
//   }
// };

// UPDATE Product status
const updateProduct = async (req, res) => {
  const client = await pool.connect();

  try {
    const productId = parseInt(req.params.id, 10);
    const userId = req.user?.id || null;
    const updates = req.body;

    //  Validate ID
    if (!productId || isNaN(productId)) {
      return errorResponse(res, "Invalid product ID", 400);
    }

    await client.query("BEGIN");

    //  Check product exists
    const existingRes = await client.query(
      `SELECT * FROM products WHERE id = $1 AND is_deleted = FALSE`,
      [productId]
    );

    if (existingRes.rowCount === 0) {
      await client.query("ROLLBACK");
      return errorResponse(res, "Product not found", 404);
    }

    // Allowed fields mapping
    const allowedFields = {
      productName: "product_name",
      description: "description",
      status: "status",
      orgId: "org_id",
    };

    const fields = [];
    const values = [];
    let index = 1;

    // Build dynamic query
    for (const key in updates) {
      if (allowedFields[key] && updates[key] !== undefined) {
        let value = updates[key];

        //  Handle boolean status
        if (key === "status") {
          value = value === "true" || value === true;
        }

        //  Handle object → id (safety)
        if (typeof value === "object") {
          value = value?.id;
        }

        //  Prevent NaN / invalid
        if (value === null || value === "" || isNaN(value) && key === "orgId") {
          continue;
        }

        fields.push(`${allowedFields[key]} = $${index}`);
        values.push(value);
        index++;
      }
    }

    // Always update audit fields
    fields.push(`updated_by = $${index}`);
    values.push(userId);
    index++;

    fields.push(`updated_at = NOW()`);

    if (fields.length === 0) {
      await client.query("ROLLBACK");
      return errorResponse(res, "No valid fields to update", 400);
    }

    // Update query
    const updateQuery = `
      UPDATE products
      SET ${fields.join(", ")}
      WHERE id = $${index} AND is_deleted = FALSE
      RETURNING *;
    `;

    values.push(productId);

    const updateRes = await client.query(updateQuery, values);
    const product = updateRes.rows[0];

    //  Log action
    await logUserAction({
      userId,
      action: "UPDATE",
      model: "Product",
      details: {
        productId: product.id,
        updatedFields: updates,
      },
      req,
    });

    await client.query("COMMIT");

    return res.json({
      success: true,
      message: "Product updated successfully",
      data: product,
    });
  } catch (err) {
    await client.query("ROLLBACK");
    return errorResponse(res, "Failed to update product", 500, err);
  } finally {
    client.release();
  }
};

const updateProductStatus = async (req, res) => {
  try {
    const { status } = req.body;
    if (typeof status !== "boolean") return errorResponse(res, "Invalid status value", 400);

    const product = await Product.findByIdAndUpdate(req.params.id, { status, updatedBy: req.user?._id }, { new: true });
    if (!product) return errorResponse(res, "Product not found", 404);

    await logUserAction({
      userId: req.user?._id,
      action: "UPDATE_STATUS",
      model: "Product",
      details: { productId: product._id, status },
      req
    });

    return res.json({
      success: true,
      message: "Product status updated successfully",
      data: product,
    });
  } catch (err) {
    return errorResponse(res, "Failed to update product status", 500, err);
  }
};

// SOFT DELETE Product
// const deleteProduct = async (req, res) => {
//   try {
//     const userId = req.user?._id;
//     const product = await Product.findByIdAndUpdate(req.params.id, { isDeleted: true, updatedBy: userId }, { new: true });
//     if (!product) return errorResponse(res, "Product not found", 404);

//     await logUserAction({
//       userId,
//       action: "DELETE",
//       model: "Product",
//       details: { productId: product._id },
//       req
//     });

//     return res.json({
//       success: true,
//       message: "Product deleted successfully",
//       data: product,
//     });
//   } catch (err) {
//     return errorResponse(res, "Failed to delete product", 500, err);
//   }
// };

const deleteProduct = async (req, res) => {
  const client = await pool.connect();

  try {
    const productId = parseInt(req.params.id, 10);
    const userId = req.user?.id || null;

    //  Validate ID
    if (!productId || isNaN(productId)) {
      return errorResponse(res, "Invalid product ID", 400);
    }

    await client.query("BEGIN");

    //  Soft delete
    const result = await client.query(
      `
      UPDATE products
      SET is_deleted = TRUE,
          updated_by = $1,
          updated_at = NOW()
      WHERE id = $2 AND is_deleted = FALSE
      RETURNING *;
      `,
      [userId, productId]
    );

    if (result.rowCount === 0) {
      await client.query("ROLLBACK");
      return errorResponse(res, "Product not found", 404);
    }

    const product = result.rows[0];

    //  Log action
    await logUserAction({
      userId,
      action: "DELETE",
      model: "Product",
      details: { productId: product.id },
      req,
    });

    await client.query("COMMIT");

    return res.json({
      success: true,
      message: "Product deleted successfully",
      data: product,
    });
  } catch (err) {
    await client.query("ROLLBACK");
    return errorResponse(res, "Failed to delete product", 500, err);
  } finally {
    client.release();
  }
};

module.exports = {
  createProduct,
  getProducts,
  getProductById,
  updateProduct,
  updateProductStatus,
  deleteProduct,
};
