const express = require('express');
const router = express.Router();
const Hotspot = require('../models/Hotspot');
const Scene = require('../models/Scene');
const { protect, optionalAuth } = require('../middlewares/authMiddleware');
const { calculateReverseYaw } = require('../utils/hotspotHelper');
const Tour = require('../models/Tour');

/**
 * @route   GET /api/hotspots/:scene_id
 * @desc    Lấy toàn bộ danh sách hotspot của một cảnh
 */
router.get('/:scene_id', optionalAuth, async (req, res) => {
    try {
        // [SECURITY] Kiểm tra quyền xem hotspots dựa trên quyền truy cập cảnh cha
        const scene = await Scene.findById(req.params.scene_id).populate('tourId');
        if (!scene) return res.status(404).json({ message: 'Scene not found' });
        
        const tour = scene.tourId;
        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);

        let hasAccess = (tour?.privacy === 'public') || (scene.privacy === 'public') || isOwner || isAdmin ||
            (scene.privacy === 'shared' && req.query.token === scene.shareToken && isSceneTokenValid) ||
            (tour?.privacy === 'shared' && req.query.token === tour.shareToken && isTourTokenValid) ||
            (tour?.privacy === 'member' && req.user && req.user._id && req.user.role !== 'guest');

        // Bridge Access cho Hotspots
        if (!hasAccess && req.query.token) {
            const potentialParents = await Hotspot.find({ target_scene_id: scene._id }).distinct('parent_scene_id');
            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(`[Backend-Hotspots-Denied] Scene: ${req.params.scene_id}`);
            return res.status(403).json({ message: 'Bạn không có quyền xem các điểm điều hướng của cảnh này.' });
        }

        const hotspots = await Hotspot.find({ parent_scene_id: req.params.scene_id })
            .populate({
                path: 'target_scene_id',
                select: 'name title assetId privacy shareToken',
                populate: { path: 'assetId', select: '_id' }
            })
            .lean();
        
        res.json(hotspots);
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

/**
 * @route   POST /api/hotspots/create
 * @desc    Tạo mới Hotspot và tự động tạo liên kết quay lại
 */
router.post('/create', protect, async (req, res) => {
    try {
        const { parent_scene_id, target_scene_id, title, description, coordinates } = req.body;
        
        const parentScene = await Scene.findById(parent_scene_id);
        if (!parentScene || (parentScene.createdBy.toString() !== req.user._id.toString() && req.user.role !== 'admin')) {
            return res.status(403).json({ message: 'Không có quyền tạo hotspot cho scene này' });
        }

        // [NEW LOGIC] Xử lý liên kết chéo giữa các Tour
        let target_tour_id = undefined;
        if (target_scene_id) {
            const targetScene = await Scene.findById(target_scene_id);
            if (targetScene && targetScene.tourId && parentScene.tourId && targetScene.tourId.toString() !== parentScene.tourId.toString()) {
                target_tour_id = targetScene.tourId;
            }
        }

        const hotspot = new Hotspot({
            parent_scene_id,
            target_scene_id,
            target_tour_id,
            title,
            description,
            coordinates: {
                yaw: Number(coordinates?.yaw) || 0,
                pitch: Number(coordinates?.pitch) || 0
            },
            is_auto_return: false
        });
        await hotspot.save();

        // [BẢO MẬT] Logic tạo liên kết quay lại tự động nếu có scene đích
        if (target_scene_id) {
            const targetScene = await Scene.findById(target_scene_id);
            if (targetScene) {
                // [TASK 3] BẢO VỆ tourId & CHẶN VANDALISM:
                // Chỉ tự động tạo link quay lại (tức là ghi dữ liệu vào cảnh đích) 
                // nếu người dùng hiện tại cũng là chủ sở hữu của cảnh đích đó.
                // Điều này đảm bảo:
                // 1. Không thay đổi cấu trúc tour của người khác khi tạo liên kết chéo (Cross-link).
                // 2. Tuyệt đối không can thiệp vào trường 'tourId' của targetScene.
                if (targetScene.createdBy.toString() === req.user._id.toString()) {
                    const reverseYaw = calculateReverseYaw(coordinates.yaw);
                const reverseHotspot = new Hotspot({
                    parent_scene_id: target_scene_id,
                    target_scene_id: parent_scene_id,
                    title: `Quay lại ${parentScene.name || parentScene.title}`,
                    coordinates: { yaw: reverseYaw, pitch: 0 },
                    is_auto_return: true
                });
                await reverseHotspot.save();
                }
            }
        }

        res.status(201).json(hotspot);
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

/**
 * @route   PUT /api/hotspots/update/:id
 * @desc    Cập nhật thông tin/vị trí hotspot
 */
router.put('/update/:id', protect, async (req, res) => {
    try {
        const { title, description, coordinates, target_scene_id } = req.body;
        const hotspot = await Hotspot.findById(req.params.id);
        if (!hotspot) return res.status(404).json({ message: 'Hotspot không tồn tại' });

        const parentScene = await Scene.findById(hotspot.parent_scene_id);
        if (parentScene.createdBy.toString() !== req.user._id.toString() && req.user.role !== 'admin') {
            return res.status(403).json({ message: 'Không có quyền cập nhật' });
        }

        // Cập nhật target_scene_id và tính toán lại target_tour_id nếu có thay đổi
        if (target_scene_id) {
            const targetScene = await Scene.findById(target_scene_id);
            if (targetScene) {
                hotspot.target_scene_id = target_scene_id;
                // Kiểm tra liên kết chéo
                if (targetScene.tourId && parentScene.tourId && targetScene.tourId.toString() !== parentScene.tourId.toString()) {
                    hotspot.target_tour_id = targetScene.tourId;
                } else {
                    hotspot.target_tour_id = undefined;
                }
            }
        }

        if (title) hotspot.title = title;
        if (description) hotspot.description = description;
        if (coordinates) hotspot.coordinates = coordinates;

        await hotspot.save();
        res.json(hotspot);
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

/**
 * @route   DELETE /api/hotspots/delete/:id
 * @desc    Xóa hotspot và liên kết quay lại tự động nếu có
 */
router.delete('/delete/:id', protect, async (req, res) => {
    try {
        const hotspot = await Hotspot.findById(req.params.id);
        if (!hotspot) return res.status(404).json({ message: 'Hotspot không tồn tại' });

        const parentScene = await Scene.findById(hotspot.parent_scene_id);
        if (parentScene.createdBy.toString() !== req.user._id.toString() && req.user.role !== 'admin') {
            return res.status(403).json({ message: 'Không có quyền xóa' });
        }

        // Xóa liên kết ngược nếu đây là cặp đôi tự động tạo
        if (hotspot.target_scene_id) {
            await Hotspot.deleteOne({
                parent_scene_id: hotspot.target_scene_id,
                target_scene_id: hotspot.parent_scene_id,
                is_auto_return: true
            });
        }

        await Hotspot.findByIdAndDelete(req.params.id);
        res.json({ message: 'Hotspot deleted successfully' });
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});

module.exports = router;