import { z } from "zod/v4";
import { zPassword } from "~/hooks/usePassword";
import {
	adminProcedure,
	createTRPCRouter,
	protectedProcedure,
	publicProcedure,
} from "~/server/api/trpc";
import {
	createUserAdmin,
	logIn,
	logOut,
	passwordChange,
	swapAuth,
} from "~/server/controllers/auth.controller";
import {
	genPasswordResetToken,
	isTokenValid,
	passwordOverrideHandler,
	pwResetSendLinkHandler,
	resetPasswordFromTokenHandler,
} from "~/server/services/auth.service";
import { zUserId } from "~/server/utils/zod_types";

// Create a new ratelimiter, that allows 10 requests per 10 seconds
/*
const ratelimit = new RateLimiterHandler({
  windowSize: 10,
  maxRequests: 10,
  analytics: true,
});
*/

export const authRouter = createTRPCRouter({
	addUserAdmin: adminProcedure
		.input(
			z.object({
				cognome: z.string().nonempty("Inserisci un cognome valido"),
				email: z.email(),
				nome: z.string().nonempty("Inserisci un nome valido"),
				password: zPassword,
				telefono: z.string().nonempty("Inserisci un numero di telefono"),
			}),
		)
		.mutation(async ({ input }) => {
			return await createUserAdmin({ ...input });
		}),
	ChangePassword: protectedProcedure
		.input(
			z.object({
				newpassword: z.string(),
				oldpassword: z.string(),
			}),
		)
		.mutation(async ({ ctx, input }) => {
			return await passwordChange({
				userId: ctx.session.id,
				ctx,
				...input,
			});
		}),
	checkTokenValidity: publicProcedure
		.input(z.object({ token: z.string() }))
		.query(async ({ input }) => {
			return await isTokenValid({ token: input.token });
		}),

	genPswResetToken: adminProcedure
		.input(z.object({ id: zUserId }))
		.mutation(async ({ input }) => {
			return await genPasswordResetToken({ id: input.id });
		}),

	getSession: publicProcedure.query(async ({ ctx }) => {
		if (ctx.session?.isBlocked) return null;
		return { session: ctx.session, sessionStatus: ctx.sessionStatus };
	}),
	loginUser: publicProcedure
		.input(
			z.object({
				email: z.email(),
				password: z.string(),
			}),
		)
		.mutation(async ({ input, ctx }) => {
			return await logIn({
				...input,
				ctx: ctx,
			});
		}),

	logoutUser: protectedProcedure.mutation(async ({ ctx }) => {
		await logOut({ req: ctx.req, res: ctx.res });
		return "logout success";
	}),

	PasswordOverride: adminProcedure
		.input(
			z.object({
				id: zUserId,
				password: z.string(),
			}),
		)
		.mutation(async ({ input }) => {
			return await passwordOverrideHandler({ ...input });
		}),

	resetPasswordFromToken: publicProcedure
		.input(
			z.object({
				newpassword: z.string(),
				resetToken: z.string(),
			}),
		)
		.mutation(async ({ input }) => {
			return await resetPasswordFromTokenHandler({
				newpassword: input.newpassword,
				token: input.resetToken,
			});
		}),
	sendResetLink: publicProcedure
		.input(z.object({ email: z.string() }))
		.mutation(async ({ input }) => {
			return await pwResetSendLinkHandler({
				email: input.email,
			});
		}),
	swapUser: adminProcedure
		.input(
			z.object({
				id: zUserId,
			}),
		)
		.mutation(async ({ ctx, input }) => {
			return await swapAuth({ ctx, userId: input.id });
		}),
});
