import type { AnalysisHistoryItem, AnalysisResult, CompanyProfile, Tender, PurchaseOrder } from "./types"; // Auto-detect API base URL based on environment export function getAPIBase(): string { // 1. Explicit env var (highest priority) if (process.env.NEXT_PUBLIC_API_BASE) { console.log('[API] Using explicit NEXT_PUBLIC_API_BASE:', process.env.NEXT_PUBLIC_API_BASE); return process.env.NEXT_PUBLIC_API_BASE; } // Only works on client side if (typeof window === 'undefined') { return ''; } const hostname = window.location.hostname; const protocol = window.location.protocol; // 2. Hugging Face Space detection (IMPROVED) if (hostname.includes('.hf.space')) { // If we are in the hackathon space or REWCHILE space // Direct point to the backend we just created const backendUrl = `https://rewchile-andesai-backend.hf.space`; console.log('[API] Hugging Face Space detected. Frontend:', hostname); console.log('[API] Connecting to Backend:', backendUrl); return backendUrl; } // 3. Vercel/Production detection if (hostname.includes('vercel.app')) { const backendUrl = process.env.REACT_APP_API_BASE || `${protocol}//${hostname.replace('andesai', 'andesai-api')}`; console.log('[API] Vercel environment detected. Using:', backendUrl); return backendUrl; } // 4. GitHub Pages + external API if (hostname.includes('github.io') || hostname.includes('github.dev')) { const backendUrl = process.env.REACT_APP_API_BASE || 'https://andesai-backend.fly.dev'; console.log('[API] GitHub Pages detected. Using:', backendUrl); return backendUrl; } // 5. Local development fallback console.log('[API] Local development environment detected'); return 'http://localhost:8000'; } const API_BASE = getAPIBase(); // Log API base for debugging if (typeof window !== 'undefined') { console.log('[API] Final API Base URL:', API_BASE, 'on hostname:', window.location.hostname); } const jsonHeaders = { "Content-Type": "application/json", }; export async function healthCheck() { const res = await fetch(`${API_BASE}/api/health`); if (!res.ok) { throw new Error("Health check failed"); } return res.json(); } export async function fetchDbStatus() { const res = await fetch(`${API_BASE}/api/health/db-status`); if (!res.ok) return null; return res.json(); } export async function searchTenders(params: { keyword?: string; buyer?: string; provider_code?: string; org_code?: string; status?: string; code?: string; date?: string; type_code?: string; skip?: number; limit?: number; }): Promise { const query = new URLSearchParams(); if (params.keyword) query.append("keyword", params.keyword); if (params.buyer) query.append("buyer", params.buyer); if (params.provider_code) query.append("provider_code", params.provider_code); if (params.org_code) query.append("org_code", params.org_code); if (params.status) query.append("status", params.status); if (params.code) query.append("code", params.code); if (params.date) query.append("date", params.date); if (params.type_code) query.append("type_code", params.type_code); if (params.skip !== undefined) query.append("skip", params.skip.toString()); if (params.limit !== undefined) query.append("limit", params.limit.toString()); const res = await fetch(`${API_BASE}/api/tenders?${query.toString()}`); if (!res.ok) { throw new Error("Error searching tenders"); } return res.json(); } export async function analyzeTender( tender: Tender, companyProfile: CompanyProfile, documentText?: string, models?: Record ): Promise { const res = await fetch(`${API_BASE}/api/analyze`, { method: "POST", headers: jsonHeaders, body: JSON.stringify({ tender, company_profile: companyProfile, document_text: documentText, models: models }), }); if (!res.ok) { throw new Error("Error analyzing tender"); } return res.json(); } export async function uploadDocument(file: File): Promise<{ text: string; filename: string }> { const formData = new FormData(); formData.append("file", file); const res = await fetch(`${API_BASE}/api/upload-document`, { method: "POST", body: formData, }); if (!res.ok) { throw new Error("Error uploading document"); } return res.json(); } export async function saveCompanyProfile(profile: CompanyProfile): Promise { const res = await fetch(`${API_BASE}/api/company-profile`, { method: "POST", headers: jsonHeaders, body: JSON.stringify(profile), }); if (!res.ok) { throw new Error("Error saving company profile"); } return res.json(); } export async function fetchCompanyProfile(): Promise { const res = await fetch(`${API_BASE}/api/company-profile`); if (!res.ok) { throw new Error("No company profile available"); } return res.json(); } export async function fetchAnalysisHistory(): Promise { const res = await fetch(`${API_BASE}/api/analysis-history`); if (!res.ok) { throw new Error("Error fetching analysis history"); } return res.json(); } export async function syncDatabase() { const res = await fetch(`${API_BASE}/api/tenders/sync`, { method: "POST" }); if (!res.ok) { throw new Error("Error syncing database"); } return res.json(); } export async function scrapeTenders(keyword: string): Promise { const res = await fetch(`${API_BASE}/api/tenders/scrape?keyword=${encodeURIComponent(keyword)}`); if (!res.ok) { const errorText = await res.text(); throw new Error(`Scraper error (${res.status}): ${errorText || "Failed to scrape tenders"}`); } return res.json(); } export async function fetchPurchaseOrders(date?: string, status: string = "todos"): Promise { const query = new URLSearchParams(); if (date) query.append("date", date); query.append("status", status); const url = `${API_BASE}/api/purchase-orders?${query.toString()}`; console.log("[API] Fetching purchase orders from:", url); const res = await fetch(url); if (!res.ok) { const errorText = await res.text(); console.error("[API] Purchase orders error:", res.status, errorText); throw new Error(`Failed to fetch purchase orders (${res.status}): Check if backend is running at ${API_BASE}`); } return res.json(); }