import { ApiValidationError } from "../../Models/Server.Error.model";
import { Body, Controller, Post, Response, Route, SuccessResponse, Middlewares } from "tsoa";
import { LoginService } from "./Login.Service";
import {
    LoginParams,
    LoginByTokenParams,
    LoginByGoogleParams,
    VerificationUserParams,
} from "../../Models/Users/Users.Interface";
import { ISession } from "../../Models/Session.model";
import { authenticateMiddleware } from "../../middleware/authentication";

@Route("users/login")
export class LoginController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse("200", "Loged") // Custom success response
    @Post()
    public async login(@Body() requestBody: LoginParams): Promise<ISession | ApiValidationError> {
        try {
            const userLoged: ISession = await new LoginService().login(requestBody);
            this.setStatus(200);
            return userLoged;
        } catch (e) {
            const errorOccured: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccured.message);
        }
    }
}

@Route("users/verificate")
export class VerificateController extends Controller {
    @Response<ApiValidationError>(500, "Ha ocurrido un error")
    @SuccessResponse("200", "Loged") // Custom success response
    @Post()
    public async verificate(
        @Body() requestBody: VerificationUserParams
    ): Promise<ISession | ApiValidationError> {
        try {
            const userLoged: ISession = await new LoginService().verificateAndLoginUser(
                requestBody
            );
            this.setStatus(200);
            return userLoged;
        } catch (e) {
            const errorOccured: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccured.message);
        }
    }
}

@Route("users/loginbytoken")
export class LoginByTokenController extends Controller {
    @Response<ApiValidationError>(400, "Ha ocurrido un error")
    @SuccessResponse("200", "Loged") // Custom success response
    @Post()
    @Middlewares(authenticateMiddleware)
    public async loginByToken(
        @Body() requestBody: LoginByTokenParams
    ): Promise<ISession | ApiValidationError> {
        try {
            const userLoged: ISession = await new LoginService().loginByToken(requestBody);
            this.setStatus(200);
            return userLoged;
        } catch (e) {
            const errorOccured: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccured.message);
        }
    }
}

@Route("users/loginbygoogle")
export class LoginByGoogleController extends Controller {
    @Response<ApiValidationError>(400, "Ha ocurrido un error")
    @SuccessResponse("200", "Loged") // Custom success response
    @Post()
    public async loginByGoogle(
        @Body() requestBody: LoginByGoogleParams
    ): Promise<ISession | ApiValidationError> {
        try {
            const userLoged: ISession = await new LoginService().loginByGoogle(requestBody);
            this.setStatus(200);
            return userLoged;
        } catch (e) {
            const errorOccured: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccured.message);
        }
    }
}

@Route("users/loginbyandroid")
export class LoginByAndroidController extends Controller {
    @Response<ApiValidationError>(400, "Ha ocurrido un error")
    @SuccessResponse("200", "Loged") // Custom success response
    @Post()
    public async loginByAndroid(
        @Body() requestBody: LoginByGoogleParams
    ): Promise<ISession | ApiValidationError> {
        try {
            const userLoged: ISession = await new LoginService().loginByAndroid(requestBody);
            this.setStatus(200);
            return userLoged;
        } catch (e) {
            const errorOccured: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccured.message);
        }
    }
}
