import { getDb } from './db.js'; // Helper to add months or years to a date string (YYYY-MM-DD) function advanceDate(dateStr, period) { const date = new Date(dateStr); if (period === 'yearly') { date.setFullYear(date.getFullYear() + 1); } else { date.setMonth(date.getMonth() + 1); } return date.toISOString().slice(0, 10); } export async function checkSubscriptions(bot) { if (!bot) { console.log('Scheduler: Bot is not initialized. Skipping subscription checks.'); return; } console.log('πŸ•°οΈ Running scheduled subscription checks...'); const db = getDb(); const todayStr = new Date().toISOString().slice(0, 10); // Calculate tomorrow's date const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const tomorrowStr = tomorrow.toISOString().slice(0, 10); try { // 1. Pre-notification for tomorrow's payments const upcomingSubs = await db.all( 'SELECT * FROM subscriptions WHERE active = 1 AND next_payment_date = ?', tomorrowStr ); for (const sub of upcomingSubs) { try { await bot.telegram.sendMessage( sub.user_id, `πŸ”” **НапоминаниС ΠΎ подпискС!**\n\nΠ—Π°Π²Ρ‚Ρ€Π° оТидаСтся ΠΎΠΏΠ»Π°Ρ‚Π° подписки *${sub.name}* Π½Π° сумму *${sub.amount} β‚½*.`, { parse_mode: 'Markdown' } ); console.log(`Sent upcoming subscription warning to user ${sub.user_id} for sub: ${sub.name}`); } catch (err) { console.error(`Failed to send Telegram message to user ${sub.user_id}:`, err.message); } } // 2. Process today's payments (Notify + Log Expense + Advance Date) const todaySubs = await db.all( 'SELECT * FROM subscriptions WHERE active = 1 AND next_payment_date <= ?', todayStr ); for (const sub of todaySubs) { try { await db.run('BEGIN TRANSACTION'); // 1. Log transaction expense await db.run( 'INSERT INTO transactions (user_id, type, amount, category, description, date) VALUES (?, ?, ?, ?, ?, ?)', sub.user_id, 'expense', sub.amount, 'РазвлСчСния', `Подписка: ${sub.name}`, todayStr ); // 2. Advance next payment date const newPaymentDate = advanceDate(sub.next_payment_date, sub.period); await db.run( 'UPDATE subscriptions SET next_payment_date = ? WHERE id = ?', newPaymentDate, sub.id ); await db.run('COMMIT'); // 3. Notify user in Telegram await bot.telegram.sendMessage( sub.user_id, `πŸ“… **БписаниС ΠΏΠΎ подпискС!**\n\nБСгодня ΠΎΠΏΠ»Π°Ρ‡Π΅Π½Π° подписка *${sub.name}* Π½Π° сумму *${sub.amount} β‚½*.\n` + `πŸ’Έ Расход автоматичСски Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ Π² ΠΈΡΡ‚ΠΎΡ€ΠΈΡŽ.\n` + `πŸ“† Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΠ»Π°Ρ‚Π΅ΠΆ Π·Π°ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½ Π½Π°: *${newPaymentDate}*`, { parse_mode: 'Markdown' } ); console.log(`Processed subscription payment for sub: ${sub.name}, advanced to: ${newPaymentDate}`); } catch (err) { try { await db.run('ROLLBACK'); } catch (_) {} console.error(`Failed to process payment for subscription ${sub.name} (${sub.id}):`, err); } } } catch (err) { console.error('Error checking subscriptions:', err); } } // Start daily check intervals export function startScheduler(bot) { // Run check immediately on start setTimeout(() => checkSubscriptions(bot), 5000); // Run checks every 12 hours (12 * 60 * 60 * 1000 ms) const intervalMs = 12 * 60 * 60 * 1000; setInterval(() => { checkSubscriptions(bot); }, intervalMs); console.log('⏰ Subscription scheduler successfully started (checks every 12 hours).'); }