// import redisClient from '@/src/lib/redis-client'
import {
  getAllProductsForCache,
  getAllStoresForCache,
  getAllDeliverySlotsForCache,
  getAllSpecialDealsForCache,
  getAllProductTagsForCache,
  getProductById as getProductByIdFromDb,
  type ProductBasicData,
  type StoreBasicData,
  type DeliverySlotData,
  type SpecialDealData,
  type ProductTagData,
} from '@/src/dbService'
import { scaffoldAssetUrl } from '@/src/lib/s3-client'

// Uniform Product Type (matches getProductDetails return)
interface Product {
  id: number
  name: string
  shortDescription: string | null
  longDescription: string | null
  price: string
  marketPrice: string | null
  unitNotation: string
  images: string[]
  isOutOfStock: boolean
  store: { id: number; name: string; description: string | null } | null
  incrementStep: number
  productQuantity: number
  isFlashAvailable: boolean
  flashPrice: string | null
  deliverySlots: Array<{ id: number; deliveryTime: Date; freezeTime: Date; isCapacityFull: boolean }>
  specialDeals: Array<{ quantity: string; price: string; validTill: Date }>
  productTags: string[]
}

export async function initializeProducts(): Promise<void> {
  try {
    console.log('Initializing product store in Redis...')

    // Fetch all products with full details (similar to productMega logic)
    const productsData = await getAllProductsForCache()

    /*
    // Old implementation - direct DB queries:
    import { db } from '@/src/db/db_index'
    import { productInfo, units } from '@/src/db/schema'

    const productsData = await 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));
    */

    // Fetch all stores
    const allStores = await getAllStoresForCache()
    const storeMap = new Map(allStores.map((s) => [s.id, s]))

    // Fetch all delivery slots (excluding full capacity slots)
    const allDeliverySlots = await getAllDeliverySlotsForCache()
    const deliverySlotsMap = new Map<number, DeliverySlotData[]>()
    for (const slot of allDeliverySlots) {
      if (!deliverySlotsMap.has(slot.productId))
        deliverySlotsMap.set(slot.productId, [])
      deliverySlotsMap.get(slot.productId)!.push(slot)
    }

    // Fetch all special deals
    const allSpecialDeals = await getAllSpecialDealsForCache()
    const specialDealsMap = new Map<number, SpecialDealData[]>()
    for (const deal of allSpecialDeals) {
      if (!specialDealsMap.has(deal.productId))
        specialDealsMap.set(deal.productId, [])
      specialDealsMap.get(deal.productId)!.push(deal)
    }

    // Fetch all product tags
    const allProductTags = await getAllProductTagsForCache()
    const productTagsMap = new Map<number, string[]>()
    for (const tag of allProductTags) {
      if (!productTagsMap.has(tag.productId))
        productTagsMap.set(tag.productId, [])
      productTagsMap.get(tag.productId)!.push(tag.tagName)
    }

    // Store each product in Redis
    // for (const product of productsData) {
    //   const signedImages = scaffoldAssetUrl(
    //     (product.images as string[]) || []
    //   )
    //   const store = product.storeId
    //     ? storeMap.get(product.storeId) || null
    //     : null
    //   const deliverySlots = deliverySlotsMap.get(product.id) || []
    //   const specialDeals = specialDealsMap.get(product.id) || []
    //   const productTags = productTagsMap.get(product.id) || []
    //
    //   const productObj: Product = {
    //     id: product.id,
    //     name: product.name,
    //     shortDescription: product.shortDescription,
    //     longDescription: product.longDescription,
    //     price: product.price.toString(),
    //     marketPrice: product.marketPrice?.toString() || null,
    //     unitNotation: product.unitShortNotation,
    //     images: signedImages,
    //     isOutOfStock: product.isOutOfStock,
    //     store: store
    //       ? { id: store.id, name: store.name, description: store.description }
    //       : null,
    //     incrementStep: product.incrementStep,
    //     productQuantity: product.productQuantity,
    //     isFlashAvailable: product.isFlashAvailable,
    //     flashPrice: product.flashPrice?.toString() || null,
    //     deliverySlots: deliverySlots.map((s) => ({
    //       id: s.id,
    //       deliveryTime: s.deliveryTime,
    //       freezeTime: s.freezeTime,
    //       isCapacityFull: s.isCapacityFull,
    //     })),
    //     specialDeals: specialDeals.map((d) => ({
    //       quantity: d.quantity.toString(),
    //       price: d.price.toString(),
    //       validTill: d.validTill,
    //     })),
    //     productTags: productTags,
    //   }
    //
    //   await redisClient.set(`product:${product.id}`, JSON.stringify(productObj))
    // }

    console.log('Product store initialized successfully')
  } catch (error) {
    console.error('Error initializing product store:', error)
  }
}

