let db;

function init(database) {
    db = database;
}

function getSummary(req, res) {
    const today = new Date().toISOString().split('T')[0];
    const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
    const monthAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];

    const queries = {
        revenue_today: `SELECT COALESCE(SUM(total_price), 0) as revenue FROM bookings WHERE status NOT IN ('отменена','новая') AND checkin_date = ?`,
        revenue_week: `SELECT COALESCE(SUM(total_price), 0) as revenue FROM bookings WHERE status NOT IN ('отменена','новая') AND checkin_date >= ?`,
        revenue_month: `SELECT COALESCE(SUM(total_price), 0) as revenue FROM bookings WHERE status NOT IN ('отменена','новая') AND checkin_date >= ?`,
        checkin_today: `SELECT COUNT(*) as count FROM bookings WHERE status IN ('заселена') AND checkin_date = ?`,
        checkout_today: `SELECT COUNT(*) as count FROM bookings WHERE status IN ('выехала') AND checkout_date = ?`,
        new_bookings: `SELECT COUNT(*) as count FROM bookings WHERE status = 'новая'`,
        active_bookings: `SELECT COUNT(*) as count FROM bookings WHERE status IN ('оплачена','зарезервирована','заселена')`,
        avg_review: `SELECT COALESCE(AVG(stars), 0) as avg FROM reviews WHERE is_approved = 1`,
        total_bookings: `SELECT COUNT(*) as total, AVG(julianday(checkout_date) - julianday(checkin_date)) as avg_stay FROM bookings WHERE status NOT IN ('отменена')`
    };

    const results = {};
    let completed = 0;
    const total = Object.keys(queries).length;

    function finish() {
        completed++;
        if (completed < total) return;

        const now = new Date().toISOString();
        const stayingSql = `SELECT COUNT(DISTINCT b.id) as count FROM bookings b WHERE b.status IN ('оплачена','зарезервирована','заселена') AND b.checkin_date <= ? AND b.checkout_date > ?`;
        db.get(stayingSql, [now, now], (err, staying) => {
            const stayingCount = (err ? 0 : staying?.count) || 0;
            db.all(`SELECT r.type, r.rooms_count, COUNT(b.id) as booked FROM rooms r LEFT JOIN bookings b ON b.room_id = r.id AND b.status IN ('новая','оплачена','зарезервирована','заселена') AND b.checkin_date <= ? AND b.checkout_date > ? WHERE r.is_active = 1 GROUP BY r.type, r.rooms_count`, [now, now], (err, occRows) => {
                const occupancy = { current: 0, by_type: {} };
                let totalRooms = 0;
                let totalBooked = 0;
                if (occRows) {
                    occRows.forEach(r => {
                        const booked = r.booked || 0;
                        const total = r.rooms_count || 0;
                        occupancy.by_type[r.type] = total > 0 ? Math.round((booked / total) * 100) : 0;
                        totalRooms += total;
                        totalBooked += booked;
                    });
                    occupancy.current = totalRooms > 0 ? Math.round((totalBooked / totalRooms) * 100) : 0;
                }

                res.json({
                    revenue: {
                        today: results.revenue_today,
                        week: results.revenue_week,
                        month: results.revenue_month
                    },
                    occupancy: occupancy,
                    bookings: {
                        new: results.new_bookings,
                        active: results.active_bookings,
                        checkin_today: results.checkin_today,
                        checkout_today: results.checkout_today,
                        staying_now: stayingCount,
                        total: results.total_bookings?.total || 0
                    },
                    avg_stay_days: Math.round((results.total_bookings?.avg_stay || 0) * 10) / 10,
                    avg_review_stars: Math.round((results.avg_review || 0) * 10) / 10
                });
            });
        });
    }

    Object.entries(queries).forEach(([key, sql]) => {
        const params = [];
        if (key === 'revenue_today' || key === 'checkin_today' || key === 'checkout_today') params.push(today);
        else if (key === 'revenue_week') params.push(weekAgo);
        else if (key === 'revenue_month') params.push(monthAgo);

        db.get(sql, params, (err, row) => {
            if (err) { results[key] = 0; }
            else if (key.includes('revenue')) results[key] = row.revenue || 0;
            else if (key === 'total_bookings') results[key] = { total: row.total || 0, avg_stay: row.avg_stay || 0 };
            else results[key] = row?.count || row?.avg || 0;
            finish();
        });
    });
}

function getRevenue(req, res) {
    const period = req.query.period || 'monthly';
    const months = parseInt(req.query.months) || 6;

    let groupBy;
    let dateFormat;

    if (period === 'daily') {
        groupBy = "date(b.checkin_date)";
        dateFormat = 'daily';
    } else if (period === 'weekly') {
        groupBy = "strftime('%Y-W%W', b.checkin_date)";
        dateFormat = 'weekly';
    } else {
        groupBy = "strftime('%Y-%m', b.checkin_date)";
        dateFormat = 'monthly';
    }

    const sinceDate = new Date();
    sinceDate.setMonth(sinceDate.getMonth() - months);
    const since = sinceDate.toISOString().split('T')[0];

    db.all(
        `SELECT ${groupBy} as label, COALESCE(SUM(total_price), 0) as revenue, COUNT(*) as bookings
         FROM bookings b
         WHERE b.status NOT IN ('отменена','новая') AND b.checkin_date >= ?
         GROUP BY label ORDER BY label ASC`,
        [since],
        (err, rows) => {
            if (err) return res.status(500).json({ error: 'Database error' });
            res.json({ period: dateFormat, data: rows });
        }
    );
}

function setupRoutes(app, authenticateToken, requireAdmin) {
    app.get('/api/admin/reports/summary', authenticateToken, getSummary);
    app.get('/api/admin/reports/revenue', authenticateToken, getRevenue);
}

module.exports = { init, setupRoutes };
