import { router, publicProcedure } from '@/src/trpc/trpc-index';
import { z } from 'zod';
import { db } from '@/src/db/db_index';
import { storeInfo, productInfo, units } from '@/src/db/schema';
import { eq, and, sql } from 'drizzle-orm';
import { scaffoldAssetUrl } from '@/src/lib/s3-client';
import { ApiError } from '@/src/lib/api-error';
import { getTagsByStoreId } from '@/src/stores/product-tag-store';

export async function scaffoldStores() {
  const storesData = await db
    .select({
      id: storeInfo.id,
      name: storeInfo.name,
      description: storeInfo.description,
      imageUrl: storeInfo.imageUrl,
      productCount: sql<number>`count(${productInfo.id})`.as('productCount'),
    })
    .from(storeInfo)
    .leftJoin(
      productInfo,
      and(eq(productInfo.storeId, storeInfo.id), eq(productInfo.isSuspended, false))
    )
    .groupBy(storeInfo.id);

  // Generate signed URLs for store images and fetch sample products
  const storesWithDetails = await Promise.all(
    storesData.map(async (store) => {
      const signedImageUrl = store.imageUrl ? scaffoldAssetUrl(store.imageUrl) : null;

      // Fetch up to 3 products for this store
      const sampleProducts = await db
        .select({
          id: productInfo.id,
          name: productInfo.name,
          images: productInfo.images,
        })
        .from(productInfo)
        .where(and(eq(productInfo.storeId, store.id), eq(productInfo.isSuspended, false)))
        .limit(3);

      // Generate signed URLs for product images
      const productsWithSignedUrls = await Promise.all(
        sampleProducts.map(async (product) => {
          const images = product.images as string[];
          return {
            id: product.id,
            name: product.name,
            signedImageUrl: (images && images.length > 0) ? scaffoldAssetUrl(images[0]) : null,
          };
        })
      );

      return {
        id: store.id,
        name: store.name,
        description: store.description,
        signedImageUrl,
        productCount: store.productCount,
        sampleProducts: productsWithSignedUrls,
      };
    })
  );

  return {
    stores: storesWithDetails,
  };
}

export async function scaffoldStoreWithProducts(storeId: number) {
  // Fetch store info
  const storeData = await db.query.storeInfo.findFirst({
    where: eq(storeInfo.id, storeId),
    columns: {
      id: true,
      name: true,
      description: true,
      imageUrl: true,
    },
  });

  if (!storeData) {
    throw new ApiError('Store not found', 404);
  }

  // Generate signed URL for store image
  const signedImageUrl = storeData.imageUrl ?  scaffoldAssetUrl(storeData.imageUrl) : null;

  // Fetch products for this store
  const productsData = await db
    .select({
      id: productInfo.id,
      name: productInfo.name,
      shortDescription: productInfo.shortDescription,
      price: productInfo.price,
      marketPrice: productInfo.marketPrice,
      images: productInfo.images,
      isOutOfStock: productInfo.isOutOfStock,
      incrementStep: productInfo.incrementStep,
      unitShortNotation: units.shortNotation,
      unitNotation: units.shortNotation,
      productQuantity: productInfo.productQuantity,
    })
    .from(productInfo)
    .innerJoin(units, eq(productInfo.unitId, units.id))
    .where(and(eq(productInfo.storeId, storeId), eq(productInfo.isSuspended, false)));

    
  // Generate signed URLs for product images
  const productsWithSignedUrls = await Promise.all(
    productsData.map(async (product) => ({
      id: product.id,
      name: product.name,
      shortDescription: product.shortDescription,
      price: product.price,
      marketPrice: product.marketPrice,
      incrementStep: product.incrementStep,
      unit: product.unitShortNotation,
      unitNotation: product.unitNotation,
      images:  scaffoldAssetUrl((product.images as string[]) || []),
      isOutOfStock: product.isOutOfStock,
      productQuantity: product.productQuantity
    }))
  );

  const tags = await getTagsByStoreId(storeId);

  return {
    store: {
      id: storeData.id,
      name: storeData.name,
      description: storeData.description,
      signedImageUrl,
    },
    products: productsWithSignedUrls,
    tags: tags.map(tag => ({
      id: tag.id,
      tagName: tag.tagName,
      tagDescription: tag.tagDescription,
      imageUrl: tag.imageUrl,
      productIds: tag.productIds,
    })),
  };
}

export const storesRouter = router({
  getStores: publicProcedure
    .query(async () => {
      const response = await scaffoldStores();
      return response;
    }),

  getStoreWithProducts: publicProcedure
    .input(z.object({
      storeId: z.number(),
    }))
    .query(async ({ input }) => {
      const { storeId } = input;
      const response = await scaffoldStoreWithProducts(storeId);
      return response;
    }),
});
