import { query } from '../database/connection'; import { BotError } from '../types/index'; export interface VipSearchFilters { ageMin?: number; ageMax?: number; city?: string; datingGoal?: string; hobbies?: string[]; lifestyle?: string[]; distance?: number; hasPhotos?: boolean; isOnline?: boolean; } export interface PremiumInfo { isPremium: boolean; expiresAt?: Date; daysLeft?: number; } export class VipService { // Проверить премиум статус пользователя async checkPremiumStatus(telegramId: string): Promise { try { // Проверяем существование пользователя const result = await query(` SELECT id FROM users WHERE telegram_id = $1 `, [telegramId]); if (result.rows.length === 0) { throw new BotError('User not found', 'USER_NOT_FOUND', 404); } // Временно возвращаем false для всех пользователей, так как колонки premium нет // В будущем, когда колонки будут добавлены, этот код нужно будет заменить обратно return { isPremium: false, expiresAt: undefined, daysLeft: undefined }; } catch (error) { console.error('Error checking premium status:', error); throw error; } } // Добавить премиум статус async addPremium(telegramId: string, durationDays: number = 30): Promise { try { // Временно заглушка, так как колонок premium и premium_expires_at нет console.log(`[VIP] Попытка добавить премиум для ${telegramId} на ${durationDays} дней`); // TODO: Добавить колонки premium и premium_expires_at в таблицу users } catch (error) { console.error('Error adding premium:', error); throw error; } } // Удалить премиум статус async removePremium(telegramId: string): Promise { try { // Временно заглушка, так как колонок premium и premium_expires_at нет console.log(`[VIP] Попытка удалить премиум для ${telegramId}`); // TODO: Добавить колонки premium и premium_expires_at в таблицу users } catch (error) { console.error('Error removing premium:', error); throw error; } } // VIP поиск с фильтрами async vipSearch(telegramId: string, filters: VipSearchFilters): Promise { try { // Проверяем премиум статус const premiumInfo = await this.checkPremiumStatus(telegramId); if (!premiumInfo.isPremium) { throw new BotError('Premium subscription required', 'PREMIUM_REQUIRED', 403); } // Получаем профиль пользователя const userProfile = await query(` SELECT p.*, u.telegram_id FROM profiles p JOIN users u ON p.user_id = u.id WHERE u.telegram_id = $1 `, [telegramId]); if (userProfile.rows.length === 0) { throw new BotError('Profile not found', 'PROFILE_NOT_FOUND', 404); } const currentUser = userProfile.rows[0]; // Строим запрос с фильтрами let query_text = ` SELECT p.*, u.telegram_id, CASE WHEN u.updated_at > NOW() - INTERVAL '15 minutes' THEN true ELSE false END as is_online FROM profiles p JOIN users u ON p.user_id = u.id LEFT JOIN swipes s ON ( s.swiper_id = $1 AND s.swiped_id = u.id ) WHERE u.telegram_id != $2 AND s.id IS NULL AND p.is_active = true `; let params = [currentUser.user_id, telegramId]; let paramIndex = 3; // Фильтр по противоположному полу if (currentUser.gender === 'male') { query_text += ` AND p.gender = 'female'`; } else if (currentUser.gender === 'female') { query_text += ` AND p.gender = 'male'`; } else { // Если пол не определен или 'other', показываем всех кроме того же пола query_text += ` AND p.gender != $${paramIndex}`; params.push(currentUser.gender); paramIndex++; } // Фильтр по возрасту if (filters.ageMin) { query_text += ` AND p.age >= $${paramIndex}`; params.push(filters.ageMin); paramIndex++; } if (filters.ageMax) { query_text += ` AND p.age <= $${paramIndex}`; params.push(filters.ageMax); paramIndex++; } // Фильтр по городу if (filters.city) { query_text += ` AND LOWER(p.city) LIKE LOWER($${paramIndex})`; params.push(`%${filters.city}%`); paramIndex++; } // Фильтр по цели знакомства if (filters.datingGoal) { query_text += ` AND p.dating_goal = $${paramIndex}`; params.push(filters.datingGoal); paramIndex++; } // Фильтр по хобби if (filters.hobbies && filters.hobbies.length > 0) { const hobbyConditions = filters.hobbies.map((_, index) => { return `LOWER(p.hobbies) LIKE LOWER($${paramIndex + index})`; }); query_text += ` AND (${hobbyConditions.join(' OR ')})`; filters.hobbies.forEach(hobby => { params.push(`%${hobby}%`); }); paramIndex += filters.hobbies.length; } // Фильтр по образу жизни if (filters.lifestyle && filters.lifestyle.length > 0) { const lifestyleConditions = filters.lifestyle.map((field) => { const condition = `p.lifestyle ? $${paramIndex}`; params.push(field); paramIndex++; return condition; }); query_text += ` AND (${lifestyleConditions.join(' OR ')})`; } // Фильтр по наличию фото if (filters.hasPhotos) { query_text += ` AND p.photos IS NOT NULL AND array_length(p.photos, 1) > 0`; } // Фильтр по онлайн статусу if (filters.isOnline) { query_text += ` AND u.updated_at > NOW() - INTERVAL '15 minutes'`; } query_text += ` ORDER BY CASE WHEN u.updated_at > NOW() - INTERVAL '15 minutes' THEN 0 ELSE 1 END, u.updated_at DESC, p.created_at DESC LIMIT 50`; const result = await query(query_text, params); return result.rows; } catch (error) { console.error('Error in VIP search:', error); throw error; } } // Получить информацию о премиум возможностях getPremiumFeatures(): string { return `💎 ПРЕМИУМ ПОДПИСКА 💎 🔥 Что дает VIP статус: 🎯 VIP Поиск с фильтрами: • Поиск по возрасту • Поиск по городу • Фильтр по целям знакомства • Поиск по хобби и интересам • Фильтр по образу жизни • Только пользователи с фото • Только онлайн пользователи ⚡ Дополнительные возможности: • Неограниченные супер-лайки • Просмотр кто лайкнул вас • Возможность отменить свайп • Приоритет в показе другим • Расширенная статистика • Скрытый режим просмотра 💰 Тарифы: • 1 месяц - 299₽ • 3 месяца - 699₽ (экономия 25%) • 6 месяцев - 1199₽ (экономия 33%) • 1 год - 1999₽ (экономия 44%) 📞 Для покупки обратитесь к администратору: @admin_bot ✨ Попробуйте VIP уже сегодня!`; } }