import { createClient, SupabaseClient } from '@supabase/supabase-js'; const supabaseUrl = process.env.SUPABASE_URL || ''; const supabaseAnonKey = process.env.SUPABASE_ANON_KEY || ''; let _client: SupabaseClient | null = null; const getClient = (): SupabaseClient => { if (!_client) { if (!supabaseUrl || !supabaseAnonKey) { throw new Error('Supabase credentials not configured. Add SUPABASE_URL and SUPABASE_ANON_KEY to environment variables.'); } _client = createClient(supabaseUrl, supabaseAnonKey); } return _client; }; export interface VendorDailyRow { id?: number; date: string; market: string; asin: string; product_title: string | null; tags: string | null; bsr_top_rank: number | null; bsr_top_category: string | null; bsr_detail_rank: number | null; bsr_detail_category: string | null; avg_rating: number | null; num_reviews: number | null; buybox_owner: string | null; buybox_price: number | null; amazon_has_buybox: boolean | null; glance_views: number | null; } export interface VendorFilters { markets?: string[]; tags?: string[]; asins?: string[]; dateFrom?: string; dateTo?: string; } export const fetchVendorData = async (filters: VendorFilters): Promise => { const allRows: VendorDailyRow[] = []; let offset = 0; const pageSize = 1000; let hasMore = true; while (hasMore) { let query = getClient() .from('vendor_daily_data') .select('*') .order('date', { ascending: true }) .range(offset, offset + pageSize - 1); if (filters.markets?.length) { query = query.in('market', filters.markets); } if (filters.tags?.length) { query = query.in('tags', filters.tags); } if (filters.asins?.length) { query = query.in('asin', filters.asins); } if (filters.dateFrom) { query = query.gte('date', filters.dateFrom); } if (filters.dateTo) { query = query.lte('date', filters.dateTo); } const { data, error } = await query; if (error) throw error; if (data) { allRows.push(...data); hasMore = data.length === pageSize; offset += pageSize; } else { hasMore = false; } } return allRows; }; export const fetchVendorFilterOptions = async (): Promise<{ markets: string[]; tags: string[]; dateRange: { min: string; max: string } | null; }> => { const client = getClient(); const { data: marketData } = await client .from('vendor_daily_data') .select('market'); const { data: tagData } = await client .from('vendor_daily_data') .select('tags'); const { data: dateMin } = await client .from('vendor_daily_data') .select('date') .order('date', { ascending: true }) .limit(1); const { data: dateMax } = await client .from('vendor_daily_data') .select('date') .order('date', { ascending: false }) .limit(1); const markets = [...new Set((marketData || []).map(r => r.market))].sort(); const tags = [...new Set((tagData || []).map(r => r.tags).filter(Boolean))].sort(); return { markets, tags, dateRange: dateMin?.[0] && dateMax?.[0] ? { min: dateMin[0].date, max: dateMax[0].date } : null, }; };