let db;
const path = require('path');
const fs = require('fs');

function init(database) {
    db = database;
}

function parseRoomFields(row) {
    if (!row) return null;
    try { row.furniture = JSON.parse(row.furniture || '[]'); } catch { row.furniture = []; }
    try { row.amenities = JSON.parse(row.amenities || '[]'); } catch { row.amenities = []; }
    try { row.floors = JSON.parse(row.floors || '[]'); } catch { row.floors = []; }
    return row;
}

function getAll(req, res) {
    db.all(`SELECT * FROM rooms WHERE is_active = 1 ORDER BY price_per_night ASC`, [], (err, rows) => {
        if (err) { console.error('Rooms API error:', err); return res.status(500).json({ error: 'Database error' }); }
        rows = rows.map(parseRoomFields);
        loadImages(rows, () => res.json(rows));
    });
}

function loadImages(rows, callback) {
    if (rows.length === 0) return callback();
    let loaded = 0;
    rows.forEach(row => {
        db.all(`SELECT * FROM room_images WHERE room_id = ? ORDER BY sort_order ASC`, [row.id], (err, images) => {
            row.images = images || [];
            if (row.image_path && !images.some(i => i.image_path === row.image_path)) {
                row.images.unshift({ id: null, room_id: row.id, image_path: row.image_path, sort_order: -1, is_primary: 1 });
            }
            loaded++;
            if (loaded === rows.length) callback();
        });
    });
}

function getAllForAdmin(req, res) {
    db.all(`SELECT * FROM rooms ORDER BY price_per_night ASC`, [], (err, rows) => {
        if (err) { console.error('Admin rooms API error:', err); return res.status(500).json({ error: 'Database error' }); }
        rows = rows.map(parseRoomFields);
        loadImages(rows, () => res.json(rows));
    });
}

