import { router, publicProcedure } from "@/src/trpc/trpc-index";
import { z } from "zod";
import { db } from "@/src/db/db_index";
import {
  deliverySlotInfo,
  productSlots,
  productInfo,
  units,
} from "@/src/db/schema";
import { eq, and } from "drizzle-orm";
import { getAllSlots as getAllSlotsFromCache, getSlotById as getSlotByIdFromCache } from "@/src/stores/slot-store";
import dayjs from 'dayjs';

// Helper method to get formatted slot data by ID
async function getSlotData(slotId: number) {
  const slot = await getSlotByIdFromCache(slotId);

  if (!slot) {
    return null;
  }

  const currentTime = new Date();
  if (dayjs(slot.freezeTime).isBefore(currentTime)) {
    return null;
  }

  return {
    deliveryTime: slot.deliveryTime,
    freezeTime: slot.freezeTime,
    slotId: slot.id,
    products: slot.products.filter((product) => !product.isOutOfStock),
  };
}

export async function scaffoldSlotsWithProducts() {
  const allSlots = await getAllSlotsFromCache();
  const currentTime = new Date();
  const validSlots = allSlots
    .filter((slot) => {
      return dayjs(slot.freezeTime).isAfter(currentTime) &&
             dayjs(slot.deliveryTime).isAfter(currentTime) &&
             !slot.isCapacityFull;
    })
    .sort((a, b) => dayjs(a.deliveryTime).valueOf() - dayjs(b.deliveryTime).valueOf());

  // Fetch all products for availability info
  const allProducts = await db
    .select({
      id: productInfo.id,
      name: productInfo.name,
      isOutOfStock: productInfo.isOutOfStock,
      isFlashAvailable: productInfo.isFlashAvailable,
    })
    .from(productInfo)
    .where(eq(productInfo.isSuspended, false));

  const productAvailability = allProducts.map(product => ({
    id: product.id,
    name: product.name,
    isOutOfStock: product.isOutOfStock,
    isFlashAvailable: product.isFlashAvailable,
  }));

  return {
    slots: validSlots,
    productAvailability,
    count: validSlots.length,
  };
}

export const slotsRouter = router({
  getSlots: publicProcedure.query(async () => {
    const slots = await db.query.deliverySlotInfo.findMany({
      where: eq(deliverySlotInfo.isActive, true),
    });
    return {
      slots,
      count: slots.length,
    };
  }),

  getSlotsWithProducts: publicProcedure.query(async () => {
    const response = await scaffoldSlotsWithProducts();
    return response;
  }),

  getSlotById: publicProcedure
    .input(z.object({ slotId: z.number() }))
    .query(async ({ input }) => {
      return await getSlotData(input.slotId);
    }),
});
