const { Scenes, Markup } = require('telegraf'); const Product = require('../../models/Product'); const Category = require('../../models/Category'); const userController = require('../../controllers/userController'); const addProductScene = new Scenes.WizardScene( 'ADD_PRODUCT_SCENE', // Step 1: Ask Category (First!) async (ctx) => { // Ensure localization logic if (!ctx.i18n) { const locales = require('../../locales'); const User = require('../../models/User'); const user = await User.findOne({ id: ctx.from.id }); ctx.i18n = locales[user ? user.language : 'uz']; } const i18n = ctx.i18n; // Init State ctx.wizard.state.product = { media: [] }; const categories = await Category.find(); let buttons = categories.map(c => c.name); buttons.push(i18n.admin.new_cat || "āž• Yangi Kategoriya"); buttons.push(i18n.btn_cancel || "āŒ Bekor qilish"); // Filter out any undefined values to prevent crashes buttons = buttons.filter(b => b); ctx.reply(i18n.admin.enter_cat || "šŸ“‚ Kategoriyani tanlang:", Markup.keyboard(buttons, { columns: 2 }).resize()); return ctx.wizard.next(); }, // Step 2: Handle Category -> Ask Name async (ctx) => { const i18n = ctx.i18n; const text = ctx.message?.text; if (text === i18n.btn_cancel) { ctx.scene.leave(); userController.start(ctx, i18n.cancel_process); return; } if (text === (i18n.admin.new_cat || "āž• Yangi Kategoriya")) { ctx.wizard.state.isNewCategory = true; ctx.reply(i18n.admin.enter_new_cat, Markup.keyboard([[i18n.btn_cancel]]).resize()); return ctx.wizard.selectStep(2); // Go to New Category Handler } // Validate Existing Category // We accept text input as category name too, or check against DB if strict ctx.wizard.state.product.category = text; ctx.reply(i18n.admin.add_product_title || "āœļø Mahsulot nomini kiriting:", Markup.keyboard([[i18n.btn_cancel]]).resize()); return ctx.wizard.selectStep(3); // Go to Name Handler }, // Step 3: Handle New Category (If selected) -> Then Ask Name async (ctx) => { const i18n = ctx.i18n; const text = ctx.message?.text; if (text === i18n.btn_cancel) { ctx.scene.leave(); userController.start(ctx, i18n.cancel_process); return; } // Save New Category try { await new Category({ id: Date.now().toString(), name: text }).save(); ctx.reply(`${i18n.admin.new_cat}: ${text}`); ctx.wizard.state.product.category = text; ctx.reply(i18n.admin.add_product_title || "āœļø Mahsulot nomini kiriting:", Markup.keyboard([[i18n.btn_cancel]]).resize()); return ctx.wizard.next(); } catch (e) { ctx.reply("Xatolik: " + e.message); return; } }, // Step 4: Handle Name -> Ask Condition (ctx) => { const i18n = ctx.i18n; if (ctx.message.text === i18n.btn_cancel) return ctx.scene.leave(); ctx.wizard.state.product.name = ctx.message.text; ctx.reply("šŸ†• Mahsulot holatini tanlang:", Markup.keyboard([ ["šŸ†• Yangi", "ā™»ļø B/U"], [i18n.btn_cancel] ]).resize()); return ctx.wizard.next(); }, // Step 5: Handle Condition -> Ask Price (ctx) => { const i18n = ctx.i18n; const text = ctx.message.text; if (text === i18n.btn_cancel) { ctx.scene.leave(); userController.start(ctx, i18n.cancel_process); return; } if (text === "šŸ†• Yangi") ctx.wizard.state.product.condition = "new"; else if (text === "ā™»ļø B/U") ctx.wizard.state.product.condition = "used"; else return ctx.reply("Iltimos tugmani tanlang: Yangi yoki B/U"); ctx.reply(i18n.admin.enter_price, Markup.keyboard([[i18n.btn_cancel]]).resize()); return ctx.wizard.next(); }, // Step 6: Handle Price -> Ask Quantity (ctx) => { const i18n = ctx.i18n; if (ctx.message.text === i18n.btn_cancel) return ctx.scene.leave(); if (isNaN(ctx.message.text)) return ctx.reply(i18n.admin.error_num); ctx.wizard.state.product.price = parseInt(ctx.message.text); ctx.reply(i18n.admin.enter_qty, Markup.keyboard([[i18n.btn_cancel]]).resize()); return ctx.wizard.next(); }, // Step 7: Handle Quantity -> Ask Description (ctx) => { const i18n = ctx.i18n; if (ctx.message.text === i18n.btn_cancel) return ctx.scene.leave(); if (isNaN(ctx.message.text)) return ctx.reply(i18n.admin.error_num); ctx.wizard.state.product.quantity = parseInt(ctx.message.text); ctx.reply(i18n.admin.enter_desc, Markup.keyboard([[i18n.btn_cancel]]).resize()); return ctx.wizard.next(); }, // Step 8: Handle Description -> Ask Media (ctx) => { const i18n = ctx.i18n; if (ctx.message.text === i18n.btn_cancel) return ctx.scene.leave(); ctx.wizard.state.product.description = ctx.message.text; ctx.reply(i18n.admin.media_prompt, Markup.keyboard([i18n.admin.media_done, i18n.btn_cancel]).resize()); return ctx.wizard.next(); }, // Step 9: Handle Media Loop async (ctx) => { const i18n = ctx.i18n; const msg = ctx.message; if (msg.text === i18n.btn_cancel) { ctx.scene.leave(); userController.start(ctx, i18n.cancel_process); return; } if (msg.text === i18n.admin.media_done) { if (ctx.wizard.state.product.media.length === 0) return ctx.reply(i18n.admin.media_error); // Save Product try { const productData = { id: Date.now(), ...ctx.wizard.state.product }; await new Product(productData).save(); ctx.reply(`āœ… Saqlandi!\n\n${productData.name} (${productData.condition === 'new' ? 'šŸ†•' : 'ā™»ļø'})\nšŸ“‚ ${productData.category}`, { parse_mode: 'HTML' }); userController.start(ctx); return ctx.scene.leave(); } catch (e) { console.error(e); ctx.reply("Error"); return ctx.scene.leave(); } } if (msg.photo) { ctx.wizard.state.product.media.push({ type: 'photo', file_id: msg.photo[msg.photo.length - 1].file_id }); ctx.reply(`Rasm (${ctx.wizard.state.product.media.length}/4)`); } else if (msg.video) { ctx.wizard.state.product.media.push({ type: 'video', file_id: msg.video.file_id }); ctx.reply(`Video (${ctx.wizard.state.product.media.length}/4)`); } } ); module.exports = addProductScene;