function createRoom(req, res) {
    const { type, name, description, rooms_count, area_sqm, max_guests, furniture, amenities, floors, price_per_night, extra_beds, extra_bed_price, is_active } = req.body;
    
    if (!type || !name || !price_per_night) {
        return res.status(400).json({ error: 'type, name и price_per_night обязательны' });
    }
    
    db.run(`INSERT INTO rooms (type, name, description, rooms_count, area_sqm, max_guests, furniture, amenities, floors, price_per_night, extra_beds, extra_bed_price, is_active) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
        [type, name, description || '', rooms_count || 1, area_sqm || 20, max_guests || 2, JSON.stringify(furniture || []), JSON.stringify(amenities || []), JSON.stringify(floors || []), price_per_night, extra_beds || 0, extra_bed_price || 0, is_active !== undefined ? (is_active ? 1 : 0) : 1],
        function(err) {
            if (err) { console.error('Create room error:', err); return res.status(500).json({ error: 'Database error' }); }
            db.get(`SELECT * FROM rooms WHERE id = ?`, [this.lastID], (err, row) => {
                if (err) return res.status(500).json({ error: 'Database error' });
                res.status(201).json(parseRoomFields(row));
            });
        }
    );
}

function updateRoom(req, res) {
    const { id } = req.params;
    const { type, name, description, rooms_count, area_sqm, max_guests, furniture, amenities, floors, price_per_night, image_path, extra_beds, extra_bed_price, is_active } = req.body;
    
    db.get(`SELECT * FROM rooms WHERE id = ?`, [id], (err, row) => {
        if (err) return res.status(500).json({ error: 'Database error' });
        if (!row) return res.status(404).json({ error: 'Номер не найден' });
        
        db.run(`UPDATE rooms SET type = ?, name = ?, description = ?, rooms_count = ?, area_sqm = ?, max_guests = ?, furniture = ?, amenities = ?, floors = ?, price_per_night = ?, image_path = ?, extra_beds = ?, extra_bed_price = ?, is_active = ? WHERE id = ?`,
            [
                type ?? row.type,
                name ?? row.name,
                description ?? row.description,
                rooms_count ?? row.rooms_count,
                area_sqm ?? row.area_sqm,
                max_guests ?? row.max_guests,
                furniture ? JSON.stringify(furniture) : row.furniture,
                amenities ? JSON.stringify(amenities) : row.amenities,
                floors ? JSON.stringify(floors) : row.floors,
                price_per_night ?? row.price_per_night,
                image_path !== undefined ? image_path : row.image_path,
                extra_beds ?? row.extra_beds,
                extra_bed_price ?? row.extra_bed_price,
                is_active !== undefined ? (is_active ? 1 : 0) : row.is_active,
                id
            ],
            function(err) {
                if (err) { console.error('Update room error:', err); return res.status(500).json({ error: 'Database error' }); }
                db.get(`SELECT * FROM rooms WHERE id = ?`, [id], (err, row) => {
                    if (err) return res.status(500).json({ error: 'Database error' });
                    loadImages([parseRoomFields(row)], () => res.json(row));
                });
            }
        );
    });
}

function deleteRoom(req, res) {
    const { id } = req.params;
    
    db.get(`SELECT * FROM rooms WHERE id = ?`, [id], (err, row) => {
        if (err) return res.status(500).json({ error: 'Database error' });
        if (!row) return res.status(404).json({ error: 'Номер не найден' });
        
        db.run(`UPDATE rooms SET is_active = 0 WHERE id = ?`, [id], function(err) {
            if (err) { console.error('Delete room error:', err); return res.status(500).json({ error: 'Database error' }); }
            res.json({ message: 'Номер удалён' });
        });
    });
}

function uploadRoomImage(req, res) {
    if (!req.file) {
        return res.status(400).json({ error: 'Файл не загружен' });
    }
    
    let imagePath = 'data/room_images/' + req.file.filename;
    
    if (req.file.mimetype !== 'image/webp') {
        const inputPath = req.file.path;
        const outputPath = path.join(path.dirname(inputPath), req.file.filename.replace(/\.[^.]+$/, '.webp'));
        
        require('sharp')(inputPath)
            .webp({ quality: 85 })
            .toFile(outputPath)
            .then(() => {
                try { fs.unlinkSync(inputPath); } catch {}
                imagePath = 'data/room_images/' + path.basename(outputPath);
                res.json({ path: imagePath });
            })
            .catch(err => {
                console.error('Image conversion error:', err);
                res.json({ path: imagePath });
            });
    } else {
        res.json({ path: imagePath });
    }
}

function uploadRoomImages(req, res) {
    const roomId = parseInt(req.params.id);
    if (!req.files || req.files.length === 0) {
        return res.status(400).json({ error: 'Файлы не загружены' });
    }

    let completed = 0;
    const results = [];

    function processFile(index) {
        if (index >= req.files.length) return;

        const file = req.files[index];
        let imagePath = 'data/room_images/' + file.filename;

        function saveByPath(finalPath) {
            db.get(`SELECT MAX(sort_order) as maxOrder FROM room_images WHERE room_id = ?`, [roomId], (err, row) => {
                const sortOrder = (row?.maxOrder || 0) + 1;
                db.run(`INSERT INTO room_images (room_id, image_path, sort_order) VALUES (?, ?, ?)`,
                    [roomId, finalPath, sortOrder], function(insErr) {
                        if (insErr) { console.error('Room image insert error:', insErr); }
                        else results.push({ id: this.lastID, image_path: finalPath, sort_order: sortOrder });
                        completed++;
                        if (completed === req.files.length) {
                            res.json({ message: 'Изображения загружены', images: results });
                        } else {
                            processFile(index + 1);
                        }
                    });
            });
        }

        if (file.mimetype !== 'image/webp') {
            const inputPath = file.path;
            const outputPath = path.join(path.dirname(inputPath), file.filename.replace(/\.[^.]+$/, '.webp'));
            require('sharp')(inputPath)
                .webp({ quality: 85 })
                .toFile(outputPath)
                .then(() => {
                    try { fs.unlinkSync(inputPath); } catch {}
                    saveByPath('data/room_images/' + path.basename(outputPath));
                })
                .catch(() => {
                    completed++;
                    if (completed === req.files.length) {
                        res.json({ message: 'Изображения загружены', images: results });
                    } else {
                        processFile(index + 1);
                    }
                });
        } else {
            saveByPath(imagePath);
        }
    }

    processFile(0);
}

function deleteRoomImage(req, res) {
    const { imageId } = req.params;
    db.get(`SELECT * FROM room_images WHERE id = ?`, [imageId], (err, row) => {
        if (err) return res.status(500).json({ error: 'Database error' });
        if (!row) return res.status(404).json({ error: 'Изображение не найдено' });
        const filePath = path.join(__dirname, '..', '..', row.image_path);
        try { if (fs.existsSync(filePath)) fs.unlinkSync(filePath); } catch {}
        db.run(`DELETE FROM room_images WHERE id = ?`, [imageId], function(err) {
            if (err) return res.status(500).json({ error: 'Database error' });
            res.json({ message: 'Изображение удалено' });
        });
    });
}

function setPrimaryImage(req, res) {
    const { imageId } = req.params;
    db.get(`SELECT * FROM room_images WHERE id = ?`, [imageId], (err, row) => {
        if (err) return res.status(500).json({ error: 'Database error' });
        if (!row) return res.status(404).json({ error: 'Изображение не найдено' });
        db.run(`UPDATE room_images SET is_primary = 0 WHERE room_id = ?`, [row.room_id], (err) => {
            if (err) return res.status(500).json({ error: 'Database error' });
            db.run(`UPDATE room_images SET is_primary = 1 WHERE id = ?`, [imageId], (err) => {
                if (err) return res.status(500).json({ error: 'Database error' });
                db.run(`UPDATE rooms SET image_path = ? WHERE id = ?`, [row.image_path, row.room_id], (err) => {
                    if (err) return res.status(500).json({ error: 'Database error' });
                    res.json({ message: 'Главное изображение обновлено' });
                });
            });
        });
    });
}

function reorderImages(req, res) {
    const { images } = req.body;
    if (!Array.isArray(images)) return res.status(400).json({ error: 'images must be an array' });
    let done = 0;
    images.forEach((img) => {
        db.run(`UPDATE room_images SET sort_order = ? WHERE id = ?`, [img.sort_order, img.id], (err) => {
            if (err) console.error('Reorder error:', err);
            done++;
            if (done === images.length) res.json({ message: 'Порядок обновлён' });
        });
    });
}

function getAvailability(req, res) {
    const { checkin, checkout } = req.query;
    if (!checkin || !checkout) {
        return res.status(400).json({ error: 'checkin и checkout обязательны' });
    }

    db.all(`SELECT * FROM rooms WHERE is_active = 1 ORDER BY price_per_night ASC`, [], (err, rooms) => {
        if (err) return res.status(500).json({ error: 'Database error' });

        if (rooms.length === 0) return res.json([]);

        let processed = 0;
        const result = [];

        rooms.forEach(room => {
            db.get(
                `SELECT COUNT(b.id) as booked FROM bookings b
                 WHERE b.room_id = ? AND b.status IN ('новая','оплачена','зарезервирована','заселена')
                 AND b.checkin_date < ? AND b.checkout_date > ?`,
                [room.id, checkout, checkin],
                (err, row) => {
                    const booked = err ? 0 : (row?.booked || 0);
                    result.push({
                        type: room.type,
                        name: room.name,
                        id: room.id,
                        total: room.rooms_count,
                        booked: booked,
                        available: Math.max(0, room.rooms_count - booked),
                        price_per_night: room.price_per_night,
                        max_guests: room.max_guests
                    });
                    processed++;
                    if (processed === rooms.length) {
                        result.sort((a, b) => a.price_per_night - b.price_per_night);
                        res.json(result);
                    }
                }
            );
        });
    });
}

function clearLegacyImage(req, res) {
    const { id } = req.params;
    db.get(`SELECT image_path FROM rooms WHERE id = ?`, [id], (err, row) => {
        if (err) return res.status(500).json({ error: 'Database error' });
        if (!row) return res.status(404).json({ error: 'Номер не найден' });
        if (!row.image_path) return res.json({ message: 'Изображение уже отсутствует' });
        const filePath = path.join(__dirname, '..', '..', row.image_path);
        try { if (fs.existsSync(filePath)) fs.unlinkSync(filePath); } catch {}
        db.run(`UPDATE rooms SET image_path = NULL WHERE id = ?`, [id], (err) => {
            if (err) return res.status(500).json({ error: 'Database error' });
            res.json({ message: 'Изображение удалено' });
        });
    });
}

function setupRoutes(app, authenticateToken, requireAdmin, upload) {
    app.get('/api/rooms', getAll);
    app.get('/api/rooms/availability', getAvailability);
    app.get('/api/admin/rooms', authenticateToken, requireAdmin, getAllForAdmin);
    app.post('/api/admin/rooms', authenticateToken, requireAdmin, createRoom);
    app.put('/api/admin/rooms/:id', authenticateToken, requireAdmin, updateRoom);
    app.delete('/api/admin/rooms/:id', authenticateToken, requireAdmin, deleteRoom);
    app.post('/api/admin/rooms/upload', authenticateToken, requireAdmin, upload.single('image'), uploadRoomImage);
    app.post('/api/admin/rooms/:id/images', authenticateToken, requireAdmin, upload.array('images', 5), uploadRoomImages);
    app.delete('/api/admin/rooms/images/:imageId', authenticateToken, requireAdmin, deleteRoomImage);
    app.put('/api/admin/rooms/images/:imageId/primary', authenticateToken, requireAdmin, setPrimaryImage);
    app.put('/api/admin/rooms/images/reorder', authenticateToken, requireAdmin, reorderImages);
    app.delete('/api/admin/rooms/:id/image', authenticateToken, requireAdmin, clearLegacyImage);
}

module.exports = { init, setupRoutes };
