import { TRPCError } from "@trpc/server";
import { z } from "zod";

import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";

export const saleRouter = createTRPCRouter({
  createSale: protectedProcedure
    .input(
      z.object({
        discount_percent: z.number().nullish(),
        discount_absolute: z.number().nullish(),
        total_discount: z.number().nullish(),
        total_sale: z.number(),
        total_paid: z.number(),
        customer_id: z.number().optional(),
        sale_items: z
          .object({
            product_id: z.number(),
            quantity: z.number(),
            price: z.number(),
          })
          .array(),
        sale_payments: z
          .object({
            payment_method_id: z.number(),
            value: z.number(),
          })
          .array(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const userConnect = { connect: { id: ctx.session.user.id } };
      let { sale_items, sale_payments, ...partialSale } = input;

      const openedRegister = await ctx.prisma.register.findFirst({
        where: {
          closed_at: null,
        },
      });

      if (openedRegister === null) {
        throw new TRPCError({
          code: "BAD_REQUEST",
          message: "Nenhum caixa aberto!",
        });
      }

      const registerConnect = { connect: { id: openedRegister.id } };

      sale_payments = sale_payments
        .filter((payment) => payment.value > 0)
        .map((payment) => {
          const { payment_method_id, ...paymentWithoutPaymentMethodId } =
            payment;
          return {
            ...paymentWithoutPaymentMethodId,
            payment_method: { connect: { id: payment_method_id } },
            user: userConnect,
          };
        });

      sale_items = sale_items.map((item) => {
        const { product_id, ...itemWithoutProductId } = item;
        return {
          ...itemWithoutProductId,
          product: { connect: { id: product_id } },
          user: userConnect,
        };
      });

      let sale = {
        ...partialSale,
        user: userConnect,
        register: registerConnect,
        sale_payments: {
          create: sale_payments,
        },
        sale_items: {
          create: sale_items,
        },
      };

      const createdSale = await ctx.prisma.sale.create({
        data: sale,
      });

      return createdSale;
    }),
  getSales: protectedProcedure.query(async ({ ctx }) => {
    const sales = await ctx.prisma.sale.findMany({
      include: {
        sale_items: {
          include: {
            product: true,
          },
        },
        sale_payments: true,
      },
      where: {
        register: {
          closed_at: null,
        },
      },
    });
    return {
      sales,
    };
  }),
  cancelSale: protectedProcedure
    .input(
      z.object({
        sale_id: z.number(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const cancelledSale = await ctx.prisma.sale.update({
        data: {
          cancelled: true,
        },
        where: {
          id: input.sale_id,
        },
      });
      return cancelledSale;
    }),
});
