import { router, publicProcedure } from '@/src/trpc/trpc-index'
import { z } from 'zod'
import { scaffoldAssetUrl } from '@/src/lib/s3-client'
import { ApiError } from '@/src/lib/api-error'
import { getTagsByStoreId } from '@/src/stores/product-tag-store'
import {
  getUserStoreSummaries as getUserStoreSummariesInDb,
  getUserStoreDetail as getUserStoreDetailInDb,
} from '@/src/dbService'
import type {
  UserStoresResponse,
  UserStoreDetail,
  UserStoreSummary,
} from '@packages/shared'

export async function scaffoldStores(): Promise<UserStoresResponse> {
  const storesData = await getUserStoreSummariesInDb()

  /*
  // Old implementation - direct DB queries:
  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);
  */

  const storesWithDetails: UserStoreSummary[] = storesData.map((store) => {
    const signedImageUrl = store.imageUrl ? scaffoldAssetUrl(store.imageUrl) : null
    const sampleProducts = store.sampleProducts.map((product) => ({
      id: product.id,
      name: product.name,
      signedImageUrl: product.images && product.images.length > 0
        ? scaffoldAssetUrl(product.images[0])
        : null,
    }))

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

  return {
    stores: storesWithDetails,
  }
}

export async function scaffoldStoreWithProducts(storeId: number): Promise<UserStoreDetail> {
  const storeDetail = await getUserStoreDetailInDb(storeId)

  /*
  // Old implementation - direct DB queries:
  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);
  }

  const signedImageUrl = storeData.imageUrl ?  scaffoldAssetUrl(storeData.imageUrl) : null;

  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)));

  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,
    })),
  };
  */

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

  const signedImageUrl = storeDetail.store.imageUrl
    ? scaffoldAssetUrl(storeDetail.store.imageUrl)
    : null

  const productsWithSignedUrls = storeDetail.products.map((product) => ({
    id: product.id,
    name: product.name,
    shortDescription: product.shortDescription,
    price: product.price,
    marketPrice: product.marketPrice,
    incrementStep: product.incrementStep,
    unit: product.unit,
    unitNotation: product.unitNotation,
    images: scaffoldAssetUrl(product.images || []),
    isOutOfStock: product.isOutOfStock,
    productQuantity: product.productQuantity,
  }))

  const tags = await getTagsByStoreId(storeId)

  return {
    store: {
      id: storeDetail.store.id,
      name: storeDetail.store.name,
      description: storeDetail.store.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 (): Promise<UserStoresResponse> => {
      const response = await scaffoldStores();
      return response;
    }),

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