let db;
let settingsModule;

function init(database, settings) {
    db = database;
    settingsModule = settings;
}

function getApprovedReviews(req, res) {
    const lang = req.query.lang || 'ru';

    db.all(
        `SELECT id, author_name, country, city, stars, text, created_at
         FROM reviews
         WHERE is_approved = 1`,
        [],
        (err, rows) => {
            if (err) {
                console.error('Get reviews error:', err);
                return res.status(500).json({ error: 'Database error' });
            }

            rows.forEach(row => {
                row.created_at = row.created_at ? new Date(row.created_at).toISOString() : null;
            });

            const maxReviews = 8;
            let reviews = rows;
            
            if (rows.length > maxReviews) {
                for (let i = reviews.length - 1; i > 0; i--) {
                    const j = Math.floor(Math.random() * (i + 1));
                    [reviews[i], reviews[j]] = [reviews[j], reviews[i]];
                }
                reviews = reviews.slice(0, maxReviews);
            }

            const stats = rows.length > 0 ? {
                count: rows.length,
                avgStars: rows.reduce((sum, r) => sum + r.stars, 0) / rows.length
            } : { count: 0, avgStars: 0 };

            res.json({ reviews: reviews, stats: stats });
        }
    );
}

function createReview(req, res) {
    const { author_name, country_code, country_name, city, stars, text, review_code } = req.body;
    const ip = req.ip || req.connection.remoteAddress || 'unknown';

    if (!author_name || !country_code || stars === undefined || !text || !review_code) {
        return res.status(400).json({ error: 'Missing required fields' });
    }

    const country = country_name || country_code;

    if (author_name.length < 2) {
        return res.status(400).json({ error: 'Name must be at least 2 characters' });
    }

    if (text.length < 20) {
        return res.status(400).json({ error: 'Review text must be at least 20 characters' });
    }

    if (stars < 0 || stars > 5) {
        return res.status(400).json({ error: 'Stars must be between 0 and 5' });
    }

    settingsModule.getReviewCode((err, correctCode) => {
        if (err) return res.status(500).json({ error: 'Server error' });

        if (review_code !== correctCode) {
            return res.status(400).json({ error: 'Invalid review code' });
        }

        settingsModule.checkIpCooldown(ip, (err, isCooldown) => {
            if (err) return res.status(500).json({ error: 'Server error' });

            if (isCooldown) {
                return res.status(429).json({ error: 'You have recently submitted a review. Please try again later.' });
            }

const stmt = db.prepare(
                `INSERT INTO reviews (author_name, country, country_code, city, stars, text, review_code, ip_address, is_approved)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)`
            );

            stmt.run(author_name, country, country_code, city, parseFloat(stars).toFixed(1), text, review_code, ip, function(err) {
                if (err) {
                    console.error('Create review error:', err);
                    return res.status(500).json({ error: 'Database error' });
                }

                res.status(201).json({
                    message: 'Review submitted for moderation',
                    id: this.lastID
                });
            });

            stmt.finalize();
        });
    });
}

function getAllReviews(req, res) {
    const filter = req.query.filter || 'all';
    let whereClause = '1=1';

    if (filter === 'pending') {
        whereClause = 'is_approved = 0';
    } else if (filter === 'approved') {
        whereClause = 'is_approved = 1';
    } else if (filter === 'rejected') {
        whereClause = 'is_approved = -1';
    }

    db.all(
        `SELECT * FROM reviews WHERE ${whereClause} ORDER BY created_at DESC`,
        [],
        (err, rows) => {
            if (err) {
                console.error('Get all reviews error:', err);
                return res.status(500).json({ error: 'Database error' });
            }

            const stats = {
                total: rows.length,
                pending: rows.filter(r => r.is_approved === 0).length,
                approved: rows.filter(r => r.is_approved === 1).length,
                rejected: rows.filter(r => r.is_approved === -1).length
            };

            db.get(`SELECT COUNT(*) as cnt, SUM(CASE WHEN is_approved = 0 THEN 1 ELSE 0 END) as pending,
                           SUM(CASE WHEN is_approved = 1 THEN 1 ELSE 0 END) as approved,
                           SUM(CASE WHEN is_approved = -1 THEN 1 ELSE 0 END) as rejected
                    FROM reviews`, [], (err, globalStats) => {
                if (!err && globalStats) {
                    stats.total = globalStats.cnt || 0;
                    stats.pending = globalStats.pending || 0;
                    stats.approved = globalStats.approved || 0;
                    stats.rejected = globalStats.rejected || 0;
                }

                rows.forEach(row => {
                    row.created_at = row.created_at ? new Date(row.created_at).toISOString() : null;
                });

                res.json({ reviews: rows, stats: stats });
            });
        }
    );
}

