"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AIService = void 0;
const https_1 = __importDefault(require("https"));
const http_1 = __importDefault(require("http"));
const url_1 = require("url");
/**
 * Universal Native HTTP Request Helper (zero extra external dependencies)
 */
function makeHttpRequest(targetUrl, method, headers, body) {
    return new Promise((resolve, reject) => {
        const parsedUrl = new url_1.URL(targetUrl);
        const options = {
            hostname: parsedUrl.hostname,
            port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80),
            path: parsedUrl.pathname + parsedUrl.search,
            method,
            headers: {
                'Content-Type': 'application/json',
                ...headers,
            },
        };
        const client = parsedUrl.protocol === 'https:' ? https_1.default : http_1.default;
        const req = client.request(options, (res) => {
            let data = '';
            res.on('data', (chunk) => (data += chunk));
            res.on('end', () => {
                if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
                    try {
                        resolve(JSON.parse(data));
                    }
                    catch {
                        resolve(data);
                    }
                }
                else {
                    reject(new Error(`HTTP ${res.statusCode}: ${data}`));
                }
            });
        });
        req.on('error', (err) => reject(err));
        if (body) {
            req.write(body);
        }
        req.end();
    });
}
class AIService {
    static getGeminiKey() {
        return process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY;
    }
    static getOpenAIKey() {
        return process.env.OPENAI_API_KEY;
    }
    /**
     * Check if any real AI provider is configured
     */
    static isAIConfigured() {
        return !!(this.getGeminiKey() || this.getOpenAIKey());
    }
    /**
     * Generate raw text using Gemini or OpenAI
     */
    static async generateText(prompt, systemInstruction, temperature = 0.7) {
        const geminiKey = this.getGeminiKey();
        const openaiKey = this.getOpenAIKey();
        // 1. Try Google Gemini API
        if (geminiKey) {
            try {
                const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${geminiKey}`;
                const payload = {
                    contents: [
                        {
                            role: 'user',
                            parts: [{ text: `${systemInstruction ? `[System Instructions: ${systemInstruction}]\n\n` : ''}${prompt}` }],
                        },
                    ],
                    generationConfig: {
                        temperature,
                        maxOutputTokens: 2048,
                    },
                };
                const response = await makeHttpRequest(url, 'POST', {}, JSON.stringify(payload));
                const text = response?.candidates?.[0]?.content?.parts?.[0]?.text;
                if (text)
                    return text.trim();
            }
            catch (err) {
                console.warn('Gemini API request failed, trying next provider:', err.message);
            }
        }
        // 2. Try OpenAI API
        if (openaiKey) {
            try {
                const url = 'https://api.openai.com/v1/chat/completions';
                const payload = {
                    model: 'gpt-4o-mini',
                    messages: [
                        ...(systemInstruction ? [{ role: 'system', content: systemInstruction }] : []),
                        { role: 'user', content: prompt },
                    ],
                    temperature,
                    max_tokens: 2048,
                };
                const response = await makeHttpRequest(url, 'POST', { Authorization: `Bearer ${openaiKey}` }, JSON.stringify(payload));
                const text = response?.choices?.[0]?.message?.content;
                if (text)
                    return text.trim();
            }
            catch (err) {
                console.warn('OpenAI API request failed:', err.message);
            }
        }
        // 3. Resilient heuristic fallback
        return this.fallbackTextGenerator(prompt);
    }
    /**
     * Generate structured JSON from Gemini or OpenAI
     */
    static async generateJSON(prompt, systemInstruction, schemaHint) {
        const enrichedSystem = `${systemInstruction || 'You are an expert Indian literature and e-commerce AI.'}\nRespond ONLY in valid RFC-8259 JSON format with no markdown ticks or preamble.${schemaHint ? ` Expected JSON structure:\n${schemaHint}` : ''}`;
        const text = await this.generateText(prompt, enrichedSystem, 0.2);
        try {
            const cleanJson = text.replace(/```json/gi, '').replace(/```/g, '').trim();
            return JSON.parse(cleanJson);
        }
        catch {
            // Find outermost JSON brackets if response contained additional text
            const match = text.match(/\{[\s\S]*\}|\[[\s\S]*\]/);
            if (match) {
                return JSON.parse(match[0]);
            }
            throw new Error(`AI generated non-JSON response: ${text.slice(0, 150)}...`);
        }
    }
    /**
     * Generate Vector Embeddings (Gemini text-embedding-004 or OpenAI text-embedding-3-small)
     */
    static async generateEmbedding(text) {
        const geminiKey = this.getGeminiKey();
        const openaiKey = this.getOpenAIKey();
        if (geminiKey) {
            try {
                const url = `https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004:embedContent?key=${geminiKey}`;
                const payload = {
                    model: 'models/text-embedding-004',
                    content: { parts: [{ text: text.slice(0, 2048) }] },
                };
                const response = await makeHttpRequest(url, 'POST', {}, JSON.stringify(payload));
                const values = response?.embedding?.values;
                if (Array.isArray(values) && values.length > 0)
                    return values;
            }
            catch (err) {
                console.warn('Gemini embedding failed, falling back:', err.message);
            }
        }
        if (openaiKey) {
            try {
                const url = 'https://api.openai.com/v1/embeddings';
                const payload = {
                    model: 'text-embedding-3-small',
                    input: text.slice(0, 2048),
                };
                const response = await makeHttpRequest(url, 'POST', { Authorization: `Bearer ${openaiKey}` }, JSON.stringify(payload));
                const values = response?.data?.[0]?.embedding;
                if (Array.isArray(values) && values.length > 0)
                    return values;
            }
            catch (err) {
                console.warn('OpenAI embedding failed:', err.message);
            }
        }
        // Heuristic 64-dimensional semantic hash vector
        return this.generateDeterministicVector(text, 64);
    }
    /**
     * Calculate Cosine Similarity between two vector embeddings
     */
    static cosineSimilarity(vecA, vecB) {
        if (!vecA.length || !vecB.length || vecA.length !== vecB.length)
            return 0;
        let dotProduct = 0;
        let normA = 0;
        let normB = 0;
        for (let i = 0; i < vecA.length; i++) {
            dotProduct += vecA[i] * vecB[i];
            normA += vecA[i] * vecA[i];
            normB += vecB[i] * vecB[i];
        }
        if (normA === 0 || normB === 0)
            return 0;
        return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
    }
    /**
     * Deterministic Term-Frequency vector generator for offline fallback
     */
    static generateDeterministicVector(text, dimensions = 64) {
        const vector = new Array(dimensions).fill(0);
        const clean = text.toLowerCase().replace(/[^a-z0-9\s]/g, '');
        const tokens = clean.split(/\s+/).filter(Boolean);
        tokens.forEach((token, index) => {
            let hash = 0;
            for (let i = 0; i < token.length; i++) {
                hash = (hash << 5) - hash + token.charCodeAt(i);
                hash |= 0;
            }
            const dim = Math.abs(hash) % dimensions;
            vector[dim] += 1 / (index + 1);
        });
        // Normalize
        const magnitude = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));
        return magnitude > 0 ? vector.map((v) => v / magnitude) : vector;
    }
    /**
     * Heuristic fallback generator when no cloud AI key is configured
     */
    static fallbackTextGenerator(prompt) {
        const p = prompt.toLowerCase();
        if (p.includes('description') || p.includes('synopsis')) {
            return `This distinguished volume presents an authoritative critical edition and commentary on classical Indian literature, philology, and philosophy. Carefully curated for scholars, collectors, and sincere seekers of knowledge, it features meticulous translation, historical contextualization, and exhaustive thematic appendices.`;
        }
        if (p.includes('seo') || p.includes('keywords')) {
            return `Indian books, classical Sanskrit literature, Vedic philosophy, Indology, sacred scriptures, English translations, rare Indian manuscripts.`;
        }
        return `Indian Books Worldwide provides authentic Indian literature, Sanskrit scriptures, indology commentaries, and academic publications with worldwide insured delivery.`;
    }
}
exports.AIService = AIService;
//# sourceMappingURL=ai.service.js.map