import { z } from "zod/v4";
import type { OrdiniUpdate } from "~/schemas/public/Ordini";
import type { PaymentsUpdate } from "~/schemas/public/Payments";
import type { NewServizio, ServizioUpdate } from "~/schemas/public/Servizio";
import type { ServizioAnnunciUpdate } from "~/schemas/public/ServizioAnnunci";
import type { Users } from "~/schemas/public/Users";
import type { UsersAnagraficaUpdate } from "~/schemas/public/UsersAnagrafica";
import {
	adminProcedure,
	createTRPCRouter,
	protectedProcedure,
	publicProcedure,
} from "~/server/api/trpc";
import {
	getOrdineById,
	getOrdini,
	removeOrder,
	updateOrder,
} from "~/server/controllers/ordini.controller";
import {
	addServizio,
	addServizioAnnunci,
	adminUpdateConfermaStatus,
	deleteServizio,
	deleteServizioAnnuncio,
	getAllPagamenti,
	getAllServizioAnnunci,
	getAnnunciAvailableToAdd,
	getCompatibileAnnunci,
	getDataPerAcquisto,
	getOrdineRicevutaData,
	getPacksPerServizio,
	getPreOnboardData,
	getServiziByUserId,
	getServizioAnnuncio,
	getServizioById,
	getServizioPagamentoData,
	getUserPagamenti,
	InteractionLogicTipologia,
	interruzioneServizio,
	isOrdineAwaitingPayment,
	postAcquistoDataHandler,
	removePagamento,
	SbloccaContatti,
	SendContactEmail,
	setupSaldoConsulenzaServizio,
	setupSaldoServizio,
	updatePagamento,
	updateServizio,
	updateServizioAnnuncio,
	userAccettaConferma,
	userSendConfermaIntent,
} from "~/server/controllers/servizio.controller";
import {
	zAnnuncioId,
	zOrdineId,
	zPagamentoId,
	zServizioId,
	zUserId,
} from "~/server/utils/zod_types";