export async function getProductById(id: number): Promise<Product | null> {
  try {
    // const key = `product:${id}`
    // const data = await redisClient.get(key)
    // if (!data) return null
    // return JSON.parse(data) as Product

    const product = await getProductByIdFromDb(id)
    if (!product) return null

    const signedImages = scaffoldAssetUrl(
      (product.images as string[]) || []
    )

    // Fetch store info
    const allStores = await getAllStoresForCache()
    const store = product.storeId
      ? allStores.find(s => s.id === product.storeId) || null
      : null

    // Fetch delivery slots for this product
    const allDeliverySlots = await getAllDeliverySlotsForCache()
    const productSlots = allDeliverySlots.filter(s => s.productId === id)

    // Fetch special deals for this product
    const allSpecialDeals = await getAllSpecialDealsForCache()
    const productDeals = allSpecialDeals.filter(d => d.productId === id)

    // Fetch product tags for this product
    const allProductTags = await getAllProductTagsForCache()
    const productTagNames = allProductTags
      .filter(t => t.productId === id)
      .map(t => t.tagName)

    return {
      id: product.id,
      name: product.name,
      shortDescription: product.shortDescription,
      longDescription: product.longDescription,
      price: product.price.toString(),
      marketPrice: product.marketPrice?.toString() || null,
      unitNotation: product.unit.shortNotation,
      images: signedImages,
      isOutOfStock: product.isOutOfStock,
      store: store
        ? { id: store.id, name: store.name, description: store.description }
        : null,
      incrementStep: product.incrementStep,
      productQuantity: product.productQuantity,
      isFlashAvailable: product.isFlashAvailable,
      flashPrice: product.flashPrice?.toString() || null,
      deliverySlots: productSlots.map((s) => ({
        id: s.id,
        deliveryTime: s.deliveryTime,
        freezeTime: s.freezeTime,
        isCapacityFull: s.isCapacityFull,
      })),
      specialDeals: productDeals.map((d) => ({
        quantity: d.quantity.toString(),
        price: d.price.toString(),
        validTill: d.validTill,
      })),
      productTags: productTagNames,
    }
  } catch (error) {
    console.error(`Error getting product ${id}:`, error)
    return null
  }
}

export async function getAllProducts(): Promise<Product[]> {
  try {
    // Get all keys matching the pattern "product:*"
    // const keys = await redisClient.KEYS('product:*')
    //
    // if (keys.length === 0) {
    //   return []
    // }
    //
    // // Get all products using MGET for better performance
    // const productsData = await redisClient.MGET(keys)
    //
    // const products: Product[] = []
    // for (const productData of productsData) {
    //   if (productData) {
    //     products.push(JSON.parse(productData) as Product)
    //   }
    // }
    //
    // return products

    const productsData = await getAllProductsForCache()

    const allStores = await getAllStoresForCache()
    const storeMap = new Map(allStores.map((s) => [s.id, s]))

    const allDeliverySlots = await getAllDeliverySlotsForCache()
    const deliverySlotsMap = new Map<number, DeliverySlotData[]>()
    for (const slot of allDeliverySlots) {
      if (!deliverySlotsMap.has(slot.productId))
        deliverySlotsMap.set(slot.productId, [])
      deliverySlotsMap.get(slot.productId)!.push(slot)
    }

    const allSpecialDeals = await getAllSpecialDealsForCache()
    const specialDealsMap = new Map<number, SpecialDealData[]>()
    for (const deal of allSpecialDeals) {
      if (!specialDealsMap.has(deal.productId))
        specialDealsMap.set(deal.productId, [])
      specialDealsMap.get(deal.productId)!.push(deal)
    }

    const allProductTags = await getAllProductTagsForCache()
    const productTagsMap = new Map<number, string[]>()
    for (const tag of allProductTags) {
      if (!productTagsMap.has(tag.productId))
        productTagsMap.set(tag.productId, [])
      productTagsMap.get(tag.productId)!.push(tag.tagName)
    }

    const products: Product[] = []
    for (const product of productsData) {
      const signedImages = scaffoldAssetUrl(
        (product.images as string[]) || []
      )
      const store = product.storeId
        ? storeMap.get(product.storeId) || null
        : null
      const deliverySlots = deliverySlotsMap.get(product.id) || []
      const specialDeals = specialDealsMap.get(product.id) || []
      const productTags = productTagsMap.get(product.id) || []

      products.push({
        id: product.id,
        name: product.name,
        shortDescription: product.shortDescription,
        longDescription: product.longDescription,
        price: product.price.toString(),
        marketPrice: product.marketPrice?.toString() || null,
        unitNotation: product.unitShortNotation,
        images: signedImages,
        isOutOfStock: product.isOutOfStock,
        store: store
          ? { id: store.id, name: store.name, description: store.description }
          : null,
        incrementStep: product.incrementStep,
        productQuantity: product.productQuantity,
        isFlashAvailable: product.isFlashAvailable,
        flashPrice: product.flashPrice?.toString() || null,
        deliverySlots: deliverySlots.map((s) => ({
          id: s.id,
          deliveryTime: s.deliveryTime,
          freezeTime: s.freezeTime,
          isCapacityFull: s.isCapacityFull,
        })),
        specialDeals: specialDeals.map((d) => ({
          quantity: d.quantity.toString(),
          price: d.price.toString(),
          validTill: d.validTill,
        })),
        productTags: productTags,
      })
    }

    return products
  } catch (error) {
    console.error('Error getting all products:', error)
    return []
  }
}
