import { apiHandler, db } from "@/helpers/api";
import formidable from "formidable";
import AWS from "aws-sdk";
import fs from "fs";
import path from "path";

export const config = {
	api: {
		bodyParser: false,
	},
};

export default apiHandler({
	get: getMarketplaceProducts,
	delete: deleteMarketplaceProduct,
	post: updateMarketplaceProduct,
     put: createMarketplaceProduct, 
});

async function parseForm(req) {
	return new Promise((resolve, reject) => {
		const form = formidable({
			maxFileSize: 5 * 1024 * 1024, // 5MB per file
			allowEmptyFiles: false,
			multiples: true,
		});

		form.parse(req, (err, fields, files) => {
			if (err) reject(err);
			resolve({ fields, files });
		});
	});
}

async function getMarketplaceProducts(req, res) {
	const userID = req.userID;

	if (!db.initialized) await db.initialize();

	try {
		const userData = await db.User.findByPk(userID);

		if (!userData) return res.status(404).json({ error: "Unknown!" });
		if (userData.id != userID) return res.status(401).json({ error: "Unauthorized!" });
		if (userData.marketplace === 0) return res.status(401).json({ error: "Unauthorized!" });

		const listedProducts = await db.Products.findAll({
			where: {
				listedBy: userData.id,
			},
			order: [["id", "DESC"]],
		});

		const listedProductIDs = listedProducts.map((p) => p.id);
		const verifiedCount = listedProducts.filter((p) => p.verified === 1).length;
		const unverifiedCount = listedProducts.filter((p) => p.verified === 0).length;

		if (listedProductIDs.length === 0) {
			return res.status(200).json({
				listedProducts,
				soldTotal: 0,
				soldUnits: 0,
				verifiedCount,
				unverifiedCount,
			});
		}

		const orders = await db.Orders.findAll({
			where: db.Sequelize.literal(`
                JSON_OVERLAPS(
                    JSON_EXTRACT(items, '$[*].id'),
                    '${JSON.stringify(listedProductIDs)}'
                )
            `),
			attributes: ["items"],
		});

		let soldTotal = 0;
		let soldUnits = 0;

		for (const order of orders) {
			const items = typeof order.items === "string" ? JSON.parse(order.items) : order.items || [];

			for (const item of items) {
				if (listedProductIDs.includes(item.id)) {
					soldTotal += item.price * item.quantity;
					soldUnits += item.quantity;
				}
			}
		}

		const responseArray = [];
		responseArray.push({ listedProducts, soldTotal, soldUnits, verifiedCount, unverifiedCount });

		return res.status(200).json(responseArray);
	} catch (error) {
		console.error(error);
		return res.status(500).json({ error: "Eroare la preluarea datelor utilizatorului." });
	}
}

async function deleteMarketplaceProduct(req, res) {
	const userID = req.userID;

	if (!db.initialized) await db.initialize();

	try {
		const userData = await db.User.findByPk(userID);

		if (!userData) return res.status(404).json({ error: "Unknown!" });
		if (userData.id != userID) return res.status(401).json({ error: "Unauthorized!" });
		if (userData.marketplace === 0) return res.status(401).json({ error: "Unauthorized!" });

		const prodID = req.body.id;

		const deletedProduct = await db.Products.findOne({
			attributes: ["id", "listedBy"],
			where: {
				listedBy: userData.id,
				id: prodID,
			},
		});

		if (!deletedProduct) {
			return res.status(404).json({ error: "Produsul nu a fost găsit." });
		}

		if (deletedProduct.listedBy !== userData.id) {
			return res.status(403).json({ error: "Nu aveți permisiunea de a șterge acest produs." });
		}

		await deletedProduct.destroy();

		return res.status(200).json({ success: true, message: "Produs șters cu succes." });
	} catch (error) {
		console.error(error);
		return res.status(500).json({ error: "Eroare la ștergerea produsului." });
	}
}

