import { FastifyPluginAsync, FastifyRequest, FastifyReply } from 'fastify';
import { UserController, UserRequestBody } from '../http/controllers/UserController';
import { UserService } from '../services/UserService';
import { UserRepository } from '../repositories/UserRepository';
import { UserRoleRepository } from '../repositories/UserRoleRepository';
import { User } from '../entities/user/_User';
import { UserRole } from '../entities/user/UserRole';
import auth from '../../../middleware/Auth';

declare module 'fastify' {
    interface FastifyInstance {
        userController: (request: FastifyRequest) => UserController;
    }
}

const userRoutes: FastifyPluginAsync = async (app) => {
    app.decorate('userController', (request: FastifyRequest) => {
        const userRepository = new UserRepository(request.em, User);
        const userRoleRepository = new UserRoleRepository(request.em, UserRole);
        const userService = new UserService(request.em, userRepository, userRoleRepository);
        return new UserController(userService);
    });

    app.get(
        '/',
        { preHandler: auth(['admin', 'user']) },
        async (request: FastifyRequest, reply: FastifyReply) => {
            const userController = app.userController(request);
            return userController.getAllUsers(request, reply);
        }
    );

    app.get(
        '/:id',
        async (request: FastifyRequest<{ Params: { id: number } }>, reply: FastifyReply) => {
            const userController = app.userController(request);
            return userController.getUserById(request, reply);
        }
    );

    app.post(
        '/',
        async (request: FastifyRequest<{ Body: UserRequestBody }>, reply: FastifyReply) => {
            const userController = app.userController(request);
            return userController.createUser(request, reply);
        }
    );

    app.post(
        '/login',
        async (
            request: FastifyRequest<{ Body: { username: string; password: string } }>,
            reply: FastifyReply
        ) => {
            const userController = app.userController(request);
            return userController.loginUser(request, reply);
        }
    );
};

export default userRoutes;
