const { updateTourCenter } = require('../middlewares/TourController');
const Scene = require('../models/Scene');
const Tour = require('../models/Tour');

// Mocking Mongoose models
jest.mock('../models/Scene');
jest.mock('../models/Tour');

describe('TourController - updateTourCenter', () => {
    const tourId = '507f1f77bcf86cd799439011';

    beforeEach(() => {
        jest.clearAllMocks();
        // Mock console.error to keep test output clean
        jest.spyOn(console, 'error').mockImplementation(() => {});
    });

    afterEach(() => {
        console.error.mockRestore();
    });

    test('nên tính toán trung bình GPS chính xác từ nhiều cảnh hợp lệ', async () => {
        const mockScenes = [
            { gps: { lat: 10.0, lng: 20.0 } },
            { gps: { lat: 20.0, lng: 40.0 } },
            { gps: { lat: 30.0, lng: 60.0 } }
        ];

        Scene.find.mockReturnValue({
            select: jest.fn().mockResolvedValue(mockScenes)
        });

        await updateTourCenter(tourId);

        // Trung bình: lat (10+20+30)/3 = 20, lng (20+40+60)/3 = 40
        expect(Tour.findByIdAndUpdate).toHaveBeenCalledWith(tourId, {
            location: { lat: 20.0, lng: 40.0 }
        }, {
            returnDocument: 'after'
        });
    });

    test('nên bỏ qua các cảnh có tọa độ (0,0), null hoặc không phải là số', async () => {
        const mockScenes = [
            { gps: { lat: 10.0, lng: 20.0 } },
            { gps: { lat: 0, lng: 0 } },           // Bỏ qua (0,0)
            { gps: null },                        // Bỏ qua null
            { gps: { lat: 'invalid', lng: 30 } }, // Bỏ qua vì không phải số
            { gps: { lat: 20.0, lng: 40.0 } }
        ];

        Scene.find.mockReturnValue({
            select: jest.fn().mockResolvedValue(mockScenes)
        });

        await updateTourCenter(tourId);

        // Chỉ tính 2 cảnh hợp lệ: lat (10+20)/2 = 15, lng (20+40)/2 = 30
        expect(Tour.findByIdAndUpdate).toHaveBeenCalledWith(tourId, {
            location: { lat: 15.0, lng: 30.0 }
        }, {
            returnDocument: 'after'
        });
    });

    test('không nên cập nhật Tour nếu không tìm thấy cảnh nào', async () => {
        Scene.find.mockReturnValue({
            select: jest.fn().mockResolvedValue([])
        });

        await updateTourCenter(tourId);

        expect(Tour.findByIdAndUpdate).not.toHaveBeenCalled();
    });

    test('không nên cập nhật Tour nếu không có cảnh nào mang GPS hợp lệ', async () => {
        const mockScenes = [
            { gps: { lat: 0, lng: 0 } },
            { gps: null }
        ];

        Scene.find.mockReturnValue({
            select: jest.fn().mockResolvedValue(mockScenes)
        });

        await updateTourCenter(tourId);

        expect(Tour.findByIdAndUpdate).not.toHaveBeenCalled();
    });

    test('nên log lỗi ra console nếu truy vấn Database thất bại', async () => {
        const errorMessage = 'Database connection lost';
        Scene.find.mockImplementation(() => {
            throw new Error(errorMessage);
        });

        await updateTourCenter(tourId);

        expect(console.error).toHaveBeenCalledWith(
            expect.stringContaining(`Error updating center for tour ${tourId}`),
            errorMessage
        );
        expect(Tour.findByIdAndUpdate).not.toHaveBeenCalled();
    });
});