var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { HttpContext, ResponseStatus } from '@adonisjs/core/http';
import '@akago/vine-lucid';
import vine from '@vinejs/vine';
import { AKVineRequest, AKVineResponse, AKVineResponseErrors, AKVineResponseStatus, } from '../crud/vine_handler_decorators.js';
import { AKVineRequestData } from '../crud/vine_validate_middleware.js';
import { AKAPIException } from '../exceptions/api_exception.js';
import { OpenApiDescription } from '../openapi/openapi_router_macros.js';
import { AKJwtService, AKJwtTokenType } from './jwt/jwt_service.js';
import { passwordSchema } from './user/user.js';
export const authController = (authServiceClass, userServiceClass, signupVineSchema) => {
    const authService = new authServiceClass();
    const userService = new userServiceClass();
    const userWithTokensSchema = vine.object({
        user: vine.lucid(userService.model, { relations: userServiceClass.enabledRelations }),
        access_token: vine.string(),
        refresh_token: vine.string(),
    });
    class AKAuthController {
        async signup({ response, request }, { email, password, ...userData }) {
            const skipStripeAccountCreation = request.qs()['skipStripeAccountCreation'] === 'true';
            const { user, access_token, refresh_token } = await authService.signup(email, password, {
                ...userData,
                skipStripeAccountCreation,
            });
            return response.created({
                user: user.serialize(),
                access_token,
                refresh_token,
            });
        }
        async login(_ctx, { email, password }) {
            const { user, access_token, refresh_token } = await authService.login(email, password);
            return {
                user: user.serialize(),
                access_token,
                refresh_token,
            };
        }
        async check() {
            return true;
        }
        async refreshTokens({ auth }) {
            const user = auth.use('jwt').user;
            const { access_token, refresh_token } = await authService.createTokens(user);
            return {
                user: user.serialize(),
                access_token,
                refresh_token,
            };
        }
        async forgotPassword(_ctx, { email }) {
            await authService.forgotPassword(email);
        }
        async setPassword({ auth }, { password, previousPassword }) {
            const user = auth.use('jwt').user;
            const tokenIsSetPassword = AKJwtService.tokenHasType(auth.use('jwt').jwtPayload, AKJwtTokenType.setPassword);
            if (!tokenIsSetPassword)
                await authService.login(user.email, previousPassword);
            await authService.setPassword(user, password);
        }
        async delete({ auth, response }, { password, reason }) {
            const user = auth.use('jwt').user;
            await authService.delete(user, password, reason);
            return response.status(ResponseStatus.NoContent);
        }
    }
    __decorate([
        AKVineRequest(signupVineSchema),
        AKVineResponseStatus(ResponseStatus.Created),
        AKVineResponse(userWithTokensSchema),
        AKVineResponseErrors([AKAPIException.alreadyExist]),
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [HttpContext,
            AKVineRequestData]),
        __metadata("design:returntype", Promise)
    ], AKAuthController.prototype, "signup", null);
    __decorate([
        AKVineRequest(vine.object({
            email: vine.string().email(),
            password: passwordSchema,
        })),
        AKVineResponse(userWithTokensSchema),
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [HttpContext, AKVineRequestData]),
        __metadata("design:returntype", Promise)
    ], AKAuthController.prototype, "login", null);
    __decorate([
        OpenApiDescription(`Checks if request is authenticated`),
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", Promise)
    ], AKAuthController.prototype, "check", null);
    __decorate([
        OpenApiDescription(`Refresh jwt tokens by providing a valid refresh token`),
        AKVineResponse(userWithTokensSchema),
        AKVineResponseErrors([
            AKAPIException.auth.token.wrongType,
            AKAPIException.auth.token.typeUnknown,
        ]),
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [HttpContext]),
        __metadata("design:returntype", Promise)
    ], AKAuthController.prototype, "refreshTokens", null);
    __decorate([
        OpenApiDescription(`Sends a forgot password email to the user associated the provided email (if exists).`),
        AKVineRequest(vine.object({ email: vine.string().email() })),
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [HttpContext, AKVineRequestData]),
        __metadata("design:returntype", Promise)
    ], AKAuthController.prototype, "forgotPassword", null);
    __decorate([
        OpenApiDescription(`Set a user's password. Used mainly in forgot password flow.
    This endpoint needs to be authenticated with a token that has the \`setPassword\` type or \`previousPassword\` should be provided.`),
        AKVineRequest(vine.object({
            password: passwordSchema,
            previousPassword: passwordSchema.optional(),
        })),
        AKVineResponseErrors([
            AKAPIException.auth.token.wrongType,
            AKAPIException.auth.token.typeUnknown,
        ]),
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [HttpContext, AKVineRequestData]),
        __metadata("design:returntype", Promise)
    ], AKAuthController.prototype, "setPassword", null);
    __decorate([
        OpenApiDescription(`Deletes current user. It actually soft deletes it.`),
        AKVineRequest(vine.object({
            password: passwordSchema,
            reason: vine.string(),
        })),
        AKVineResponseErrors([AKAPIException.auth.wrongCredentials]),
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [HttpContext, AKVineRequestData]),
        __metadata("design:returntype", Promise)
    ], AKAuthController.prototype, "delete", null);
    return AKAuthController;
};
//# sourceMappingURL=auth_controller.js.map