const express = require('express');
const router = express.Router();
const path = require('path');
const fs = require('fs');
const sharp = require('sharp');
const jwt = require('jsonwebtoken');

const Asset = require('../models/Asset');
const Scene = require('../models/Scene');
const Hotspot = require('../models/Hotspot');
const { protect, optionalAuth } = require('../middlewares/authMiddleware');
const { verifyReferer } = require('../middlewares/securityMiddleware');
const { deleteSceneCascade } = require('../utils/sceneHelper');
const { logActivity } = require('../utils/logger');

// Chuẩn hóa đường dẫn uploads (Giai đoạn 1)
const uploadDir = process.env.UPLOAD_DIR 
    ? path.resolve(process.env.UPLOAD_DIR) 
    : path.join(__dirname, '../uploads');

/**
 * @route   GET /api/assets/view/:assetId
 * @desc    Stream ảnh panorama (Có Referer & Token Verification)
 */
router.get('/assets/view/:assetId', verifyReferer, optionalAuth, async (req, res) => {
    try {
        console.log(`[AssetView] Đang yêu cầu hiển thị Asset: ${req.params.assetId}. Token: ${req.query.token ? 'Có' : 'Không'}`);

        const asset = await Asset.findById(req.params.assetId);
        if (!asset) return res.status(404).json({ message: 'Asset not found' });

        // [FIX] Luôn kiểm tra JWT từ query string ngay cả khi optionalAuth đã chạy
        let user = req.user;
        const isGuest = !user || user.role === 'guest';
        if (isGuest && req.query.token) {
            try {
                const decoded = jwt.verify(req.query.token, process.env.JWT_SECRET || 'your_jwt_secret');
                if (decoded && decoded.id) {
                    const User = require('../models/User');
                    const authenticatedUser = await User.findById(decoded.id);
                    if (authenticatedUser) user = authenticatedUser;
                }
            } catch (e) {
            }
        }

        const isAdmin = user && (user.role === 'admin' || user.role === 'moderator');
        const userIdStr = user && user._id ? user._id.toString() : null;
        const userEmail = user ? user.email : null;

        // Kiểm tra quyền truy cập dựa trên Privacy của Scene liên kết
        const scene = await Scene.findOne({ assetId: asset._id }).populate('tourId');
        if (!scene) {
            // Asset mồ côi, chỉ chủ sở hữu được xem
            if (!isAdmin && (!userIdStr || userIdStr !== asset.uploadedBy.toString())) {
                return res.status(403).json({ message: 'Bạn không được phép di chuyển đến cảnh này' });
            }
        } else {
            const isSceneTokenValid = scene.shareToken && (!scene.shareTokenExpires || new Date() < scene.shareTokenExpires);
            const tour = scene.tourId;
            const isTourTokenValid = tour && tour.shareToken && (!tour.shareTokenExpires || new Date() < tour.shareTokenExpires);
            
            // Chuẩn hóa ID người tạo để so sánh
            const sceneOwnerId = scene.createdBy?._id || scene.createdBy || scene.owner?._id || scene.owner;
            const isOwner = userIdStr && sceneOwnerId && sceneOwnerId.toString() === userIdStr;

            let hasAccess = isAdmin || 
                scene.privacy === 'public' || 
                (tour && tour.privacy === 'public') ||
                (scene.privacy === 'member' && userIdStr && (scene.sharedWith.some(id => id.toString() === userIdStr) || (userEmail && scene.sharedEmails.includes(userEmail)))) ||
                isOwner ||
                (scene.privacy === 'shared' && req.query.token === scene.shareToken && isSceneTokenValid) ||
                (tour && tour.privacy === 'shared' && req.query.token === tour.shareToken && isTourTokenValid);

            if (scene.status === 'processing' && !hasAccess) {
                return res.status(403).json({ message: 'Ảnh đang được xử lý và bạn không có quyền xem tạm thời' });
            }

            // [BRIDGE ACCESS LOGIC]
            // Áp dụng tương tự cho Asset để đảm bảo hiển thị được ảnh khi di chuyển liên kết chéo
            if (!hasAccess && req.query.token) {
                const potentialParents = await Hotspot.find({ target_scene_id: scene._id }).distinct('parent_scene_id');
                if (potentialParents.length > 0) {
                    const authorizedParentExists = await Scene.exists({
                        _id: { $in: potentialParents },
                        shareToken: req.query.token,
                        $or: [{ shareTokenExpires: null }, { shareTokenExpires: { $gt: new Date() } }]
                    });
                    if (authorizedParentExists) hasAccess = true;
                }
            }

            if (!hasAccess) {
                console.warn(`[AssetView Denied] Không có quyền xem ảnh cho Asset ${asset._id}`);
                return res.status(403).json({ message: 'Bạn không được phép di chuyển đến cảnh này' });
            }
        }

        // Kiểm tra file vật lý (Giai đoạn 2 - Async)
        try { 
            await fs.promises.access(asset.filePath); 
        } catch (e) {
            return res.status(404).json({ message: 'Physical file not found on disk' });
        }

        const resolvedPath = path.resolve(asset.filePath);
        
        // Xử lý Watermark cho mạng xã hội hoặc yêu cầu thủ công
        const userAgent = req.headers['user-agent'] || '';
        const isSocialBot = /facebookexternalhit|Facebot|ZaloBot|Twitterbot|Slackbot|LinkedInBot|Embedly/i.test(userAgent);
        
        if (isSocialBot || req.query.watermark === 'true') {
            const iconPath = path.join(__dirname, '../assets/static/360-badge.png');
            if (fs.existsSync(iconPath)) {
                try {
                    const buffer = await sharp(resolvedPath)
                        .resize(1200, 1200, { fit: 'cover' })
                        .composite([{ input: iconPath, gravity: 'center' }])
                        .jpeg({ quality: 90 })
                        .toBuffer();
                    res.set({
                        'Content-Type': 'image/jpeg',
                        'Cache-Control': 'public, max-age=2592000'
                    });
                    return res.send(buffer);
                } catch (e) {
                    console.error("[Assets] Watermark processing failed:", e.message);
                }
            }
        }

        // Stream file với caching tốt
        res.sendFile(resolvedPath, {
            maxAge: 2592000000, // 30 ngày
            headers: {
                'Content-Type': 'image/jpeg',
                'Cache-Control': 'public, max-age=2592000, immutable'
            }
        });
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

/**
 * @route   GET /api/assets/view_avatar/:filename
 * @desc    Stream ảnh đại diện
 */
router.get('/assets/view_avatar/:filename', async (req, res) => {
    try {
        const avatarPath = path.join(uploadDir, req.params.filename);
        try { 
            await fs.promises.access(avatarPath); 
        } catch (e) {
            return res.status(404).json({ message: 'Avatar not found' });
        }
        res.sendFile(avatarPath, { 
            maxAge: 2592000000,
            headers: { 'Content-Type': 'image/jpeg' } 
        });
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

/**
 * @route   GET /api/me/assets
 * @desc    Kho ảnh của tôi (Dùng cho Dashboard Media Library)
 */
router.get('/me/assets', protect, async (req, res) => {
    try {
        const query = (req.user.role === 'admin') ? {} : { uploadedBy: req.user._id };
        
        const assets = await Asset.aggregate([
            { $match: query },
            { $lookup: { from: 'scenes', localField: '_id', foreignField: 'assetId', as: 'linkedScene' } },
            { $unwind: { path: '$linkedScene', preserveNullAndEmptyArrays: true } },
            { $lookup: { from: 'hotspots', localField: 'linkedScene._id', foreignField: 'target_scene_id', as: 'incomingHotspots' } },
            { $lookup: { from: 'scenes', localField: 'incomingHotspots.parent_scene_id', foreignField: '_id', as: 'parentScenes' } },
            { $project: { filePath: 0 } },
            { $sort: { createdAt: -1 } }
        ]);
        res.json(assets);
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

/**
 * @route   GET /api/me/assets/top-large
 * @desc    Thống kê 5 file chiếm dung lượng lớn nhất
 */
router.get('/me/assets/top-large', protect, async (req, res) => {
    try {
        const topAssets = await Asset.aggregate([
            { $match: { uploadedBy: req.user._id } },
            { $sort: { fileSize: -1 } },
            { $limit: 5 },
            { $lookup: { from: 'scenes', localField: '_id', foreignField: 'assetId', as: 'scene' } },
            { $unwind: { path: '$scene', preserveNullAndEmptyArrays: true } },
            { $project: { fileSize: 1, createdAt: 1, 'scene.name': 1, 'scene.title': 1, 'scene._id': 1 } }
        ]);
        res.json(topAssets);
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

/**
 * @route   DELETE /api/assets/:id
 * @desc    Xóa file vật lý và bản ghi (kèm Scene liên quan)
 */
router.delete('/assets/:id', protect, async (req, res) => {
    try {
        const asset = await Asset.findById(req.params.id);
        if (!asset) return res.status(404).json({ message: 'Asset not found' });

        if (asset.uploadedBy.toString() !== req.user._id.toString() && req.user.role !== 'admin') {
            return res.status(403).json({ message: 'Bạn không có quyền xóa tập tin này' });
        }

        const linkedScene = await Scene.findOne({ assetId: asset._id });
        if (linkedScene) {
            await deleteSceneCascade(linkedScene._id, req.user._id);
        } else {
            // Nếu là asset mồ côi (không gắn scene)
            if (asset.filePath) await fs.promises.unlink(asset.filePath).catch(() => {});
            await Asset.findByIdAndDelete(req.params.id);
            await logActivity('ORPHAN_ASSET_DELETE', { assetId: req.params.id }, req.user._id.toString());
        }

        res.json({ message: 'Đã xóa ảnh và dữ liệu liên quan thành công' });
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

module.exports = router;