const axios = require('axios');
jest.mock('axios');

const {
    createComplain,
    deleteComplain,
    updateComplain,
    getComplainsByTargetUser,
    getComplainsByPostingUser,
    getAllComplains,
    getComplainDetailById
} = require('../complain');

describe('Complain API Tests', () => {
    beforeEach(() => {
        jest.clearAllMocks();
    });

    test('createComplain should post complain data', async () => {
        const mockData = { data: { complainid: 1 } };
        const complainPayload = { puse: 1, duser: 2, content: 'test', torrentid: 99 };
        axios.post.mockResolvedValue(mockData);

        const response = await createComplain(complainPayload);

        expect(axios.post).toHaveBeenCalledWith(
            'http://localhost:8080/complain/create',
            complainPayload
        );
        expect(response).toEqual(mockData.data);
    });

    test('deleteComplain should send delete request', async () => {
        const mockData = { data: true };
        axios.delete.mockResolvedValue(mockData);

        const response = await deleteComplain(1);

        expect(axios.delete).toHaveBeenCalledWith('http://localhost:8080/complain/delete/1');
        expect(response).toBe(true);
    });

    test('updateComplain should put complain data', async () => {
        const complainPayload = { complainid: 1, content: 'updated' };
        const mockData = { data: true };
        axios.put.mockResolvedValue(mockData);

        const response = await updateComplain(complainPayload);

        expect(axios.put).toHaveBeenCalledWith(
            'http://localhost:8080/complain/update',
            complainPayload
        );
        expect(response).toBe(true);
    });

    test('getComplainsByTargetUser should fetch complains by duser', async () => {
        const mockData = { data: [{ complainid: 1, duser: 2 }] };
        axios.get.mockResolvedValue(mockData);

        const response = await getComplainsByTargetUser(2);

        expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/complain/target/2');
        expect(response).toEqual(mockData.data);
    });

    test('getComplainsByPostingUser should fetch complains by puse', async () => {
        const mockData = { data: [{ complainid: 1, puse: 1 }] };
        axios.get.mockResolvedValue(mockData);

        const response = await getComplainsByPostingUser(1);

        expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/complain/from/1');
        expect(response).toEqual(mockData.data);
    });

    test('getAllComplains should fetch all complains', async () => {
        const mockData = { data: [{ complainid: 1 }] };
        axios.get.mockResolvedValue(mockData);

        const response = await getAllComplains();

        expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/complain/all');
        expect(response).toEqual(mockData.data);
    });

    test('getComplainDetailById should fetch detailed complain info', async () => {
        const mockData = { data: { complainid: 1, puse: 1, duser: 2 } };
        axios.get.mockResolvedValue(mockData);

        const response = await getComplainDetailById(1);

        expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/complain/detail/1');
        expect(response).toEqual(mockData.data);
    });
});