export const servizioRouter = createTRPCRouter({
	AnnuncioServizioTipologiaMatch: protectedProcedure
		.input(
			z.object({
				annuncioId: zAnnuncioId,
				tipologia: z.string(),
				userId: zUserId,
			}),
		)
		.query(async ({ input }) => {
			return await InteractionLogicTipologia({
				annuncioId: input.annuncioId,
				tipologia: input.tipologia,
				userId: input.userId,
			});
		}),
	addServizio: adminProcedure
		.input(
			z.object({
				data: z.custom<NewServizio>(),
			}),
		)
		.mutation(async ({ input }) => {
			return await addServizio(input.data);
		}),
	addServizioAnnunci: adminProcedure
		.input(
			z.object({
				annunci: z.array(zAnnuncioId),
				servizioId: zServizioId,
			}),
		)
		.mutation(async ({ input }) => {
			return await addServizioAnnunci({
				annunci: input.annunci,
				servizioId: input.servizioId,
			});
		}),
	deleteServizio: adminProcedure
		.input(
			z.object({
				servizioId: zServizioId,
			}),
		)
		.mutation(async ({ input }) => {
			return await deleteServizio(input.servizioId);
		}),

	getAcquistoData: protectedProcedure
		.input(
			z.object({
				servizioId: zServizioId,
			}),
		)
		.query(async ({ input }) => {
			return await getDataPerAcquisto(input.servizioId);
		}),
	getAllPagamenti: adminProcedure.query(async () => {
		return await getAllPagamenti();
	}),
	getAllServizioAnnunci: protectedProcedure
		.input(
			z.object({
				userId: zUserId,
			}),
		)
		.query(async ({ input }) => {
			return await getAllServizioAnnunci(input.userId);
		}),
	getAnnunciAvailableToAdd: adminProcedure
		.input(
			z.object({
				servizioId: zServizioId,
			}),
		)
		.query(async ({ input }) => {
			return await getAnnunciAvailableToAdd(input.servizioId);
		}),

	getCompatibileAnnunci: protectedProcedure
		.input(
			z.object({
				servizioId: zServizioId,
				adminOverride: z.boolean().optional(),
			}),
		)
		.query(async ({ input }) => {
			return await getCompatibileAnnunci({ ...input });
		}),
	getOrdineById: protectedProcedure
		.input(
			z.object({
				ordineId: zOrdineId,
			}),
		)
		.query(async ({ input }) => {
			return await getOrdineById(input.ordineId);
		}),
	getOrdineRicevutaData: protectedProcedure
		.input(
			z.object({
				ordineId: zOrdineId,
			}),
		)
		.query(async ({ input, ctx }) => {
			return await getOrdineRicevutaData({ ctx, ordineId: input.ordineId });
		}),
	getOrdini: protectedProcedure
		.input(
			z.object({
				userId: zUserId.optional(),
			}),
		)
		.query(async ({ input }) => {
			return await getOrdini(input.userId);
		}),
	getPreOnboardData: publicProcedure
		.input(
			z.object({
				servizioId: zServizioId,
			}),
		)
		.query(async ({ input }) => {
			return await getPreOnboardData(input.servizioId);
		}),
	getServizio: protectedProcedure
		.input(
			z.object({
				servizioId: zServizioId,
			}),
		)
		.query(async ({ input }) => {
			return await getServizioById(input.servizioId);
		}),
	getServizioAnnuncio: protectedProcedure
		.input(
			z.object({
				annuncioId: zAnnuncioId,
				servizioId: zServizioId,
			}),
		)
		.query(async ({ input }) => {
			return await getServizioAnnuncio({
				annuncioId: input.annuncioId,
				servizioId: input.servizioId,
			});
		}),
	getServizioPaymentData: protectedProcedure
		.input(
			z.object({
				ordineId: zOrdineId,
			}),
		)
		.query(async ({ input }) => {
			return await getServizioPagamentoData(input.ordineId);
		}),
	getUserPagamenti: protectedProcedure
		.input(
			z.object({
				userId: zUserId,
			}),
		)
		.query(async ({ input }) => {
			return await getUserPagamenti(input.userId);
		}),

	getUserServizi: adminProcedure
		.input(
			z.object({
				userId: zUserId,
			}),
		)
		.query(async ({ input }) => {
			return await getServiziByUserId(input.userId);
		}),
	interruzioneServizio: protectedProcedure
		.input(
			z.object({
				servizioId: zServizioId,
			}),
		)
		.mutation(async ({ input }) => {
			return await interruzioneServizio(input.servizioId);
		}),
	isOrdineAwaitingPayment: protectedProcedure
		.input(
			z.object({
				ordineId: zOrdineId,
			}),
		)
		.query(async ({ input }) => {
			return await isOrdineAwaitingPayment(input.ordineId);
		}),

	submitOnboardForPurchase: protectedProcedure
		.input(
			z.object({
				anagrafica: z.custom<UsersAnagraficaUpdate>(),
				servizio: z.custom<ServizioUpdate>(),
				servizioId: zServizioId,
				user: z.custom<
					Pick<Users, "nome" | "cognome" | "email" | "telefono" | "username">
				>(),
				userId: zUserId,
			}),
		)
		.mutation(async ({ input }) => {
			return await postAcquistoDataHandler({
				...input,
			});
		}),
	removeAnnuncioServizio: protectedProcedure
		.input(
			z.object({
				annuncioId: zAnnuncioId,
				servizioId: zServizioId,
			}),
		)
		.mutation(async ({ input }) => {
			return await deleteServizioAnnuncio(input.servizioId, input.annuncioId);
		}),
	removeOrder: adminProcedure
		.input(
			z.object({
				ordineId: zOrdineId,
			}),
		)
		.mutation(async ({ input }) => {
			return await removeOrder(input.ordineId);
		}),
	removePagamento: adminProcedure
		.input(
			z.object({
				pagamentoId: zPagamentoId,
			}),
		)
		.mutation(async ({ input }) => {
			return await removePagamento(input.pagamentoId);
		}),

	sendContattoEmail: publicProcedure
		.input(
			z.object({
				codice: z.string(),
				email: z.string(),
				messaggio: z.string(),
				nome: z.string(),
				telefono: z.string(),
			}),
		)
		.mutation(async ({ input }) => {
			return await SendContactEmail({
				...input,
			});
		}),

	setupSaldoConsulenzaServizio: protectedProcedure
		.input(
			z.object({
				annuncioId: zAnnuncioId,
				servizioId: zServizioId,
			}),
		)
		.mutation(async ({ input }) => {
			return await setupSaldoConsulenzaServizio({
				annuncioId: input.annuncioId,
				servizioId: input.servizioId,
			});
		}),
	setupSaldoServizio: protectedProcedure
		.input(
			z.object({
				annuncioId: zAnnuncioId,
				servizioId: zServizioId,
			}),
		)
		.mutation(async ({ input }) => {
			return await setupSaldoServizio({
				annuncioId: input.annuncioId,
				servizioId: input.servizioId,
			});
		}),
	getPacksSolution: protectedProcedure
		.input(
			z.object({
				servizioId: zServizioId,
			}),
		)
		.query(async ({ input }) => {
			return await getPacksPerServizio(input.servizioId);
		}),
	unlockServizioContatti: protectedProcedure
		.input(
			z.object({
				annuncioId: zAnnuncioId,
				servizioId: zServizioId,
			}),
		)
		.mutation(async ({ input }) => {
			return await SbloccaContatti({
				annuncioId: input.annuncioId,
				servizioId: input.servizioId,
			});
		}),

	updateOrder: adminProcedure
		.input(
			z.object({
				data: z.custom<OrdiniUpdate>(),
				ordineId: zOrdineId,
			}),
		)
		.mutation(async ({ input }) => {
			return await updateOrder({
				data: input.data,
				ordineId: input.ordineId,
			});
		}),
	updatePagamento: adminProcedure
		.input(
			z.object({
				data: z.custom<PaymentsUpdate>(),
				pagamentoId: zPagamentoId,
			}),
		)
		.mutation(async ({ input }) => {
			return await updatePagamento({
				data: input.data,
				paymentId: input.pagamentoId,
			});
		}),
	updateServizio: protectedProcedure
		.input(
			z.object({
				data: z.custom<ServizioUpdate>(),
				servizioId: zServizioId,
			}),
		)
		.mutation(async ({ input }) => {
			return await updateServizio({
				data: input.data,
				servizioId: input.servizioId,
			});
		}),
	updateServizioAnnunci: protectedProcedure
		.input(
			z.object({
				annuncioId: zAnnuncioId,
				data: z.custom<ServizioAnnunciUpdate>(),
				servizioId: zServizioId,
			}),
		)
		.mutation(async ({ input }) => {
			return await updateServizioAnnuncio({
				annuncioId: input.annuncioId,
				data: input.data,
				servizioId: input.servizioId,
			});
		}),
	adminUpdateConfermaStatus: adminProcedure
		.input(
			z.object({
				annuncioId: zAnnuncioId,
				servizioId: zServizioId,
				status: z.boolean(),
			}),
		)
		.mutation(async ({ input }) => {
			return await adminUpdateConfermaStatus({
				annuncioId: input.annuncioId,
				servizioId: input.servizioId,
				status: input.status,
			});
		}),
	userSendConfermaIntent: protectedProcedure
		.input(
			z.object({
				annuncioId: zAnnuncioId,
				servizioId: zServizioId,
			}),
		)
		.mutation(async ({ input }) => {
			return await userSendConfermaIntent({
				annuncioId: input.annuncioId,
				servizioId: input.servizioId,
			});
		}),
	userAcceptConfermaImmobile: protectedProcedure
		.input(
			z.object({
				annuncioId: zAnnuncioId,
				servizioId: zServizioId,
			}),
		)
		.mutation(async ({ input }) => {
			return await userAccettaConferma({
				annuncioId: input.annuncioId,
				servizioId: input.servizioId,
			});
		}),
});
