const express = require('express');
const router = express.Router();
const path = require('path');
const fs = require('fs');
const AdmZip = require('adm-zip');
const multer = require('multer');

const User = require('../models/User');
const Asset = require('../models/Asset');
const Scene = require('../models/Scene');
const Hotspot = require('../models/Hotspot');
const Setting = require('../models/Setting');
const { protect } = require('../middlewares/authMiddleware');
const { logActivity } = require('../utils/logger');

const uploadDir = process.env.UPLOAD_DIR ? path.resolve(process.env.UPLOAD_DIR) : path.join(__dirname, '../uploads');
const tempDir = path.join(uploadDir, 'temp');
const upload = multer({ dest: tempDir });

// Helper: Dọn dẹp dữ liệu mồ côi
const runOrphanedCleanup = async (performer = 'System') => {
    const validUserIds = await User.distinct('_id');
    const orphanedScenes = await Scene.find({ createdBy: { $nin: validUserIds } });
    const orphanedSceneIds = orphanedScenes.map(s => s._id);

    if (orphanedSceneIds.length > 0) {
        await Hotspot.deleteMany({ $or: [{ parent_scene_id: { $in: orphanedSceneIds } }, { target_scene_id: { $in: orphanedSceneIds } }] });
        await Scene.deleteMany({ _id: { $in: orphanedSceneIds } });
    }

    const usedAssetIds = await Scene.distinct('assetId');
    const safeDate = new Date(Date.now() - 2 * 3600 * 1000);
    const orphanedAssets = await Asset.find({ $or: [{ uploadedBy: { $nin: validUserIds } }, { $and: [{ _id: { $nin: usedAssetIds } }, { createdAt: { $lt: safeDate } }] }] });

    for (const asset of orphanedAssets) {
        if (asset.filePath) await fs.promises.unlink(asset.filePath).catch(() => {});
        await Asset.findByIdAndDelete(asset._id);
    }
    await logActivity('SYSTEM_ORPHAN_CLEANUP', { scenesDeleted: orphanedSceneIds.length, assetsDeleted: orphanedAssets.length }, performer);
    return { scenesDeleted: orphanedSceneIds.length, assetsDeleted: orphanedAssets.length };
};

// @route   POST /api/admin/backup
router.post('/backup', protect, async (req, res) => {
    if (req.user.role !== 'admin' && req.user.role !== 'Chủ sở hữu') return res.status(403).json({ message: 'Forbidden' });
    try {
        const zip = new AdmZip();
        const dbData = {
            users: await User.find().lean(),
            assets: await Asset.find().lean(),
            scenes: await Scene.find().lean(),
            hotspots: await Hotspot.find().lean(),
            settings: await Setting.find().lean()
        };
        zip.addFile("database.json", Buffer.from(JSON.stringify(dbData, null, 2), "utf8"));
        if (fs.existsSync(uploadDir)) zip.addLocalFolder(uploadDir, "uploads");
        res.set({ 'Content-Type': 'application/zip', 'Content-Disposition': 'attachment; filename="backup.zip"' });
        res.send(zip.toBuffer());
    } catch (error) { res.status(500).json({ message: error.message }); }
});

// @route   GET /api/admin/maintenance/stray-files
router.get('/maintenance/stray-files', protect, async (req, res) => {
    if (req.user.role !== 'admin' && req.user.role !== 'Chủ sở hữu') return res.status(403).json({ message: 'Forbidden' });
    try {
        const entries = await fs.promises.readdir(uploadDir, { withFileTypes: true });
        const assets = await Asset.find().select('filePath').lean();
        const dbFileNames = new Set(assets.map(a => path.basename(a.filePath)));
        const strayFiles = entries.filter(e => e.isFile() && !e.name.startsWith('.') && !dbFileNames.has(e.name)).map(e => e.name);
        res.json({ count: strayFiles.length, files: strayFiles });
    } catch (error) { res.status(500).json({ message: error.message }); }
});

// @route   POST /api/admin/maintenance/cleanup
router.post('/maintenance/cleanup', protect, async (req, res) => {
    if (req.user.role !== 'admin' && req.user.role !== 'Chủ sở hữu') return res.status(403).json({ message: 'Forbidden' });
    try {
        const report = await runOrphanedCleanup(req.user.username);
        res.json({ message: 'Cleanup completed', report });
    } catch (error) { res.status(500).json({ message: error.message }); }
});

// @route   GET /api/admin/users
router.get('/users', protect, async (req, res) => {
    if (req.user.role !== 'admin' && req.user.role !== 'Chủ sở hữu') return res.status(403).json({ message: 'Forbidden' });
    try {
        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 10;
        const skip = (page - 1) * limit;
        const users = await User.find().sort({ createdAt: -1 }).skip(skip).limit(limit).select('-password');
        const total = await User.countDocuments();
        res.json({ users, totalPages: Math.ceil(total / limit), currentPage: page });
    } catch (error) { res.status(500).json({ message: error.message }); }
});

// @route   PUT /api/admin/users/:id
router.put('/users/:id', protect, async (req, res) => {
    if (req.user.role !== 'admin' && req.user.role !== 'Chủ sở hữu') return res.status(403).json({ message: 'Forbidden' });
    try {
        const { fullName, email, role, password, quota } = req.body;
        const user = await User.findById(req.params.id);
        if (!user) return res.status(404).json({ message: 'User not found' });
        if (fullName) user.fullName = fullName;
        if (email) user.email = email;
        if (role && user.role !== 'admin') user.role = role;
        if (password) user.password = password;
        if (quota !== undefined) {
            user.storage = { ...user.storage, quota: parseInt(quota) * 1024 * 1024 };
        }
        await user.save();
        res.json({ message: 'User updated' });
    } catch (error) { res.status(500).json({ message: error.message }); }
});

// @route   DELETE /api/admin/users/:id
router.delete('/users/:id', protect, async (req, res) => {
    if (req.user.role !== 'admin' && req.user.role !== 'Chủ sở hữu') return res.status(403).json({ message: 'Forbidden' });
    try {
        const user = await User.findById(req.params.id);
        if (!user || user.role === 'admin') return res.status(400).json({ message: 'Invalid request' });
        await User.findByIdAndDelete(req.params.id);
        await logActivity('USER_PERMANENT_DELETE', { userId: user._id, username: user.username }, req.user.username);
        await runOrphanedCleanup(req.user.username);
        res.json({ message: 'User deleted' });
    } catch (error) { res.status(500).json({ message: error.message }); }
});

module.exports = router;