// apps/api/src/controllers/search.controller.js

const { DatabaseClient } = require('../../../../packages/db/client');
const Validators = require('../../../../packages/shared/validators');
const Helpers = require('../../../../packages/shared/helpers');
const scrapeService = require('../services/scrape.service');

const db = new DatabaseClient();

exports.search = async (req, res) => {
    try {
        const { query, location, urgency } = req.body;

        const validation = Validators.validateSearchQuery(query);
        if (!validation.valid) {
            return res.status(400).json({ error: validation.error });
        }

        const userPlan = await db.get('SELECT plan FROM users WHERE id = ?', [req.user.id]);

        let dbResults = await searchDatabase(validation.value, location, urgency);

        if (dbResults.length < 10 && userPlan.plan === 'pro') {
            scrapeService.searchAndScrape(validation.value, location).catch(console.error);
        } else if (dbResults.length < 10 && req.availableCredits > 0) {
            scrapeService.searchAndScrape(validation.value, location).catch(console.error);
        }

        await db.run(
            'INSERT INTO search_history (user_id, query, results_count) VALUES (?, ?, ?)',
            [req.user.id, validation.value, dbResults.length]
        );

        await db.run('UPDATE users SET searches_count = searches_count + 1 WHERE id = ?', [req.user.id]);

        if (userPlan.plan !== 'pro' && req.availableCredits > 0) {
            await db.run('UPDATE users SET daily_credits = daily_credits - 1 WHERE id = ?', [req.user.id]);
        }

        res.json({
            query: validation.value,
            results_count: dbResults.length,
            remaining_credits: userPlan.plan === 'pro' ? -1 : req.availableCredits - 1,
            plan: userPlan.plan,
            leads: dbResults.map(lead => ({
                ...lead,
                time_ago: Helpers.timeAgo(lead.discovered_at)
            }))
        });
    } catch (error) {
        console.error('Search error:', error);
        res.status(500).json({ error: 'Search failed' });
    }
};

async function searchDatabase(query, location, urgency) {
    let sql = `
        SELECT id, title, description, service_needed, location, contact_phone, contact_email,
               source_url, source_type, urgency_level, confidence_score, score, score_category,
               posted_date, discovered_at
        FROM leads
        WHERE is_active = true
        AND (title ILIKE ? OR description ILIKE ? OR service_needed ILIKE ?)
    `;

    const params = [`%${query}%`, `%${query}%`, `%${query}%`];

    if (location) {
        sql += ' AND location ILIKE ?';
        params.push(`%${location}%`);
    }

    if (urgency && urgency !== 'all') {
        sql += ' AND urgency_level = ?';
        params.push(urgency);
    }

    sql += ' ORDER BY score DESC, discovered_at DESC LIMIT 100';

    return await db.query(sql, params);
}

exports.getSearchHistory = async (req, res) => {
    try {
        const history = await db.query(
            'SELECT id, query, results_count, created_at FROM search_history WHERE user_id = ? ORDER BY created_at DESC LIMIT 50',
            [req.user.id]
        );
        res.json(history);
    } catch (error) {
        console.error('Get search history error:', error);
        res.status(500).json({ error: 'Failed to get search history' });
    }
};

exports.deleteSearchHistory = async (req, res) => {
    try {
        await db.run('DELETE FROM search_history WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
        res.json({ message: 'Search history deleted' });
    } catch (error) {
        console.error('Delete search history error:', error);
        res.status(500).json({ error: 'Failed to delete search history' });
    }
};

exports.getTodaySearchCount = async (req, res) => {
    try {
        const result = await db.get(
            `SELECT COUNT(*) as count FROM search_history
             WHERE user_id = ? AND created_at::date = CURRENT_DATE`,
            [req.user.id]
        );

        res.json({ count: Number(result.count) || 0 });
    } catch (error) {
        console.error('Get today search count error:', error);
        res.status(500).json({ error: 'Failed to get today\'s search count' });
    }
};

exports.getRemainingCredits = async (req, res) => {
    try {
        const user = await db.get('SELECT plan, daily_credits FROM users WHERE id = ?', [req.user.id]);

        if (user.plan === 'pro') {
            res.json({ plan: 'pro', remaining: -1, limit: -1 });
        } else {
            const freeLimit = await db.get(
                'SELECT setting_value FROM system_settings WHERE setting_key = ?',
                ['free_daily_limit']
            );

            const limit = freeLimit ? parseInt(freeLimit.setting_value, 10) : 5;
            res.json({ plan: 'free', remaining: user.daily_credits, limit: limit });
        }
    } catch (error) {
        console.error('Get remaining credits error:', error);
        res.status(500).json({ error: 'Failed to get credits' });
    }
};