/**
 * ============================================================================
 * WSC2026 Web Technologies - Test Project: AI Middleware Server
 * ============================================================================
 * 🚨 [Competitor Notice] 
 * You do NOT need to modify this file. This is a black-box AI microservice.
 * Your task is to run this server, test the APIs, and build your own 
 * Front-end and Back-end (Database) application that communicates with it.
 * ============================================================================
 */

const express = require('express');
const cors = require('cors');
const multer = require('multer');

const app = express();
app.use(cors());
app.use(express.json());

// Use memory storage (Converts image buffer directly to Base64)
const upload = multer({ storage: multer.memoryStorage() });
const OLLAMA_API = 'http://localhost:11434/api/generate';

// ----------------------------------------------------------------------------
// API 1: Text AI (Generate City Description and Country Info)
// ----------------------------------------------------------------------------
app.post('/api/generate-text', async (req, res) => {
    const { city_name, country } = req.body;
    if (!city_name || !country) {
        return res.status(400).json({ error: 'city_name and country are required.' });
    }

    try {
        const response = await fetch(OLLAMA_API, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                model: 'phi3',
                // 🚀 Advanced Prompt: Request city description and country info in JSON format
                prompt: `Provide information about ${city_name} in ${country}.
                         Return a JSON object with exactly two keys:
                         1. "city_description": A 2-sentence tourist introduction for the city.
                         2. "country_info": One interesting or essential fact about the country ${country}.
                         DO NOT output any explanations. JUST the JSON object.`,
                format: 'json',
                stream: false
            })
        });
        const data = await response.json();
        const rawText = data.response;

        console.log(`[Text API] AI Original Response for ${city_name}, ${country}:`, rawText);

        // --- 🛡️ Text Hallucination Defense Logic ---
        let cityDescription = "Failed to generate city description. Please enter manually.";
        let countryInfo = "Failed to generate country information. Please enter manually.";

        try {
            const parsed = JSON.parse(rawText);
            cityDescription = parsed.city_description || cityDescription;
            countryInfo = parsed.country_info || countryInfo;
        } catch (e) {
            // Fallback: Use regular expressions if JSON parsing fails
            console.warn("[Text API] JSON parsing failed. Attempting regex extraction.");
            const descMatch = rawText.match(/"city_description"\s*:\s*"([^"]+)"/i);
            if (descMatch) cityDescription = descMatch[1];
            const infoMatch = rawText.match(/"country_info"\s*:\s*"([^"]+)"/i);
            if (infoMatch) countryInfo = infoMatch[1];
        }

        res.json({ 
            city_description: cityDescription, 
            country_info: countryInfo 
        });
    } catch (error) {
        console.error("[Text API] Error:", error);
        res.status(500).json({ error: 'Text AI processing failed. Ensure Ollama is running.' });
    }
});

// ----------------------------------------------------------------------------
// API 2: Vision AI (Integrated Image Analysis - Description and Keywords)
// ----------------------------------------------------------------------------
app.post('/api/analyze-image', upload.single('image'), async (req, res) => {
    const file = req.file;
    const { city_name, country } = req.body;
    
    if (!file || !city_name || !country) {
        return res.status(400).json({ error: 'image, city_name, and country are required.' });
    }

    try {
        const base64Image = file.buffer.toString('base64');
        const response = await fetch(OLLAMA_API, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                model: 'llava',
                prompt: `Analyze this image of ${city_name}, ${country}. 
                         Return a JSON object with:
                         1. "description": A short 1-2 sentence description of the image.
                         2. "keywords": An array of exactly 3 descriptive words.
                         JUST the JSON object. DO NOT output any markdown, tags, or extra text.`,
                images: [base64Image],
                format: 'json',
                stream: false
            })
        });
        
        const data = await response.json();
        const rawAiText = data.response; 
        
        console.log(`[Vision API] AI Original Response for ${city_name}, ${country}:`, rawAiText);

        // --- 🛡️ Hallucination Defense & Data Sanitization Logic ---
        let finalDescription = "No description generated. Please enter manually.";
        let finalKeywords = [];

        try {
            // Attempt 1: Force extract inside curly braces {} in case AI adds markdown wrappers
            const jsonMatch = rawAiText.match(/\{[\s\S]*\}/);
            const targetText = jsonMatch ? jsonMatch[0] : rawAiText;
            const parsed = JSON.parse(targetText);
            
            if (parsed.description) finalDescription = parsed.description;
            if (parsed.keywords) {
                if (Array.isArray(parsed.keywords)) {
                    finalKeywords = parsed.keywords;
                } else if (typeof parsed.keywords === 'string') {
                    // Split into an array if keywords arrive as a comma-separated string
                    finalKeywords = parsed.keywords.split(',');
                }
            }
        } catch (e) {
            console.warn("[Vision API] JSON parsing failed. Attempting regex fallback.");
            
            // Attempt fallback extraction for description
            const descMatch = rawAiText.match(/"description"\s*:\s*"([^"]+)"/i);
            if (descMatch) finalDescription = descMatch[1];
            
            // Attempt fallback extraction for keywords array
            const arrMatch = rawAiText.match(/\[(.*?)\]/s);
            if (arrMatch) finalKeywords = arrMatch[1].replace(/["']/g, '').split(',');
        }

        // Sanitize the keywords array (trim, remove brackets/quotes, filter empty, limit to 3)
        finalKeywords = finalKeywords
            .map(w => w.trim().replace(/[{}"\[\]]/g, ''))
            .filter(w => w.length > 0)
            .slice(0, 3);
            
        if (finalKeywords.length === 0) {
            finalKeywords = ["analysis_failed", "manual_input_required", "error"];
        }

        // Finally, return the description (Text) and keywords (Stringified Array)
        res.json({ 
            description: finalDescription,
            keywords: JSON.stringify(finalKeywords) 
        }); 

    } catch (error) {
        console.error("[Vision API] Error:", error);
        res.status(500).json({ error: 'Vision AI processing failed. Ensure Ollama is running.' });
    }
});

const PORT = 3000;
app.listen(PORT, () => {
    console.log(`🚀 AI Middleware Server running on http://localhost:${PORT}`);
    console.log(`- Text API: POST http://localhost:${PORT}/api/generate-text`);
    console.log(`- Vision API: POST http://localhost:${PORT}/api/analyze-image`);
});