import { z } from "zod";
import { createRouter, publicQuery } from "../middleware";
import { getDb } from "../queries/connection";
import { products, productReviews, productFaqs } from "@db/schema";
import { eq, like, desc, asc, sql, and } from "drizzle-orm";

export const productRouter = createRouter({
  list: publicQuery
    .input(
      z.object({
        category: z.string().optional(),
        search: z.string().optional(),
        sort: z.enum(["price-asc", "price-desc", "popular", "newest"]).optional(),
        limit: z.number().default(50),
        offset: z.number().default(0),
      }).optional()
    )
    .query(async ({ input }) => {
      const db = getDb();
      const category = input?.category;
      const search = input?.search;
      const sort = input?.sort;
      const limit = input?.limit ?? 50;
      const offset = input?.offset ?? 0;

      let conditions = [];
      if (category) {
        conditions.push(eq(products.category, category));
      }
      if (search) {
        conditions.push(like(products.name, `%${search}%`));
      }

      const orderBy = sort === "price-asc" ? asc(products.price)
        : sort === "price-desc" ? desc(products.price)
        : sort === "popular" ? desc(products.soldCount)
        : desc(products.createdAt);

      if (category && search) {
        return db.select().from(products).where(and(eq(products.category, category), like(products.name, `%${search}%`))).orderBy(orderBy).limit(limit).offset(offset);
      }
      if (category) {
        return db.select().from(products).where(eq(products.category, category)).orderBy(orderBy).limit(limit).offset(offset);
      }
      if (search) {
        return db.select().from(products).where(like(products.name, `%${search}%`)).orderBy(orderBy).limit(limit).offset(offset);
      }
      return db.select().from(products).orderBy(orderBy).limit(limit).offset(offset);
    }),

  getBySlug: publicQuery
    .input(z.object({ slug: z.string() }))
    .query(async ({ input }) => {
      const db = getDb();
      const [product] = await db.select().from(products).where(eq(products.slug, input.slug)).limit(1);
      if (!product) return null;

      const reviews = await db.select().from(productReviews).where(eq(productReviews.productId, product.id));
      const faqs = await db.select().from(productFaqs).where(eq(productFaqs.productId, product.id));

      const relatedProducts = await db
        .select()
        .from(products)
        .where(eq(products.category, product.category))
        .limit(5);

      return { ...product, reviews, faqs, relatedProducts: relatedProducts.filter(r => r.id !== product.id) };
    }),

  getCategories: publicQuery.query(async () => {
    const db = getDb();
    const result = await db
      .select({
        category: products.category,
        count: sql<number>`count(*)`,
      })
      .from(products)
      .groupBy(products.category);
    return result;
  }),

  getFeatured: publicQuery.query(async () => {
    const db = getDb();
    return db
      .select()
      .from(products)
      .where(sql`badge IN ('Best Seller', 'Premium', 'Trending', 'Popular')`)
      .limit(8);
  }),

  getTrending: publicQuery.query(async () => {
    const db = getDb();
    return db
      .select()
      .from(products)
      .orderBy(desc(products.soldCount))
      .limit(6);
  }),

  trackView: publicQuery
    .input(z.object({ productId: z.number() }))
    .mutation(async ({ input }) => {
      const db = getDb();
      await db
        .update(products)
        .set({ viewCount: sql`${products.viewCount} + 1` })
        .where(eq(products.id, input.productId));
      return { success: true };
    }),
});
