import { router, publicProcedure } from "../trpc-index";
import { z } from "zod";
import { db } from "../../db/db_index";
import {
  deliverySlotInfo,
  productSlots,
  productInfo,
  units,
} from "../../db/schema";
import { eq, and, gt, asc } from "drizzle-orm";
import { generateSignedUrlsFromS3Urls } from "../../lib/s3-client";
import { getAllSlots as getAllSlotsFromCache, getSlotById as getSlotByIdFromCache } from "../../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 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 allSlots = await getAllSlotsFromCache();
    const currentTime = new Date();
    const validSlots = allSlots.filter((slot) =>
      dayjs(slot.freezeTime).isAfter(currentTime)
    );

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

  nextMajorDelivery: publicProcedure.query(async () => {
    const now = new Date();

    // Find the next upcoming active delivery slot ID
    const nextSlot = await db.query.deliverySlotInfo.findFirst({
      where: and(
        eq(deliverySlotInfo.isActive, true),
        gt(deliverySlotInfo.deliveryTime, now),
      ),
      orderBy: asc(deliverySlotInfo.deliveryTime),
    });

    if (!nextSlot) {
      return null; // No upcoming delivery slots
    }

    // Get formatted data using helper method
    return await getSlotData(nextSlot.id);
  }),

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