import { FastifyReply, FastifyRequest } from 'fastify';
import { UserService } from '../../services/UserService';
import { UserRoleType } from '@/constants/roles';
import jwt from 'jsonwebtoken';

export type UserRequestBody = {
    username: string;
    password: string;
    email: string;
    roleName: UserRoleType;
};
export class UserController {
    constructor(private userService: UserService) {}

    async getAllUsers(req: FastifyRequest, reply: FastifyReply) {
        try {
            const users = await this.userService.getAllUsers();
            return reply.send(users);
        } catch (error) {
            console.error('Error in getAllUsers:', error);
            return reply.code(500).send(error);
        }
    }

    async getUserById(req: FastifyRequest<{ Params: { id: number } }>, reply: FastifyReply) {
        try {
            const user = await this.userService.getUserById(req.params.id);
            if (user) {
                return reply.send(user);
            } else {
                return reply.code(404).send({ message: 'User not found' });
            }
        } catch (error) {
            console.error('Error in getUserById:', error);
            return reply.code(500).send(error);
        }
    }

    async createUser(req: FastifyRequest<{ Body: UserRequestBody }>, reply: FastifyReply) {
        try {
            const { username, password, email, roleName } = req.body as UserRequestBody;

            const existingUser = await this.userService.getUserByUsername(username);

            if (existingUser) {
                return reply.code(409).send({ message: 'Username already exists' });
            }

            const user = await this.userService.createUserWithRole(
                username,
                password,
                email,
                roleName
            );
            return reply.code(201).send(user);
        } catch (error) {
            console.error('Error in createUser:', error);
            return reply.code(500).send(error);
        }
    }

    async loginUser(
        req: FastifyRequest<{ Body: { username: string; password: string } }>,
        reply: FastifyReply
    ) {
        try {
            const { username, password } = req.body;
            const user = await this.userService.authenticateUser(username, password);

            if (!user) {
                return reply.code(401).send({ 
                    success: false,
                    message: 'Invalid username or password' 
                });
            }

            const token = jwt.sign(
                {
                    id: user.id,
                    username: user.username,
                    roles: user.roles.map((role) => role.name),
                },
                process.env.JWT_SECRET as string,
                { expiresIn: '1h' }
            );

            return reply.send({ 
                success: true,
                message: 'Authentication successful', 
                data: {
                    token,
                    user: {
                        id: user.id,
                        username: user.username,
                        email: user.email,
                        roles: user.roles.map((role) => role.name)
                    }
                }
            });
        } catch (error) {
            console.error('Error in loginUser:', error);
            return reply.code(401).send({ 
                success: false,
                message: 'Authentication failed',
                error: error instanceof Error ? error.message : 'Unknown error'
            });
        }
    }
}
