import { router, publicProcedure } from '@/src/trpc/trpc-index'
import { db } from '@/src/db/db_index'
import { productInfo, units, productSlots, deliverySlotInfo, storeInfo } from '@/src/db/schema'
import { eq, gt, and, sql, inArray } from 'drizzle-orm';
import { generateSignedUrlsFromS3Urls, generateSignedUrlFromS3Url } from '@/src/lib/s3-client'
import { getAllProducts as getAllProductsFromCache } from '@/src/stores/product-store'
import { getDashboardTags as getDashboardTagsFromCache } from '@/src/stores/product-tag-store'

export const getNextDeliveryDate = async (productId: number): Promise<Date | null> => {
  const result = await db
    .select({ deliveryTime: deliverySlotInfo.deliveryTime })
    .from(productSlots)
    .innerJoin(deliverySlotInfo, eq(productSlots.slotId, deliverySlotInfo.id))
    .where(
      and(
        eq(productSlots.productId, productId),
        eq(deliverySlotInfo.isActive, true),
        eq(deliverySlotInfo.isCapacityFull, false),
        gt(deliverySlotInfo.deliveryTime, sql`NOW()`)
      )
    )
    .orderBy(deliverySlotInfo.deliveryTime)
    .limit(1);


  return result[0]?.deliveryTime || null;
};

export async function scaffoldProducts() {
  // Get all products from cache
  let products = await getAllProductsFromCache();
  products = products.filter(item => Boolean(item.id))

  // Get suspended product IDs to filter them out
  const suspendedProducts = await db
    .select({ id: productInfo.id })
    .from(productInfo)
    .where(eq(productInfo.isSuspended, true));

  const suspendedProductIds = new Set(suspendedProducts.map(sp => sp.id));

  // Filter out suspended products
  products = products.filter(product => !suspendedProductIds.has(product.id));

  // Format products to match the expected response structure
  const formattedProducts = await Promise.all(
    products.map(async (product) => {
      const nextDeliveryDate = await getNextDeliveryDate(product.id);
      return {
        id: product.id,
        name: product.name,
        shortDescription: product.shortDescription,
        price: parseFloat(product.price),
        marketPrice: product.marketPrice ? parseFloat(product.marketPrice) : null,
        unit: product.unitNotation,
        unitNotation: product.unitNotation,
        incrementStep: product.incrementStep,
        productQuantity: product.productQuantity,
        storeId: product.store?.id || null,
        isOutOfStock: product.isOutOfStock,
        isFlashAvailable: product.isFlashAvailable,
        nextDeliveryDate: nextDeliveryDate ? nextDeliveryDate.toISOString() : null,
        images: product.images,
        flashPrice: product.flashPrice
      };
    })
  );

  return {
    products: formattedProducts,
    count: formattedProducts.length,
  };
}

export const commonRouter = router({
  getDashboardTags: publicProcedure
    .query(async () => {
      // Get dashboard tags from cache
      const tags = await getDashboardTagsFromCache();

      return {
        tags: tags,
      };
    }),

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

  getStoresSummary: publicProcedure
    .query(async () => {
      const stores = await db.query.storeInfo.findMany({
        columns: {
          id: true,
          name: true,
          description: true,
        },
      });

      return {
        stores,
      };
    }),

  healthCheck: publicProcedure
    .query(async () => {
      // Test DB connection by selecting product names
      await db.select({ name: productInfo.name }).from(productInfo).limit(1);

      return {
        status: "ok",
      };
    }),
});
