const express = require('express');
const router = express.Router();
const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
const multer = require('multer');

const Scene = require('../models/Scene');
const Tour = require('../models/Tour');
const Asset = require('../models/Asset');
const Hotspot = require('../models/Hotspot');
const { protect, optionalAuth } = require('../middlewares/authMiddleware');
const { checkQuota } = require('../middlewares/quotaMiddleware');
const { resizeTo8K } = require('../utils/imageHelper');
const { injectGPSCoordinates } = require('../utils/exifHelper');
const { imageQueue } = require('./imageQueue');
const { deleteSceneCascade, propagateScenePrivacy } = require('../utils/sceneHelper');

const uploadDir = process.env.UPLOAD_DIR ? path.resolve(process.env.UPLOAD_DIR) : path.join(__dirname, '../uploads');

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        // req.user đã được populate bởi protect middleware
        const userId = req.user._id.toString();
        const userTempDir = path.join(uploadDir, userId, 'temp');
        if (!fs.existsSync(userTempDir)) {
            fs.mkdirSync(userTempDir, { recursive: true });
        }
        cb(null, userTempDir);
    },
    filename: (req, file, cb) => cb(null, `${Date.now()}_${crypto.randomBytes(4).toString('hex')}${path.extname(file.originalname)}`)
});
const upload = multer({ storage });

const uploadSinglePanorama = (req, res, next) => {
    upload.single('panorama')(req, res, (err) => {
        if (err) return res.status(400).json({ message: err.message });
        next();
    });
};

// @route   POST /api/scenes
router.post('/', protect, uploadSinglePanorama, checkQuota, async (req, res) => {
    try {
        const { title, lat, lng, privacy, sharedWithUsers, sharedEmails, shareExpireDays, tourId } = req.body;
        if (!req.file) return res.status(400).json({ message: 'Please upload a panorama image' });

        // [QUY TRÌNH MỚI] Bắt buộc tourId và kế thừa từ Tour model
        if (!tourId || tourId === 'null' || tourId === 'undefined') {
            return res.status(400).json({ message: 'tourId là bắt buộc khi tạo cảnh mới.' });
        }

        const tour = await Tour.findById(tourId);
        if (!tour) return res.status(404).json({ message: 'Tour không tồn tại hoặc đã bị xóa.' });

        // [SECURITY] Chỉ chủ sở hữu Tour hoặc Admin mới được thêm cảnh
        if (tour.createdBy.toString() !== req.user._id.toString() && req.user.role !== 'admin') {
            return res.status(403).json({ message: 'Bạn không có quyền thêm cảnh vào Tour này.' });
        }

        const latitude = Number(lat) || 0;
        const longitude = Number(lng) || 0;
        const tempFilePath = req.file.path;

        // Tạo thư mục lưu trữ chính cho User nếu chưa có
        const userId = req.user._id.toString();
        const userUploadDir = path.join(uploadDir, userId);
        if (!fs.existsSync(userUploadDir)) {
            fs.mkdirSync(userUploadDir, { recursive: true });
        }

        const processedFileName = `processed_${req.file.filename}.jpg`;
        const processedFilePath = path.join(userUploadDir, processedFileName);

        const asset = new Asset({
            filePath: tempFilePath,
            fileSize: req.file.size,
            uploadedBy: req.user._id,
            coordinates: { lat: latitude, lng: longitude }
        });
        await asset.save();

        const scene = new Scene({
            name: title,
            assetId: asset._id,
            scene_url: tempFilePath,
            gps: { lat: latitude, lng: longitude },
            createdBy: req.user._id,
            privacy: tour.privacy || 'private',
            status: 'processing',
            tourId: tour._id,
            shareToken: tour.shareToken,
            shareTokenExpires: tour.shareTokenExpires,
            sharedWith: tour.sharedWith,
            sharedEmails: tour.sharedEmails
        });

        await scene.save();

        // Cập nhật Tour: Thêm scene vào danh sách và gán rootSceneId nếu là cảnh đầu tiên
        tour.scenes.push(scene._id);
        if (!tour.rootSceneId) {
            tour.rootSceneId = scene._id;
        }
        await tour.save();

        // Tự động tính toán lại vị trí trung tâm của Tour khi thêm cảnh mới
        if (latitude !== 0 || longitude !== 0) {
            const tourController = require('../middlewares/TourController');
            if (tourController.updateTourCenter) await tourController.updateTourCenter(tour._id);
        }

        await imageQueue.add('process-panorama', {
            tempFilePath, processedFilePath, latitude, longitude, assetId: asset._id, sceneId: scene._id
        });

        res.status(201).json({ message: 'Scene đã được tạo! Ảnh đang được xử lý 8K ngầm...', scene });
    } catch (error) {
        if (req.file) await fs.promises.unlink(req.file.path).catch(() => {});
        res.status(500).json({ message: error.message });
    }
});

