const { Scenes, Markup } = require('telegraf');
const Product = require('../../models/Product');
const User = require('../../models/User');
const flashSaleScene = new Scenes.WizardScene(
'admin_flash_sale',
// Step 1: Menu
async (ctx) => {
const text = "š„ **Flash Sale (Aksiya) Boshqaruvi**\n\nNima qilmoqchisiz?";
const buttons = [
[Markup.button.callback("š Aksiya Boshlash", "start_sale")],
[Markup.button.callback("š Aksiyani To'xtatish (Narxlarni tiklash)", "stop_sale")],
[Markup.button.callback("š Asosiy menyu", "back_dashboard")]
];
if (ctx.callbackQuery) {
await ctx.editMessageText(text, { parse_mode: 'Markdown', ...Markup.inlineKeyboard(buttons) });
} else {
await ctx.replyWithMarkdown(text, Markup.inlineKeyboard(buttons));
}
return ctx.wizard.next();
},
// Step 2: Handle Choice
async (ctx) => {
if (!ctx.callbackQuery && !ctx.message) return;
const txt = ctx.message ? ctx.message.text : '';
if (txt === '/start' || txt === 'ā Bekor qilish') return ctx.scene.leave();
if (ctx.callbackQuery) {
const data = ctx.callbackQuery.data;
if (data === 'back_dashboard') {
await ctx.scene.leave();
const adminController = require('../../controllers/adminController');
return adminController.showDashboard(ctx);
}
if (data === 'stop_sale') {
await ctx.answerCbQuery("Narxlar tiklanmoqda...");
// Revert Logic
const products = await Product.find({ originalPrice: { $ne: null } });
if (products.length === 0) {
await ctx.reply("ā ļø Tiklash uchun o'zgartirilgan mahsulotlar topilmadi.");
return ctx.scene.leave();
}
let count = 0;
for (let p of products) {
p.price = p.originalPrice;
p.originalPrice = null; // Clear history
p.discountPercent = 0; // Reset discount
await p.save();
count++;
}
await ctx.reply(`ā
Aksiya tugatildi.\n${count} ta mahsulot narxi joyiga qaytarildi.`, { parse_mode: 'HTML' });
return ctx.scene.leave();
}
if (data === 'start_sale') {
await ctx.reply("š Chegirma foizini kiriting:\nMasalan: 10 (10% arzonlashadi)\n\nEslatma: Bu barcha mahsulotlarga ta'sir qiladi!", { parse_mode: 'HTML', ...Markup.keyboard([['ā Bekor qilish']]).resize() });
ctx.wizard.state.action = 'get_percent';
return ctx.wizard.next();
}
}
},
// Step 3: Apply Discount
async (ctx) => {
const txt = ctx.message ? ctx.message.text : '';
if (txt === 'ā Bekor qilish') {
await ctx.reply("Bekor qilindi.", Markup.removeKeyboard());
await ctx.scene.leave();
const adminController = require('../../controllers/adminController');
return adminController.showDashboard(ctx);
}
const percent = parseInt(txt);
if (isNaN(percent) || percent <= 0 || percent >= 100) {
await ctx.reply("ā ļø Iltimos, to'g'ri foiz kiriting (1-99 oralig'ida).");
return;
}
await ctx.reply(`ā³ ${percent}% chegirma qo'llanmoqda...`);
const products = await Product.find({});
let count = 0;
for (let p of products) {
try {
// Skip invalid products (corrupt data)
if (!p.id || !p.name) {
console.warn(`Skipping invalid product (Missing ID/Name): ${p._id}`);
continue;
}
// Only update if not already discounted (prevent double discount)
// Or overwrite? Let's assume overwrite logic:
// If already has originalPrice, use THAT as base. If not, use current price.
let basePrice = p.originalPrice || p.price;
// Save original price if not already saved
if (!p.originalPrice) {
p.originalPrice = basePrice;
}
// Calculate new price
const discountAmount = (basePrice * percent) / 100;
p.price = Math.round(basePrice - discountAmount);
p.discountPercent = percent; // Save percent display
await p.save();
count++;
} catch (err) {
console.error(`Failed to update product ${p.id}:`, err.message);
}
}
const User = require('../../models/User'); // Ensure User model is required at top
// ... inside the scene ...
await ctx.reply(`ā
Aksiya Boshlandi!\n\n${count} ta mahsulot narxi ${percent}% ga arzonlashtirildi.`, { parse_mode: 'HTML', ...Markup.removeKeyboard() });
// --- BROADCAST NOTIFICATION ---
await ctx.reply("š¢ Foydalanuvchilarga xabar yuborilmoqda...");
const users = await User.find({});
let sent = 0;
const message = `š„ DIQQAT AKSIYA!\n\nš Do'konimizda FLASH SALE boshlandi!\n\nš Barcha mahsulotlarga ${percent}% CHEGIRMA e'lon qilindi.\n\nHoziroq xarid qiling, aksiya vaqti chegaralangan! ā³\n\nššš`;
for (let user of users) {
try {
await ctx.telegram.sendMessage(user.id, message, { parse_mode: 'HTML' });
sent++;
} catch (e) {
// User blocked bot or inactive
}
// Small delay to prevent spam flood
await new Promise(r => setTimeout(r, 50));
}
await ctx.reply(`š¢ Xabar ${sent} ta foydalanuvchiga yuborildi.`);
await ctx.scene.leave();
const adminController = require('../../controllers/adminController');
return adminController.showDashboard(ctx);
}
);
module.exports = flashSaleScene;