import express from 'express';
import request from 'supertest';
import bodyParser from 'body-parser';
import { generateToken } from '../auth';
import { resetMemoryStorage } from '../storage/memory';
import { FeatureRequest } from '../../../types/gen/types.gen';
import votingRouter from '../routes/votingRoutes';

const VALID_OPTION = FeatureRequest.STATISTICS;

function buildApp() {
    const app = express();
    app.use(bodyParser.json());
    app.use('/api/voting', votingRouter);
    app.use((err: any, _req: any, res: any, _next: any) => {
        res.status(400).json({ error: err.message });
    });
    return app;
}

const TOKEN = `Bearer ${generateToken('testuser')}`;

beforeEach(() => {
    resetMemoryStorage();
});

test('GET /getVotes vrátí 200 s prázdným polem pro nového uživatele', async () => {
    const res = await request(buildApp())
        .get('/api/voting/getVotes')
        .set('Authorization', TOKEN);
    expect(res.status).toBe(200);
    expect(res.body).toEqual([]);
});

test('GET /getVotes vrátí 401 bez tokenu', async () => {
    const res = await request(buildApp()).get('/api/voting/getVotes');
    expect(res.status).toBeGreaterThanOrEqual(400);
});

test('POST /updateVote přidá hlas a vrátí 200', async () => {
    const res = await request(buildApp())
        .post('/api/voting/updateVote')
        .set('Authorization', TOKEN)
        .send({ option: VALID_OPTION, active: true });
    expect(res.status).toBe(200);
});

test('POST /updateVote vrátí 400 pro chybějící parametry', async () => {
    const res = await request(buildApp())
        .post('/api/voting/updateVote')
        .set('Authorization', TOKEN)
        .send({});
    expect(res.status).toBe(400);
});

test('POST /updateVote vrátí 400 při duplicitním hlasu', async () => {
    const app = buildApp();
    await request(app)
        .post('/api/voting/updateVote')
        .set('Authorization', TOKEN)
        .send({ option: VALID_OPTION, active: true });
    const res = await request(app)
        .post('/api/voting/updateVote')
        .set('Authorization', TOKEN)
        .send({ option: VALID_OPTION, active: true });
    expect(res.status).toBe(400);
    expect(res.body.error).toContain('hlasovali');
});

test('GET /stats vrátí 200 s objektem', async () => {
    const res = await request(buildApp())
        .get('/api/voting/stats')
        .set('Authorization', TOKEN);
    expect(res.status).toBe(200);
    expect(typeof res.body).toBe('object');
});