// @route   GET /api/scenes
router.get('/', optionalAuth, async (req, res) => {
    try {
        const { token } = req.query;
        
        // [FIX] Lấy danh sách ID của các Tour đang ở chế độ công khai
        const publicTours = await Tour.find({ privacy: 'public' }).select('_id');
        const publicTourIds = publicTours.map(t => t._id);
        
        // Quyền cơ bản: Công khai hoặc là chủ sở hữu/thành viên được chia sẻ
        let baseQuery = req.user && req.user.role !== 'guest'
            ? { 
                $or: [
                    { privacy: 'public' }, 
                    { privacy: 'member' },
                    { tourId: { $in: publicTourIds } }, 
                    { createdBy: req.user._id }, 
                    { sharedWith: req.user._id }, 
                    { sharedEmails: req.user.email }
                ] 
              }
            : { $or: [{ privacy: 'public' }, { tourId: { $in: publicTourIds } }] };

        let finalQuery = baseQuery;

        // Nếu có token từ URL (Guest truy cập link shared), cho phép lấy các scene thuộc Tour/Scene mang token đó
        if (token) {
            const tourWithToken = await Tour.findOne({ shareToken: token }).select('_id');
            finalQuery = {
                $or: [
                    baseQuery,
                    { shareToken: token },
                    { tourId: tourWithToken ? tourWithToken._id : null }
                ]
            };
        }

        const scenes = await Scene.find(finalQuery)
            .populate('createdBy', 'username')
            .populate('tourId') // Nạp thông tin Tour để Frontend nhận diện
            .lean();
        res.json(scenes);
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

/**
 * @route   GET /api/share/:id
 * @desc    Trang trung gian hỗ trợ Open Graph (Facebook, Zalo,...)
 */
const shareScene = async (req, res) => {
    try {
        const scene = await Scene.findById(req.params.id).populate('tourId');
        if (!scene) return res.status(404).send('Không tìm thấy cảnh 3D');

        const tour = scene.tourId;
        const title = tour ? tour.name : (scene.name || 'Virtual Tour 3D');
        const description = tour ? tour.description : (scene.description || 'Khám phá không gian 360 độ chân thực');
        
        // Lấy token chia sẻ (nếu có)
        const token = req.query.token || scene.shareToken || (tour && tour.shareToken) || '';
        
        // Xác định host của hệ thống
        const protocol = req.headers['x-forwarded-proto'] || req.protocol;
        const host = process.env.SYSTEM_HOST || `${protocol}://${req.get('host')}`;
        
        // URL ảnh thumbnail gọi sang Asset API với cờ watermark (đã được xử lý trong assetRoutes.js)
        const imageUrl = `${host}/api/assets/view/${scene.assetId}?watermark=true${token ? '&token=' + token : ''}`;
        
        // URL thực tế của ứng dụng để redirect người dùng
        const appUrl = `${host}/?sceneId=${scene._id}${token ? '&token=' + token : ''}`;

        // URL Canonical của chính trang chia sẻ này (Dùng cho og:url)
        const shareUrl = `${host}/api/share/${scene._id}${token ? '?token=' + token : ''}`;

        res.send(`
<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>${title}</title>
    <link rel="canonical" href="${appUrl}" />
    
    <!-- Open Graph / Facebook -->
    <meta property="og:site_name" content="3D Tours - Virtual Tour 360">
    <meta property="og:type" content="website">
    <meta property="og:url" content="${shareUrl}">
    <meta property="og:title" content="${title}">
    <meta property="og:description" content="${description}">
    <meta property="og:image" content="${imageUrl}">
    <meta property="og:image:secure_url" content="${imageUrl}">
    <meta property="og:image:type" content="image/jpeg">
    <meta property="og:image:width" content="1200">
    <meta property="og:image:height" content="630">

    <!-- Twitter -->
    <meta property="twitter:card" content="summary_large_image">
    <meta property="twitter:title" content="${title}">
    <meta property="twitter:description" content="${description}">
    <meta property="twitter:image" content="${imageUrl}">

    <!-- Chuyển hướng người dùng về trang chủ để mở viewer -->
    <script type="text/javascript">
        window.location.href = "${appUrl}";
    </script>
</head>
<body style="font-family: sans-serif; text-align: center; padding-top: 50px; background: #1a1a1a; color: #fff;">
    <h2>${title}</h2>
    <p>Đang tải không gian 3D, vui lòng đợi...</p>
</body>
</html>`);
    } catch (error) {
        console.error("[Share Error]", error);
        res.status(500).send('Lỗi máy chủ');
    }
};

// Đăng ký route phụ trợ trong router này
router.get('/share/:id', shareScene);

// @route   GET /api/scenes/:id
router.get('/:id', optionalAuth, async (req, res) => {
    try {
        console.log(`[Backend-Scene] Yêu cầu chi tiết: ${req.params.id}. User: ${req.user?._id || 'Guest'}, QueryToken: ${req.query.token || 'N/A'}`);

        const scene = await Scene.findById(req.params.id)
            .populate('createdBy', 'username')
            .populate('assetId')
            .populate('tourId');

        if (!scene) return res.status(404).json({ message: 'Scene not found' });

        const tour = scene.tourId; // tourId is populated
        if (!tour) return res.status(404).json({ message: 'Tour liên kết không tồn tại.' });

        const isOwner = req.user && req.user._id && tour.createdBy?.toString() === req.user._id.toString();
        const isAdmin = req.user && req.user.role === 'admin';

        const isSceneTokenValid = scene.shareToken && (!scene.shareTokenExpires || new Date() < scene.shareTokenExpires);
        const isTourTokenValid = tour.shareToken && (!tour.shareTokenExpires || new Date() < tour.shareTokenExpires);
        const userEmail = req.user ? req.user.email : null;

        // [FIX] Cho phép truy cập nếu bản thân Scene CÔNG KHAI hoặc Tour CÔNG KHAI
        let hasAccess = tour.privacy === 'public' || scene.privacy === 'public' || isOwner || isAdmin ||
            (scene.privacy === 'shared' && req.query.token === scene.shareToken && isSceneTokenValid) || // Access via scene's token
            (tour.privacy === 'shared' && req.query.token === tour.shareToken && isTourTokenValid) || // Access via tour's token
            (tour.privacy === 'member' && req.user && req.user._id && req.user.role !== 'guest') || // Access for any logged-in member
            (tour.privacy === 'member' && req.user && req.user._id && ( // Specific shared members (legacy support)
                tour.sharedWith.some(u => u.toString() === req.user._id.toString()) ||
                (userEmail && tour.sharedEmails.includes(userEmail))
            ));

        if (req.query.token) {
            console.log(`[Backend-Auth] Token: ${req.query.token}. Match Scene: ${req.query.token === scene.shareToken}, Match Tour: ${req.query.token === tour.shareToken}, Access: ${hasAccess}`);
        }

        // [BRIDGE ACCESS LOGIC] 
        // Nếu chưa có quyền, kiểm tra xem người dùng có đến từ một cảnh hợp lệ thuộc Tour khác không
        if (!hasAccess && req.query.token) {
            const potentialParents = await Hotspot.find({ target_scene_id: scene._id }).distinct('parent_scene_id');
            if (potentialParents.length > 0) {
                // Kiểm tra xem có cảnh cha nào sở hữu shareToken này và còn hạn không
                const authorizedParentExists = await Scene.exists({
                    _id: { $in: potentialParents },
                    shareToken: req.query.token,
                    $or: [{ shareTokenExpires: null }, { shareTokenExpires: { $gt: new Date() } }]
                });
                if (authorizedParentExists) {
                    hasAccess = true;
                    console.log(`[Backend-Bridge] Quyền được chấp thuận qua Scene cha.`);
                }
            }
        }

        if (!hasAccess) {
            console.warn(`[Backend-Denied] Scene: ${scene._id}, TourPrivacy: ${tour.privacy}, ScenePrivacy: ${scene.privacy}`);
            return res.status(403).json({ message: 'Bạn không có quyền truy cập cảnh này.' });
        }

        // Increment view count if not owner/admin and not a bot
        if (!isOwner && !isAdmin && !req.headers['user-agent']?.match(/bot|crawl|spider/i)) {
            scene.views = (scene.views || 0) + 1;
            const today = new Date();
            today.setHours(0, 0, 0, 0);
            const viewEntry = scene.viewHistory.find(entry => new Date(entry.date).setHours(0,0,0,0) === today.getTime());
            if (viewEntry) {
                viewEntry.count++;
            } else {
                scene.viewHistory.push({ date: today, count: 1 });
            }
            await scene.save();
        }
        res.json(scene);
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

// @route   PUT /api/scenes/:id
router.put('/:id', protect, uploadSinglePanorama, async (req, res) => {
    try {
        const { title, description, privacy, sharedWithUsers, sharedEmails, shareExpireDays, lat, lng } = req.body;
        const scene = await Scene.findById(req.params.id);

        if (!scene || (scene.createdBy.toString() !== req.user._id.toString() && req.user.role !== 'admin')) {
            return res.status(403).json({ message: 'Not authorized' });
        }

        // [BẢO MẬT] Chặn thay đổi Privacy trực tiếp trên Scene. Phải thông qua Tour.
        if (privacy && privacy !== scene.privacy) {
            return res.status(403).json({ 
                message: "Quyền riêng tư phải được quản lý tập trung tại cấp độ Tour." 
            });
        }

        const oldPrivacy = scene.privacy;
        scene.name = title || scene.name;
        scene.description = description !== undefined ? description : scene.description;
        scene.privacy = privacy || scene.privacy;
        if (lat) scene.gps.lat = parseFloat(lat);
        if (lng) scene.gps.lng = parseFloat(lng);

        // [BẢO MẬT] Tuyệt đối không cho phép thay đổi tourId qua API cập nhật Metadata
        // Một cảnh khi đã thuộc về một Tour thì không thể bị "chuyển hộ khẩu" sang Tour khác.
        // (Trường tourId không có trong danh sách bóc tách req.body ở trên)

        // [BẢO MẬT] Chỉ duy trì shareToken ở chế độ 'shared'. 
        // Gán undefined để Mongoose xóa trường này khỏi DB khi save.
        if (scene.privacy !== 'shared') {
            scene.shareToken = undefined; // Mongoose sẽ xóa field này khỏi document
            scene.shareTokenExpires = undefined; // Mướng sẽ xóa field này khỏi document
            // Nếu không phải 'member', xóa luôn danh sách chia sẻ người dùng
            if (scene.privacy !== 'member') {
                scene.sharedWith = [];
                scene.sharedEmails = [];
            }
        }

        if (scene.privacy !== 'private') {
            // Cập nhật danh sách chia sẻ nếu không phải chế độ Private
            if (sharedWithUsers) {
                try { scene.sharedWith = JSON.parse(sharedWithUsers); } catch (e) {}
            }
            if (sharedEmails) {
                try { scene.sharedEmails = JSON.parse(sharedEmails); } catch (e) {}
            }
        }

        if (scene.privacy === 'shared') {
            if (!scene.shareToken) scene.shareToken = crypto.randomBytes(24).toString('hex');
            if (shareExpireDays && shareExpireDays !== 'never') {
                const expires = new Date();
                expires.setDate(expires.getDate() + parseInt(shareExpireDays));
                scene.shareTokenExpires = expires;
            } else if (shareExpireDays === 'never') {
                scene.shareTokenExpires = null;
            }
        }

        if (req.file) {
            const userId = req.user._id.toString();
            const userUploadDir = path.join(uploadDir, userId);
            if (!fs.existsSync(userUploadDir)) {
                fs.mkdirSync(userUploadDir, { recursive: true });
            }

            const processedFileName = `processed_${req.file.filename}.jpg`;
            const processedFilePath = path.join(userUploadDir, processedFileName);
            await resizeTo8K(req.file.path, processedFilePath);
            await injectGPSCoordinates(processedFilePath, scene.gps.lat, scene.gps.lng);
            
            const asset = new Asset({ filePath: processedFilePath, uploadedBy: req.user._id });
            await asset.save();
            scene.assetId = asset._id;
            await fs.promises.unlink(req.file.path).catch(() => {});
        }

        // Đảm bảo tính nhất quán: Nếu không có tourId cha, scene này tự làm gốc
        if (!scene.tourId) scene.tourId = scene._id; 
        await scene.save();

        // Cập nhật lại vị trí trung tâm của Tour nếu tọa độ của Scene này thay đổi
        if (lat || lng) {
            const tourController = require('../middlewares/TourController');
            if (tourController.updateTourCenter) await tourController.updateTourCenter(scene.tourId);
        }

        res.json({ message: 'Cập nhật thành công và đã đồng bộ quyền riêng tư cho các cảnh liên quan.', scene });
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

// @route   DELETE /api/scenes/:id
router.delete('/:id', protect, async (req, res) => {
    try {
        const rootSceneId = req.params.id;
        const rootScene = await Scene.findById(rootSceneId);
        if (!rootScene) return res.status(404).json({ message: 'Scene không tồn tại' });

        if (req.user.role !== 'admin' && rootScene.createdBy.toString() !== req.user._id.toString()) {
            return res.status(403).json({ message: 'Forbidden' });
        }

        let tourId = rootScene.tourId; 

        const { deletedCount } = await deleteSceneCascade(rootSceneId, req.user._id);

        // --- NEW LOGIC TO UPDATE PARENT TOUR ---
        if (tourId) {
            const tour = await Tour.findById(tourId);
            if (tour) {
                // Remove the deleted scene from the tour's scenes array
                tour.scenes = tour.scenes.filter(sId => sId.toString() !== rootSceneId.toString());

                // If the deleted scene was the rootSceneId, find a new root or set to null
                if (tour.rootSceneId && tour.rootSceneId.toString() === rootSceneId.toString()) {
                    tour.rootSceneId = tour.scenes.length > 0 ? tour.scenes[0] : null;
                }

                // [KIỂM TRA CHÍNH XÁC] Đếm số lượng scene thực tế còn lại trong database của Tour này
                const actualRemainingScenes = await Scene.countDocuments({ tourId: tour._id });

                if (actualRemainingScenes === 0) {
                    await Tour.findByIdAndDelete(tour._id);
                    return res.json({ 
                        message: `Đã xóa Tour "${tour.name}" vì không còn cảnh nào bên trong.`,
                        tourDeleted: true 
                    });
                } else {
                    await tour.save();
                }
            }
        }
        // --- END NEW LOGIC ---

        res.json({ 
            message: deletedCount > 1 
                ? `Đã xóa scene cha và ${deletedCount - 1} scene con liên quan.` 
                : 'Đã xóa scene thành công.' 
        });
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

router.shareScene = shareScene; // Xuất hàm để apiRoutes sử dụng
module.exports = router;