async function updateMarketplaceProduct(req, res) {
	const userID = req.userID;

	if (!db.initialized) await db.initialize();

	try {
		const userData = await db.User.findByPk(userID);

		if (!userData) return res.status(404).json({ error: "Unknown!" });
		if (userData.id != userID) return res.status(401).json({ error: "Unauthorized!" });
		if (userData.marketplace === 0) return res.status(401).json({ error: "Unauthorized!" });

		// Parse form data
		const { fields, files } = await parseForm(req);

		// Extract fields (formidable v3+ returns arrays)
		const getField = (name) => (Array.isArray(fields[name]) ? fields[name][0] : fields[name]);

		const productId = getField("id");
		const name = getField("name");
		const desc = getField("desc");
		const keywords = getField("keywords");
		const price = getField("price");
		const priceReduced = getField("priceReduced");
		const stock = getField("stock");
		const existingImages = getField("existingImages");
		const specificationsRaw = getField("specifications");

		// FIX: Parse specifications correctly
		let specificationsJSON;
		try {
			// Dacă vine ca string, parse-uim
			const parsed = typeof specificationsRaw === 'string' 
				? JSON.parse(specificationsRaw) 
				: specificationsRaw;
			
			// Convertim înapoi în string pentru MySQL (fără escape dublu)
			specificationsJSON = JSON.stringify(parsed);
		} catch (e) {
			console.error('Error parsing specifications:', e);
			specificationsJSON = '[]'; // fallback
		}

		// Verify ownership
		const product = await db.Products.findOne({
			where: {
				id: productId,
				listedBy: userData.id,
			},
		});

		if (!product) {
			return res.status(404).json({ error: "Produsul nu a fost găsit." });
		}

		// Handle new image uploads
		const s3 = new AWS.S3({
			accessKeyId: 'AKIA2AFW3Y3G5AFYQX6F',
			secretAccessKey: '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',
			region: "eu-north-1",
		});

		let newImageUrls = [];

		if (files.images) {
			const imageFiles = Array.isArray(files.images) ? files.images : [files.images];

			for (const file of imageFiles) {
				const ext = path.extname(file.originalFilename || file.newFilename || "").toLowerCase();
				const allowedExt = [".jpg", ".jpeg", ".png", ".webp"];

				if (!allowedExt.includes(ext)) {
					continue;
				}

				const fileName = `products/${productId}_${Date.now()}${ext}`;
				const fileBuffer = fs.readFileSync(file.filepath);

				const uploadResult = await s3
					.upload({
						Bucket: "emagyl",
						Key: fileName,
						Body: fileBuffer,
						ContentType: file.mimetype || "image/jpeg",
						ACL: "public-read",
					})
					.promise();

				newImageUrls.push(uploadResult.Location);
			}
		}

		// Combine existing and new images
		const existingImagesArray = existingImages ? existingImages.split("|").filter(Boolean) : [];
		const finalImages = [...existingImagesArray, ...newImageUrls].join("|");

		// Update product - FOLOSIM RAW QUERY pentru a evita escape-ul dublu
		await db.sequelize.query(
			`UPDATE products SET 
				name = :name,
				\`desc\` = :desc,
				keywords = :keywords,
				price = :price,
				priceReduced = :priceReduced,
				stock = :stock,
				images = :images,
				specifications = :specifications,
				updatedAt = NOW()
			WHERE id = :productId`,
			{
				replacements: {
					name,
					desc,
					keywords,
					price: parseFloat(price),
					priceReduced: priceReduced ? parseFloat(priceReduced) : null,
					stock: parseInt(stock),
					images: finalImages,
					specifications: specificationsJSON, // JSON string fără escape dublu
					productId: productId
				},
				type: db.Sequelize.QueryTypes.UPDATE
			}
		);

		return res.status(200).json({ success: true, message: "Produs actualizat cu succes." });
	} catch (error) {
		console.error(error);
		return res.status(500).json({ error: "Eroare la actualizarea produsului." });
	}
}

