import { Controller, UseGuards, HttpException, HttpStatus, Get, Post, Delete, Body, Req, Res } from '@nestjs/common';
import { AuthenticateGuard, TwoFactorGuard } from 'src/auth/42/guards/42guards';
import { ConnectedSocket } from '@nestjs/websockets';
import { ChatService } from './chat.service';
import { User } from 'src/users/entities/user.entity';
import { PartialUsersDto } from 'src/users/dto/partial-users.dto';
import { createRoomDto } from './dto/createRoom.dto';
import { joinRoomDto } from './dto/joinRoom.dto';
import { setCurrentRoomDto } from './dto/setCurrentRoom.dto';
import { ChatGateway } from './chat.gateway';

@Controller('chat')
export class ChatController {
	
	private allowed_chars: string;

	constructor(
		private chatService: ChatService,
		private chatGateway: ChatGateway,
	)
	{
		this.allowed_chars = "#!?-_";
	}


	@UseGuards(AuthenticateGuard)
	@UseGuards(TwoFactorGuard)
	@Get('myrooms')
	async getMyRooms(@Req() req, @Res() res): Promise<object>
	{
		console.log("- in getMyRooms controller");
		const rooms = await this.chatService.getMyRooms(req.user.username);
		console.log("- out getMyRooms controller");
		return res.status(HttpStatus.OK).json({ rooms: rooms });
	}

	@UseGuards(AuthenticateGuard)
	@UseGuards(TwoFactorGuard)
	@Get('allrooms')
	async getAllRooms(@Req() req, @Res() res): Promise<object>
	{
		console.log("- in getAllRooms controller");
		const rooms = await this.chatService.getAllNotMyRooms(req.user.username);
		console.log("- out getAllRooms controller");
		return res.status(HttpStatus.OK).json({ rooms: rooms });
	}

	@UseGuards(AuthenticateGuard)
	@UseGuards(TwoFactorGuard)
	@Get('current')
	async setCurrentRoom(@Body() setCurrentRoomDto: setCurrentRoomDto, @Req() req, @Res() res): Promise<object>
	{
		console.log("- in setCurrentRoom controller");
		const response = await this.chatService.setCurrentRoom(req.user.username, setCurrentRoomDto.name);
		console.log("- out setCurrentRoom controller");
		return res.status(HttpStatus.OK).json({ message: response });
	}

	@UseGuards(AuthenticateGuard)
	@UseGuards(TwoFactorGuard)
	@Get('allowedchars')
	async allowedChars(@Res() res): Promise<object>
	{
		console.log("- in allowedChars controller");
		console.log("- out allowedChars controller");
		return res.status(HttpStatus.OK).json({ chars: this.allowed_chars });
	}

	@UseGuards(AuthenticateGuard)
	@UseGuards(TwoFactorGuard)
	@Post('create')
	async createRoom(@Body() createRoomDto: createRoomDto, @Req() req, @Res() res): Promise<object>
	{
		console.log("- in createRoom controller");

		let regex_base = `[a-zA-Z0-9\\s${this.allowed_chars}]`;
		let test_regex = new RegExp(`^${regex_base}+$`);
		if (test_regex.test(createRoomDto.room_name) === false)
		{
			let forbidden_chars = createRoomDto.room_name.replace(new RegExp(regex_base, "g"), "");
			throw new HttpException(`Your room name can not contains these characters : ${forbidden_chars}`, HttpStatus.UNPROCESSABLE_ENTITY);
		}

		const response = await this.chatService.addUserToNewRoom(req.user.username, createRoomDto);
		console.log("- out createRoom controller");
		return res.status(HttpStatus.OK).json({ room_name: createRoomDto.room_name, message: response });
	}

	@UseGuards(AuthenticateGuard)
	@UseGuards(TwoFactorGuard)
	@Post('join')
	async joinRoom(@Body() joinRoomDto: joinRoomDto, @Req() req, @Res() res): Promise<object>
	{
		console.log("- in joinRoom controller");
		console.log("-- room_name", joinRoomDto.room_name);
		const response = await this.chatService.addUserToRoom(req.user.username, joinRoomDto.room_name);

		//this.chatGateway.joinRoom(null, joinRoomDto.room_name);

		console.log("- out joinRoom controller");
		return res.status(HttpStatus.OK).json({ room_name: joinRoomDto.room_name, message: response });
	}

	@UseGuards(AuthenticateGuard)
	@UseGuards(TwoFactorGuard)
	@Post('change')
	async changeRoom(@Body() joinRoomDto: joinRoomDto, @Req() req, @Res() res): Promise<object>
	{
		console.log("- in changeRoom controller");
		const response = await this.chatService.setCurrentRoom(req.user.username, joinRoomDto.room_name);
		console.log("- out changeRoom controller");
		return res.status(HttpStatus.OK).json({ room_name: joinRoomDto.room_name, message: response });
	}

	@UseGuards(AuthenticateGuard)
	@UseGuards(TwoFactorGuard)
	@Post('leave')
	async leaveRoom(@Body() body)
	{
		console.log("- in leaveRoom controller");
		console.log("- out leaveRoom controller");
	}

	@UseGuards(AuthenticateGuard)
	@UseGuards(TwoFactorGuard)
	@Get('messages')
	async getMessages(@Req() req, @Res() res): Promise<object>
	{
		console.log("- in getMessages controller");
		const messages = await this.chatService.getMessagesFromCurrentRoom(req.user.username);
		console.log("- out getMessages controller");
		return res.status(HttpStatus.OK).json({ messages: messages });
	}

	@UseGuards(AuthenticateGuard)
	@UseGuards(TwoFactorGuard)
	@Get('roomusers')
	async getRoomUsers(@Req() req, @Res() res): Promise<object>
	{
		console.log("- in getRoomUsers controller");
		const room_name = await this.chatService.getCurrentRoomName(req.user.username);
		const room = await this.chatService.getRoomByName(room_name);
		const users = room.users;
		console.log("- out getRoomUsers controller");
		return res.status(HttpStatus.OK).json({ users: users });
	}

	@UseGuards(AuthenticateGuard)
	@UseGuards(TwoFactorGuard)
	@Delete('removeuser')
	async removeUser(@Req() req, @Res() res): Promise<object>
	{
		console.log("- in removeUser controller");
		const room_name = await this.chatService.getCurrentRoomName(req.user.username);
		let response = await this.chatService.removeUserFromRoom(req.user.username, room_name);
		console.log("- out removeUser controller");
		return res.status(HttpStatus.OK).json({ message: response });
	}

}