function approveReview(req, res) {
    const reviewId = parseInt(req.params.id);
    const { approved } = req.body;

    const newStatus = approved ? 1 : -1;

    db.run(
        `UPDATE reviews SET is_approved = ? WHERE id = ?`,
        [newStatus, reviewId],
        function(err) {
            if (err) {
                console.error('Approve review error:', err);
                return res.status(500).json({ error: 'Database error' });
            }

            if (this.changes === 0) {
                return res.status(404).json({ error: 'Review not found' });
            }

            res.json({ message: 'Review status updated', id: reviewId, is_approved: newStatus });
        }
    );
}

function deleteReview(req, res) {
    const reviewId = parseInt(req.params.id);

    db.run(`DELETE FROM reviews WHERE id = ?`, [reviewId], function(err) {
        if (err) {
            console.error('Delete review error:', err);
            return res.status(500).json({ error: 'Database error' });
        }

        if (this.changes === 0) {
            return res.status(404).json({ error: 'Review not found' });
        }

        res.json({ message: 'Review deleted', id: reviewId });
    });
}

function getPopularCountries(req, res) {
    if (!db) {
        return res.status(500).json({ error: 'Database not initialized' });
    }
    
    db.all(`
        SELECT country_code, COUNT(*) as count 
        FROM reviews 
        WHERE is_approved = 1 AND country_code IS NOT NULL AND country_code != ''
        GROUP BY country_code 
        ORDER BY count DESC 
        LIMIT 20
    `, (err, countries) => {
        if (err) {
            console.error('Get popular countries error:', err);
            return res.status(500).json({ error: err.message });
        }
        
        if (!countries || countries.length === 0) {
            return res.json({ countries: [], cities: {} });
        }
        
        const placeholders = countries.map(() => '?').join(',');
        
        db.all(`
            SELECT country_code, city, COUNT(*) as count 
            FROM reviews 
            WHERE is_approved = 1 AND country_code IN (${placeholders})
            GROUP BY country_code, city 
            ORDER BY count DESC
        `, countries.map(c => c.country_code), (err, cities) => {
            if (err) {
                console.error('Get popular cities error:', err);
                return res.status(500).json({ error: err.message });
            }
            
            const citiesByCountry = {};
            if (cities) {
                cities.forEach(c => {
                    if (!citiesByCountry[c.country_code]) {
                        citiesByCountry[c.country_code] = [];
                    }
                    citiesByCountry[c.country_code].push(c.city);
                });
            }
            
            res.json({ countries, cities: citiesByCountry });
        });
    });
}

function getPopularCitiesByCountry(req, res) {
    const countryCode = req.params.countryCode;
    
    if (!db) {
        return res.status(500).json({ error: 'Database not initialized' });
    }
    
    if (!countryCode) {
        return res.json({ popular: [], countryCode: null });
    }
    
    db.all(`
        SELECT city, COUNT(*) as count 
        FROM reviews 
        WHERE is_approved = 1 AND country_code = ?
        GROUP BY city 
        ORDER BY count DESC
    `, [countryCode], (err, popularCities) => {
        if (err) {
            console.error('Get popular cities by country error:', err);
            popularCities = [];
        }
        
        const popularCityNames = popularCities ? popularCities.map(c => c.city) : [];
        res.json({ popular: popularCityNames, countryCode });
    });
}

function setupRoutes(app, authenticateToken, requireAdmin) {
    app.get('/api/reviews', getApprovedReviews);
    app.post('/api/reviews', createReview);
    app.get('/api/reviews/popular', getPopularCountries);
    app.get('/api/reviews/cities/:countryCode', getPopularCitiesByCountry);

    app.get('/api/admin/reviews', authenticateToken, getAllReviews);
    app.patch('/api/admin/reviews/:id/approve', authenticateToken, approveReview);
    app.delete('/api/admin/reviews/:id', authenticateToken, deleteReview);
}

module.exports = { init, setupRoutes };