import fs from "fs";
import path from "path";
import Product, { InfoSectionLibrary } from "../models/productsModel.js";
import Category from "../models/categoryModel.js";

/* --------------------------------------------------
    Helper
-------------------------------------------------- */
function parseJSON(val) {
    try {
        return typeof val === "string" ? JSON.parse(val) : val;
    } catch {
        return val;
    }
}

/* --------------------------------------------------
    GLOBAL INFO LIBRARY
-------------------------------------------------- */
export const getInfoLibrary = async () => {
    let lib = await InfoSectionLibrary.findById("GLOBAL_INFO_LIBRARY");
    if (!lib) {
        lib = await InfoSectionLibrary.create({
            _id: "GLOBAL_INFO_LIBRARY",
            sections: [],
        });
    }
    return lib.sections;
};

export const saveInfoLibrary = async (list) => {
    return await InfoSectionLibrary.findByIdAndUpdate(
        "GLOBAL_INFO_LIBRARY",
        { sections: list },
        { new: true, upsert: true }
    );
};

/* --------------------------------------------------
    CREATE PRODUCT
-------------------------------------------------- */
export const createProduct = async (body, files) => {
    const categoryExists = await Category.findById(body.category);
    if (!categoryExists) throw new Error("Category not found");

    body.infoSections = parseJSON(body.infoSections || []);
    body.options = parseJSON(body.options || []);
    body.modifiers = parseJSON(body.modifiers || []);
    body.variants = parseJSON(body.variants || []);

    // ✅ Ensure rating and reviews are numeric and defaulted
    body.rating = body.rating ? Number(body.rating) : 0;
    body.reviewsCount = body.reviewsCount ? Number(body.reviewsCount) : 0;

    const media = [];
    if (files && files.length > 0) {
        for (const f of files) {
            media.push({
                url: `/uploads/products/${f.filename}`,
                type: f.mimetype.includes("video") ? "video" : "image",
            });
        }
    }

    return await Product.create({ ...body, media });
};

/* --------------------------------------------------
    UPDATE PRODUCT
-------------------------------------------------- */
export const updateProduct = async (id, updates, files) => {
    const product = await Product.findById(id);
    if (!product) throw new Error("Product not found");

    updates.infoSections = parseJSON(updates.infoSections || []);
    updates.options = parseJSON(updates.options || []);
    updates.modifiers = parseJSON(updates.modifiers || []);
    updates.variants = parseJSON(updates.variants || []);

    // ✅ Normalize rating and reviewsCount
    if (updates.rating !== undefined)
        updates.rating = Number(updates.rating) || 0;

    if (updates.reviewsCount !== undefined)
        updates.reviewsCount = Number(updates.reviewsCount) || 0;

    // ✅ Add new media files if provided
    if (files && files.length > 0) {
        files.forEach((f) => {
            product.media.push({
                url: `/uploads/products/${f.filename}`,
                type: f.mimetype.includes("video") ? "video" : "image",
            });
        });
    }

    Object.assign(product, updates);
    await product.save();

    return product;
};

/* --------------------------------------------------
    GET ALL PRODUCTS (pagination + sorting + search)
-------------------------------------------------- */
export const getProducts = async ({
    page = 1,
    limit = 10,
    sort = "createdAt",
    order = "desc",
    search = "",
    category,
}) => {
    const query = {};

    // Search filter
    if (search) {
        query.name = { $regex: search, $options: "i" };
    }

    // Category filter
    if (category) {
        query.category = category;
    }

    const skip = (page - 1) * limit;
    const total = await Product.countDocuments(query);

    const products = await Product.find(query)
        .populate("category")
        .sort({ [sort]: order === "asc" ? 1 : -1 })
        .skip(skip)
        .limit(Number(limit));

    return {
        total,
        page: Number(page),
        limit: Number(limit),
        pages: Math.ceil(total / limit),
        products,
    };
};

/* --------------------------------------------------
    GET PRODUCT BY ID
-------------------------------------------------- */
export const getProductId = async (id) => {
    return await Product.findById(id).populate("category");
};

/* --------------------------------------------------
    DELETE PRODUCT (with uploaded images)
-------------------------------------------------- */
export const deleteProduct = async (id) => {
    const product = await Product.findById(id);
    if (!product) throw new Error("Product not found");

    // Delete uploaded files safely
    product.media.forEach((file) => {
        const filePath = path.join(process.cwd(), file.url);
        if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
    });

    await Product.findByIdAndDelete(id);
    return { message: "Product deleted successfully" };
};

/* --------------------------------------------------
    GET PRODUCTS BY CATEGORY
-------------------------------------------------- */
export const getProductsByCategory = async (categoryId) => {
    return await Product.find({ category: categoryId })
        .populate("category")
        .sort({ createdAt: -1 });
};
