import { router, publicProcedure } from "@/src/trpc/trpc-index"
import { z } from "zod"
import { getAllSlots as getAllSlotsFromCache, getSlotById as getSlotByIdFromCache } from "@/src/stores/slot-store"
import dayjs from 'dayjs'
import { getUserActiveSlotsList as getUserActiveSlotsListInDb, getUserProductAvailability as getUserProductAvailabilityInDb } from '@/src/dbService'
import type { UserSlotData, UserSlotsListResponse, UserSlotsWithProductsResponse } from '@packages/shared'

// 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(): Promise<UserSlotsWithProductsResponse> {
  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());

  const productAvailability = await getUserProductAvailabilityInDb()

  /*
  // Old implementation - direct DB query:
  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 (): Promise<UserSlotsListResponse> => {
    const slots = await getUserActiveSlotsListInDb()

    /*
    // Old implementation - direct DB query:
    const slots = await db.query.deliverySlotInfo.findMany({
      where: eq(deliverySlotInfo.isActive, true),
    });
    */

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

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

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