// import redisClient from '@/src/lib/redis-client'
import {
  getAllTagsForCache,
  getAllTagProductMappings,
  getAllProductTags,
  getProductTagById as getProductTagByIdFromDb,
  type TagBasicData,
  type TagProductMapping,
} from '@/src/dbService'
import { scaffoldAssetUrl } from '@/src/lib/s3-client'

// Tag Type (matches getDashboardTags return)
interface Tag {
  id: number
  tagName: string
  tagDescription: string | null
  imageUrl: string | null
  isDashboardTag: boolean
  relatedStores: number[]
  productIds: number[]
}

async function transformTagToStoreTag(tag: {
  id: number
  tagName: string
  tagDescription: string | null
  imageUrl: string | null
  isDashboardTag: boolean
  relatedStores: unknown
  products?: Array<{ productId: number }>
}): Promise<Tag> {
  const signedImageUrl = tag.imageUrl
    ? scaffoldAssetUrl(tag.imageUrl)
    : null

  return {
    id: tag.id,
    tagName: tag.tagName,
    tagDescription: tag.tagDescription,
    imageUrl: signedImageUrl,
    isDashboardTag: tag.isDashboardTag,
    relatedStores: (tag.relatedStores as number[]) || [],
    productIds: tag.products ? tag.products.map(p => p.productId) : [],
  }
}

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

    // Fetch all tags
    const tagsData = await getAllTagsForCache()

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

    const tagsData = await db
      .select({
        id: productTagInfo.id,
        tagName: productTagInfo.tagName,
        tagDescription: productTagInfo.tagDescription,
        imageUrl: productTagInfo.imageUrl,
        isDashboardTag: productTagInfo.isDashboardTag,
        relatedStores: productTagInfo.relatedStores,
      })
      .from(productTagInfo);
    */

    // Fetch product IDs for each tag
    const productTagsData = await getAllTagProductMappings()

    /*
    // Old implementation - direct DB queries:
    import { productTags } from '@/src/db/schema'
    import { inArray } from 'drizzle-orm'

    const tagIds = tagsData.map(t => t.id);
    const productTagsData = await db
      .select({
        tagId: productTags.tagId,
        productId: productTags.productId,
      })
      .from(productTags)
      .where(inArray(productTags.tagId, tagIds));
    */

    // Group product IDs by tag
    const productIdsByTag = new Map<number, number[]>()
    for (const pt of productTagsData) {
      if (!productIdsByTag.has(pt.tagId)) {
        productIdsByTag.set(pt.tagId, [])
      }
      productIdsByTag.get(pt.tagId)!.push(pt.productId)
    }

    // Store each tag in Redis
    // for (const tag of tagsData) {
    //   const signedImageUrl = tag.imageUrl
    //     ? await generateSignedUrlFromS3Url(tag.imageUrl)
    //     : null
    //
    //   const tagObj: Tag = {
    //     id: tag.id,
    //     tagName: tag.tagName,
    //     tagDescription: tag.tagDescription,
    //     imageUrl: signedImageUrl,
    //     isDashboardTag: tag.isDashboardTag,
    //     relatedStores: (tag.relatedStores as number[]) || [],
    //     productIds: productIdsByTag.get(tag.id) || [],
    //   }
    //
    //   await redisClient.set(`tag:${tag.id}`, JSON.stringify(tagObj))
    // }

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

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

    const tag = await getProductTagByIdFromDb(id)
    if (!tag) return null

    return transformTagToStoreTag(tag)
  } catch (error) {
    console.error(`Error getting tag ${id}:`, error)
    return null
  }
}

export async function getAllTags(): Promise<Tag[]> {
  try {
    // Get all keys matching the pattern "tag:*"
    // const keys = await redisClient.KEYS('tag:*')
    //
    // if (keys.length === 0) {
    //   return []
    // }
    //
    // // Get all tags using MGET for better performance
    // const tagsData = await redisClient.MGET(keys)
    //
    // const tags: Tag[] = []
    // for (const tagData of tagsData) {
    //   if (tagData) {
    //     tags.push(JSON.parse(tagData) as Tag)
    //   }
    // }
    //
    // return tags

    const tags = await getAllProductTags()

    const result: Tag[] = []
    for (const tag of tags) {
      result.push(await transformTagToStoreTag(tag))
    }
    return result
  } catch (error) {
    console.error('Error getting all tags:', error)
    return []
  }
}

export async function getDashboardTags(): Promise<Tag[]> {
  try {
    // Get all keys matching the pattern "tag:*"
    // const keys = await redisClient.KEYS('tag:*')
    //
    // if (keys.length === 0) {
    //   return []
    // }
    //
    // // Get all tags using MGET for better performance
    // const tagsData = await redisClient.MGET(keys)
    //
    // const dashboardTags: Tag[] = []
    // for (const tagData of tagsData) {
    //   if (tagData) {
    //     const tag = JSON.parse(tagData) as Tag
    //     if (tag.isDashboardTag) {
    //       dashboardTags.push(tag)
    //     }
    //   }
    // }
    //
    // return dashboardTags

    const tags = await getAllProductTags()

    const result: Tag[] = []
    for (const tag of tags) {
      if (tag.isDashboardTag) {
        result.push(await transformTagToStoreTag(tag))
      }
    }
    return result
  } catch (error) {
    console.error('Error getting dashboard tags:', error)
    return []
  }
}

export async function getTagsByStoreId(storeId: number): Promise<Tag[]> {
  try {
    // Get all keys matching the pattern "tag:*"
    // const keys = await redisClient.KEYS('tag:*')
    //
    // if (keys.length === 0) {
    //   return []
    // }
    //
    // // Get all tags using MGET for better performance
    // const tagsData = await redisClient.MGET(keys)
    //
    // const storeTags: Tag[] = []
    // for (const tagData of tagsData) {
    //   if (tagData) {
    //     const tag = JSON.parse(tagData) as Tag
    //     if (tag.relatedStores.includes(storeId)) {
    //       storeTags.push(tag)
    //     }
    //   }
    // }
    //
    // return storeTags

    const tags = await getAllProductTags()

    const result: Tag[] = []
    for (const tag of tags) {
      const relatedStores = (tag.relatedStores as number[]) || []
      if (relatedStores.includes(storeId)) {
        result.push(await transformTagToStoreTag(tag))
      }
    }
    return result
  } catch (error) {
    console.error(`Error getting tags for store ${storeId}:`, error)
    return []
  }
}
