const mongoose = require('mongoose');
const fs = require('fs');
const path = require('path');
const connectDB = require('../config/db');
const User = require('../models/User');
const Scene = require('../models/Scene');
const Asset = require('../models/Asset');
const Hotspot = require('../models/Hotspot');

/**
 * Script dọn dẹp dữ liệu rác (orphaned data)
 * Xóa các Scene, Asset và File vật lý của những người dùng đã bị xóa khỏi hệ thống.
 * Đồng thời dọn dẹp các Asset "mồ côi" không còn được gắn vào bất kỳ Scene nào.
 */
const cleanup = async () => {
    try {
        console.log('--- Bắt đầu quy trình dọn dẹp dữ liệu rác ---');
        await connectDB();

        // 1. Lấy danh sách tất cả ID người dùng hiện đang tồn tại
        const validUserIds = await User.distinct('_id');
        console.log(`- Tìm thấy ${validUserIds.length} người dùng hợp lệ.`);

        // 2. Tìm các Scene mồ côi (Người tạo không còn tồn tại)
        const orphanedScenes = await Scene.find({ createdBy: { $nin: validUserIds } });
        const orphanedSceneIds = orphanedScenes.map(s => s._id);
        console.log(`- Tìm thấy ${orphanedSceneIds.length} cảnh (Scene) mồ côi.`);

        // 3. Xóa các Hotspot liên quan đến các Scene mồ côi
        // Xóa cả hotspot xuất phát từ và trỏ đến các scene bị xóa
        const hotspotResult = await Hotspot.deleteMany({
            $or: [
                { parent_scene_id: { $in: orphanedSceneIds } },
                { target_scene_id: { $in: orphanedSceneIds } }
            ]
        });
        console.log(`- Đã xóa ${hotspotResult.deletedCount} liên kết Hotspot liên quan.`);

        // 4. Xóa các Scene mồ côi trong DB
        const sceneResult = await Scene.deleteMany({ _id: { $in: orphanedSceneIds } });
        console.log(`- Đã xóa ${sceneResult.deletedCount} bản ghi Scene trong Database.`);

        // 5. Tìm các Asset mồ côi (Người upload không tồn tại HOẶC không có Scene nào liên kết)
        // Chúng ta lấy danh sách assetId đang được sử dụng bởi các Scene còn lại
        const usedAssetIds = await Scene.distinct('assetId');
        
        // Để an toàn, chỉ xóa các Asset không liên kết nếu chúng đã tồn tại hơn 2 giờ 
        // (Tránh xóa nhầm ảnh đang trong hàng đợi xử lý của Worker)
        const safeDate = new Date(Date.now() - 2 * 3600 * 1000);

        const orphanedAssets = await Asset.find({
            $or: [
                { uploadedBy: { $nin: validUserIds } }, // User đã bị xóa
                { 
                    $and: [
                        { _id: { $nin: usedAssetIds } }, // Không có scene nào trỏ tới
                        { createdAt: { $lt: safeDate } }  // Đã quá 2 giờ
                    ]
                }
            ]
        });
        console.log(`- Tìm thấy ${orphanedAssets.length} ảnh (Asset) mồ côi hoặc không liên kết.`);

        // 6. Xóa tệp tin vật lý và bản ghi Asset
        let filesDeleted = 0;
        for (const asset of orphanedAssets) {
            if (asset.filePath) {
                try {
                    await fs.promises.unlink(asset.filePath);
                    filesDeleted++;
                } catch (e) {
                    if (e.code !== 'ENOENT') console.error(`  [Lỗi] Không thể xóa file: ${asset.filePath}`);
                }
            }
            await Asset.findByIdAndDelete(asset._id);
        }
        console.log(`- Đã dọn dẹp ${filesDeleted} tệp tin vật lý.`);
        console.log(`- Đã xóa ${orphanedAssets.length} bản ghi Asset trong Database.`);

        console.log('--- Hoàn tất dọn dẹp! Hệ thống đã sạch sẽ. ---');
        
        mongoose.connection.close();
        process.exit(0);
    } catch (err) {
        console.error('Lỗi nghiêm trọng khi dọn dẹp:', err.message);
        if (mongoose.connection) mongoose.connection.close();
        process.exit(1);
    }
};

cleanup();