const modelCategory = require('../models/category.model');
const modelProduct = require('../models/product.model');
const fs = require('fs');
const path = require('path');

const slugify = require('slugify');

class categoryServices {
    async createCategory({ nameCategory, parentId, isActive, image, level }) {
        const slug = slugify(nameCategory, {
            replacement: '-', // replace spaces with replacement character, defaults to `-`
            remove: undefined, // remove characters that match regex, defaults to `undefined`
            lower: true, // convert to lower case, defaults to `false`
            strict: false, // strip special characters except replacement, defaults to `false`
            locale: 'vi', // language code of the locale to use
            trim: true, // trim leading and trailing replacement chars, defaults to `true`
        });
        const category = await modelCategory.create({
            nameCategory,
            slug,
            parentId,
            isActive,
            image,
            level,
        });
        return category;
    }

    async getAllCategory() {
        // Use lean() to get plain objects that we can attach properties to
        const categories = await modelCategory.find({}).lean();

        // Use Promise.all to handle async tasks in parallel
        const categoryWithCount = await Promise.all(
            categories.map(async (item) => {
                // Chỉ đếm sản phẩm còn available (chưa bán)
                const count = await modelProduct.countDocuments({
                    categoryId: item._id,
                    status: 'available',
                });
                return {
                    ...item,
                    productCount: count,
                };
            }),
        );

        return categoryWithCount;
    }

    async updateCategory({ id, nameCategory, slug, parentId, isActive, image, oldImage, level }) {
        // If there's a new image and an old image exists, delete the old one
        if (image && oldImage) {
            const oldImagePath = path.join(__dirname, '../uploads/category', oldImage);
            if (fs.existsSync(oldImagePath)) {
                fs.unlinkSync(oldImagePath);
            }
        }

        // If no new image is uploaded, keep the old one (implied by logic, but ensuring update object structure)
        const updateData = {
            nameCategory,
            slug,
            parentId,
            isActive,
            level,
        };
        if (image) {
            updateData.image = image;
        }

        const category = await modelCategory.findByIdAndUpdate(id, updateData, { new: true });
        return category;
    }

    async deleteCategory(id) {
        // Find category to delete image
        const category = await modelCategory.findById(id);
        if (category && category.image) {
            const imagePath = path.join(__dirname, '../uploads/category', category.image);
            if (fs.existsSync(imagePath)) {
                fs.unlinkSync(imagePath);
            }
        }
        await modelCategory.findByIdAndDelete(id);
        return true;
    }
}

module.exports = new categoryServices();
