import { db } from '@/src/db/db_index'
import { productInfo, units, productSlots, deliverySlotInfo, specialDeals, storeInfo, productReviews, users } from '@/src/db/schema'
import { eq, and, gt, sql, desc } from 'drizzle-orm'

/**
 * Get product basic info with unit
 */
export async function getProductWithUnit(productId: number) {
  return db
    .select({
      id: productInfo.id,
      name: productInfo.name,
      shortDescription: productInfo.shortDescription,
      longDescription: productInfo.longDescription,
      price: productInfo.price,
      marketPrice: productInfo.marketPrice,
      images: productInfo.images,
      isOutOfStock: productInfo.isOutOfStock,
      storeId: productInfo.storeId,
      unitShortNotation: units.shortNotation,
      incrementStep: productInfo.incrementStep,
      productQuantity: productInfo.productQuantity,
      isFlashAvailable: productInfo.isFlashAvailable,
      flashPrice: productInfo.flashPrice,
    })
    .from(productInfo)
    .innerJoin(units, eq(productInfo.unitId, units.id))
    .where(eq(productInfo.id, productId))
    .limit(1)
}

/**
 * Get store info by ID
 */
export async function getStoreById(storeId: number) {
  return db.query.storeInfo.findFirst({
    where: eq(storeInfo.id, storeId),
    columns: { id: true, name: true, description: true },
  })
}

/**
 * Get delivery slots for product
 */
export async function getProductDeliverySlots(productId: number) {
  return db
    .select({
      id: deliverySlotInfo.id,
      deliveryTime: deliverySlotInfo.deliveryTime,
      freezeTime: deliverySlotInfo.freezeTime,
    })
    .from(productSlots)
    .innerJoin(deliverySlotInfo, eq(productSlots.slotId, deliverySlotInfo.id))
    .where(
      and(
        eq(productSlots.productId, productId),
        eq(deliverySlotInfo.isActive, true),
        gt(deliverySlotInfo.deliveryTime, sql`NOW()`),
        gt(deliverySlotInfo.freezeTime, sql`NOW()`)
      )
    )
    .orderBy(deliverySlotInfo.deliveryTime)
}

/**
 * Get special deals for product
 */
export async function getProductSpecialDeals(productId: number) {
  return db
    .select({
      quantity: specialDeals.quantity,
      price: specialDeals.price,
      validTill: specialDeals.validTill,
    })
    .from(specialDeals)
    .where(
      and(
        eq(specialDeals.productId, productId),
        gt(specialDeals.validTill, sql`NOW()`)
      )
    )
    .orderBy(specialDeals.quantity)
}

/**
 * Get product reviews with user info
 */
export async function getProductReviews(productId: number, limit: number, offset: number) {
  return db
    .select({
      id: productReviews.id,
      reviewBody: productReviews.reviewBody,
      ratings: productReviews.ratings,
      imageUrls: productReviews.imageUrls,
      reviewTime: productReviews.reviewTime,
      userName: users.name,
    })
    .from(productReviews)
    .innerJoin(users, eq(productReviews.userId, users.id))
    .where(eq(productReviews.productId, productId))
    .orderBy(desc(productReviews.reviewTime))
    .limit(limit)
    .offset(offset)
}

/**
 * Count reviews for product
 */
export async function countProductReviews(productId: number) {
  const result = await db
    .select({ count: sql`count(*)` })
    .from(productReviews)
    .where(eq(productReviews.productId, productId))
  
  return Number(result[0].count)
}

/**
 * Check if product exists
 */
export async function checkProductExists(productId: number) {
  return db.query.productInfo.findFirst({
    where: eq(productInfo.id, productId),
  })
}

/**
 * Insert new review
 */
export async function insertReview(data: {
  userId: number
  productId: number
  reviewBody: string
  ratings: number
  imageUrls: string[]
}) {
  return db.insert(productReviews).values(data).returning()
}