async function createMarketplaceProduct(req, res) {
	const userID = req.userID;

	if (!db.initialized) await db.initialize();

	try {
		const userData = await db.User.findByPk(userID);

		if (!userData) return res.status(404).json({ error: "Unknown!" });
		if (userData.id != userID) return res.status(401).json({ error: "Unauthorized!" });
		if (userData.marketplace === 0) return res.status(401).json({ error: "Unauthorized!" });

		const { fields, files } = await parseForm(req);
		const getField = (name) => (Array.isArray(fields[name]) ? fields[name][0] : fields[name]);

		const name = getField("name");
		const desc = getField("desc");
		const keywords = getField("keywords");
		const price = getField("price");
		const priceReduced = getField("priceReduced");
		const stock = getField("stock");
		const categoryName = getField("categoryName");
		const categorySlug = getField("categorySlug");
		const subcategoryName = getField("subcategoryName");
		const subcategorySlug = getField("subcategorySlug");
		const thirdCategoryName = getField("thirdCategoryName");
		const thirdCategorySlug = getField("thirdCategorySlug");
		const specificationsRaw = getField("specifications");

		// Generate URL slug from name
		const url = name
			.toLowerCase()
			.normalize("NFD")
			.replace(/[\u0300-\u036f]/g, "")
			.replace(/[^a-z0-9]+/g, "-")
			.replace(/^-+|-+$/g, "");

		// Parse specifications
		let specificationsJSON;
		try {
			const parsed = typeof specificationsRaw === 'string' 
				? JSON.parse(specificationsRaw) 
				: specificationsRaw;
			specificationsJSON = parsed;
		} catch (e) {
			specificationsJSON = '[]';
		}

		// Create product first to get ID
		const tempProduct = await db.Products.create({
			name,
			desc,
			keywords,
			price: parseFloat(price),
			priceReduced: priceReduced ? parseFloat(priceReduced) : null,
			stock: parseInt(stock),
			images: '',
			specifications: specificationsJSON,
			categoryName,
			categorySlug,
			subcategoryName: subcategoryName || null,
			subcategorySlug: subcategorySlug || null,
			thirdCategoryName: thirdCategoryName || null,
			thirdCategorySlug: thirdCategorySlug || null,
			url,
			supplier: userData.nume_firma,
			sku: `MP-${Date.now()}`,
			ean: '',
			listedBy: userData.id,
			verified: 0,
			rejectReason: '',
		});

		// Handle image uploads with Sharp
		const sharp = require('sharp');
		const crypto = require('crypto');
		
		const s3 = new AWS.S3({
			accessKeyId: 'AKIA2AFW3Y3G5AFYQX6F',
			secretAccessKey: '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',
			region: "eu-north-1",
		});

		let imageUrls = [];

		if (files.images) {
			const imageFiles = Array.isArray(files.images) ? files.images : [files.images];
			
			// Generate UUID pentru acest produs
			const uuid = crypto.randomBytes(4).toString('hex'); // 8 caractere

			for (let index = 0; index < imageFiles.length; index++) {
				const file = imageFiles[index];
				const ext = path.extname(file.originalFilename || file.newFilename || "").toLowerCase();
				const allowedExt = [".jpg", ".jpeg", ".png", ".webp"];

				if (!allowedExt.includes(ext)) continue;

				// Citim fișierul original
				const fileBuffer = fs.readFileSync(file.filepath);
				
				// Convertim în WebP
				let processedBuffer = await sharp(fileBuffer)
					.webp({ quality: 85 })
					.toBuffer();

				// Pentru prima imagine, facem și resize 294x294 pentru card
				if (index === 0) {
					const cardBuffer = await sharp(fileBuffer)
						.resize(294, 294, {
							fit: 'cover',
							position: 'center'
						})
						.webp({ quality: 85 })
						.toBuffer();

					// Upload imagine card (294x294)
					const cardFileName = `productscards/${tempProduct.id}_${uuid}_${index + 1}.webp`;
					await s3.upload({
						Bucket: "emagyl",
						Key: cardFileName,
						Body: cardBuffer,
						ContentType: "image/webp",
						ACL: "public-read",
					}).promise();
				}

				// Upload imagine full size (în format WebP)
				const fileName = `products/${tempProduct.id}_${uuid}_${index + 1}.webp`;
				
				const uploadResult = await s3.upload({
					Bucket: "emagyl",
					Key: fileName,
					Body: processedBuffer,
					ContentType: "image/webp",
					ACL: "public-read",
				}).promise();

				imageUrls.push(uploadResult.Location);
			}

			// Înlocuim URL-urile S3 cu CloudFront
			const oldBase = "https://emagyl.s3.eu-north-1.amazonaws.com/products/";
			const newBase = "https://d372xxb7fb1cod.cloudfront.net/products/";

			const updatedImageUrls = imageUrls.map(url =>
				url.replaceAll(oldBase, newBase)
			);

			// Update produs cu imaginile
			await tempProduct.update({ images: updatedImageUrls.join('|') });

			return res.status(200).json({ success: true, message: "Produs adăugat cu succes.", productId: tempProduct.id });
		} else {
			// Ștergem produsul dacă nu sunt imagini
			await tempProduct.destroy();
			return res.status(400).json({ error: "Trebuie să adăugați cel puțin o imagine." });
		}

	} catch (error) {
		console.error(error);
		return res.status(500).json({ error: "Eroare la adăugarea produsului." });
	}
}