import type { EnhancedProductAnalysis, SearchConfig, GeneratedQuery, SearchStrategy, PlatformId } from './types' const DEFAULT_PLATFORMS: Record = { reddit: { name: 'Reddit', rateLimit: 30 }, twitter: { name: 'X/Twitter', rateLimit: 20 }, hackernews: { name: 'Hacker News', rateLimit: 30 }, indiehackers: { name: 'Indie Hackers', rateLimit: 20 }, quora: { name: 'Quora', rateLimit: 20 }, stackoverflow: { name: 'Stack Overflow', rateLimit: 30 }, linkedin: { name: 'LinkedIn', rateLimit: 15 } } export function getDefaultPlatforms(): Record { return { reddit: { name: 'Reddit', icon: 'MessageSquare', rateLimit: 30, enabled: true }, twitter: { name: 'X/Twitter', icon: 'Twitter', rateLimit: 20, enabled: true }, hackernews: { name: 'Hacker News', icon: 'HackerIcon', rateLimit: 30, enabled: true }, indiehackers: { name: 'Indie Hackers', icon: 'Users', rateLimit: 20, enabled: false }, quora: { name: 'Quora', icon: 'HelpCircle', rateLimit: 20, enabled: false }, stackoverflow: { name: 'Stack Overflow', rateLimit: 30, enabled: false }, linkedin: { name: 'LinkedIn', rateLimit: 15, enabled: false } } } export function generateSearchQueries( analysis: EnhancedProductAnalysis, config: SearchConfig ): GeneratedQuery[] { const queries: GeneratedQuery[] = [] const enabledPlatforms = config.platforms.filter(p => p.enabled) enabledPlatforms.forEach(platform => { config.strategies.forEach(strategy => { const strategyQueries = buildStrategyQueries(strategy, analysis, platform.id) queries.push(...strategyQueries) }) }) const deduped = sortAndDedupeQueries(queries) const limited = deduped.slice(0, config.maxResults || 50) console.info( `[opportunities] queries: generated=${queries.length} deduped=${deduped.length} limited=${limited.length}` ) return limited } function buildStrategyQueries( strategy: SearchStrategy, analysis: EnhancedProductAnalysis, platform: PlatformId ): GeneratedQuery[] { switch (strategy) { case 'direct-keywords': return buildDirectKeywordQueries(analysis, platform) case 'problem-pain': return buildProblemQueries(analysis, platform) case 'competitor-alternative': return buildCompetitorQueries(analysis, platform) case 'how-to': return buildHowToQueries(analysis, platform) case 'emotional-frustrated': return buildEmotionalQueries(analysis, platform) case 'comparison': return buildComparisonQueries(analysis, platform) case 'recommendation': return buildRecommendationQueries(analysis, platform) default: return [] } } function buildDirectKeywordQueries(analysis: EnhancedProductAnalysis, platform: PlatformId): GeneratedQuery[] { const keywords = analysis.keywords .filter(k => k.type === 'product' || k.type === 'feature') .slice(0, 8) const templates: Record = { reddit: ['("looking for" OR "need" OR "recommendation")', '("what do you use" OR "suggestion")'], twitter: ['("looking for" OR "need")', '("any recommendations" OR "suggestions")'], hackernews: ['("Ask HN")'], indiehackers: ['("looking for" OR "need")'], quora: ['("what is the best" OR "how do I choose")'], stackoverflow: ['("best tool for" OR "recommendation")'], linkedin: ['("looking for" OR "seeking")'] } return keywords.flatMap(kw => (templates[platform] || templates.reddit).map(template => ({ query: buildPlatformQuery(platform, `"${kw.term}" ${template}`), platform, strategy: 'direct-keywords' as SearchStrategy, priority: 3, expectedIntent: 'looking' })) ) } function buildProblemQueries(analysis: EnhancedProductAnalysis, platform: PlatformId): GeneratedQuery[] { const highSeverityProblems = analysis.problemsSolved .filter(p => p.severity === 'high') .slice(0, 5) return highSeverityProblems.flatMap(problem => [ { query: buildPlatformQuery(platform, `"${problem.problem}" ("how to" OR "fix" OR "solve")`), platform, strategy: 'problem-pain', priority: 5, expectedIntent: 'frustrated' }, ...problem.searchTerms.slice(0, 2).map(term => ({ query: buildPlatformQuery(platform, `"${term}"`), platform, strategy: 'problem-pain', priority: 4, expectedIntent: 'frustrated' })) ]) } function buildCompetitorQueries(analysis: EnhancedProductAnalysis, platform: PlatformId): GeneratedQuery[] { const competitors = analysis.competitors.slice(0, 5) return competitors.flatMap(comp => [ { query: buildPlatformQuery(platform, `"${comp.name}" ("alternative" OR "switching from" OR "moving away")`), platform, strategy: 'competitor-alternative', priority: 5, expectedIntent: 'comparing' }, { query: buildPlatformQuery(platform, `"${comp.name}" ("vs" OR "versus" OR "compared to" OR "better than")`), platform, strategy: 'competitor-alternative', priority: 4, expectedIntent: 'comparing' }, { query: buildPlatformQuery(platform, `"${comp.name}" ("frustrated" OR "disappointed" OR "problems with")`), platform, strategy: 'competitor-alternative', priority: 5, expectedIntent: 'frustrated' } ]) } function buildHowToQueries(analysis: EnhancedProductAnalysis, platform: PlatformId): GeneratedQuery[] { const keywords = analysis.keywords .filter(k => k.type === 'feature' || k.type === 'solution') .slice(0, 6) return keywords.map(kw => ({ query: buildPlatformQuery(platform, `"how to" "${kw.term}" ("tutorial" OR "guide" OR "help")`), platform, strategy: 'how-to', priority: 2, expectedIntent: 'learning' })) } function buildEmotionalQueries(analysis: EnhancedProductAnalysis, platform: PlatformId): GeneratedQuery[] { const keywords = analysis.keywords .filter(k => k.type === 'product' || k.type === 'problem') .slice(0, 5) const emotionalTerms = ['frustrated', 'hate', 'sucks', 'terrible', 'annoying', 'fed up', 'tired of'] return keywords.flatMap(kw => emotionalTerms.slice(0, 3).map(term => ({ query: buildPlatformQuery(platform, `"${kw.term}" ${term}`), platform, strategy: 'emotional-frustrated', priority: 4, expectedIntent: 'frustrated' })) ) } function buildComparisonQueries(analysis: EnhancedProductAnalysis, platform: PlatformId): GeneratedQuery[] { const keywords = analysis.keywords .filter(k => k.type === 'product' || k.type === 'differentiator') .slice(0, 4) return keywords.map(kw => ({ query: buildPlatformQuery(platform, `"${kw.term}" ("vs" OR "versus" OR "or" OR "comparison")`), platform, strategy: 'comparison', priority: 3, expectedIntent: 'comparing' })) } function buildRecommendationQueries(analysis: EnhancedProductAnalysis, platform: PlatformId): GeneratedQuery[] { const keywords = analysis.keywords .filter(k => k.type === 'product' || k.type === 'feature') .slice(0, 5) return keywords.map(kw => ({ query: buildPlatformQuery(platform, `("what do you use" OR "recommendation" OR "suggest") "${kw.term}"`), platform, strategy: 'recommendation', priority: 3, expectedIntent: 'recommending' })) } function buildPlatformQuery(platform: PlatformId, query: string): string { const siteOperators: Record = { reddit: 'site:reddit.com', twitter: 'site:twitter.com OR site:x.com', hackernews: 'site:news.ycombinator.com', indiehackers: 'site:indiehackers.com', quora: 'site:quora.com', stackoverflow: 'site:stackoverflow.com', linkedin: 'site:linkedin.com' } return `${siteOperators[platform]} ${query}` } function sortAndDedupeQueries(queries: GeneratedQuery[]): GeneratedQuery[] { // Sort by priority (high first) const sorted = queries.sort((a, b) => b.priority - a.priority) // Deduplicate by query string const seen = new Set() return sorted.filter(q => { const normalized = q.query.toLowerCase().replace(/\s+/g, ' ') if (seen.has(normalized)) return false seen.add(normalized) return true }) } export function estimateSearchTime(queryCount: number, platforms: PlatformId[]): number { const avgRateLimit = 25 // requests per minute return Math.ceil(queryCount / avgRateLimit) }