import { NextRequest, NextResponse } from "next/server";
import db from "@/lib/db";
import { Prisma } from "@prisma/client";
import { getLogger } from "@/utils/logger";

const logger = getLogger("/api/variants/category/[categoryName]");

export const POST = async (req: NextRequest, { params }: { params: { categoryName: string } }) => {
    try {
        const { searchParams } = new URL(req.url);

        const page = parseInt(searchParams.get("page") || "1");
        const limit = parseInt(searchParams.get("limit") || "10");
        const sort = searchParams.get("sort") || "default";

        const { filters } = (await req.json()) as { filters: Record<string, string[]> };

        //console.log(filters);
        const jsonFilters: any[] = [];

        const priceFilters: any[] = [];
        const stockFilters: any[] = [];




        Object.entries(filters).forEach(([key, values]) => {
            const path = key.split("-");

            if (key == "price" || key == 'stock') {
                if (key == "price") {
                    priceFilters.push(...values);

                    //console.log(values)

                }
                if (key == "stock") {
                    stockFilters.push(...values);
                }

            }
            else {
                (values as string[]).forEach((val) => {

                    if (tryParseInt(val) !== null) {
                        jsonFilters.push({
                            specs: {
                                path,
                                equals: val
                            }
                        });
                    }
                    else {
                        jsonFilters.push({
                            specs: {
                                path,
                                string_contains: val
                            }
                        });
                    }
                });

            }
        });


        const orderValue: Prisma.SortOrder = sort === "highToLow" ? Prisma.SortOrder.desc : Prisma.SortOrder.asc;

        const categoryName = params.categoryName;

        const category = await db.categories.findUnique({
            where: { name: categoryName },
            include: { coupons: true }
        });

        if (!category) {
            return NextResponse.json({ error: "Category not found" }, { status: 404 });
        }

        var priceCondition = false;

        if (tryParseInt(priceFilters[0]) !== 0 && tryParseInt(priceFilters[1]) !== 0) {
            priceCondition = true;
        }

        const variants = await db.productVariant.findMany({
            where: {
                AND: [
                    // 1. Category / Sub-category / Sub-sub-category filter
                    {
                        OR: [
                            { product: { category_id: category.id } },
                            { product: { sub_category_id: category.id } },
                            { product: { sub_sub_category_id: category.id } },
                        ],
                    },
                    // 2. Price range filter (only added if active)
                    priceCondition
                        ? {
                            special_price: {
                                gte: tryParseInt(priceFilters[0]) || 0,
                                lte: tryParseInt(priceFilters[1]) || Number.MAX_SAFE_INTEGER,
                            },
                        }
                        : undefined,

                    // 3. JSON filters (optional)
                    jsonFilters.length > 0 ? { OR: jsonFilters } : undefined,
                ].filter(Boolean) as any, // cleans undefined entries
            },
            orderBy: sort !== "default" ? { special_price: orderValue } : undefined,
            skip: (page - 1) * limit,
            take: limit,
            include: {
                variant_images: true,
                coupons: true,
                Review: { select: { rating: true } },
                _count: { select: { Review: true } }
            },

        })


        const variantsWithAverage = variants.map((v) => {
            const ratings = v.Review.map((r) => r.rating);
            const averageRating = ratings.length ? ratings.reduce((a, b) => a + b, 0) / ratings.length : 0;
            return { ...v, averageRating };
        });

        const TotalVariants = await db.productVariant.count({
            where: {
                AND: [
                    {
                        OR: [
                            { product: { category_id: category.id } },
                            { product: { sub_category_id: category.id } },
                            { product: { sub_sub_category_id: category.id } },
                        ],
                    },
                
                    stockFilters.includes("in_stock") ? { stock: { gt: 0 } } : undefined,
                    priceCondition
                        ? {
                            special_price: {
                                gte: tryParseInt(priceFilters[0]) || 0,
                                lte: tryParseInt(priceFilters[1]) || Number.MAX_SAFE_INTEGER,
                            },
                        }
                        : undefined,

                    // 3. JSON filters (optional)
                    jsonFilters.length > 0 ? { OR: jsonFilters } : undefined,
                ].filter(Boolean) as any, // cleans undefined entries
            },
        });



        const minPriceVariant = await db.productVariant.findFirst({
            where: {
                OR: [
                    { product: { category_id: category.id } },
                    { product: { sub_category_id: category.id } },
                    { product: { sub_sub_category_id: category.id } },
                ],
            },
            orderBy: { special_price: "asc" },
            select: { special_price: true }
        });

        const maxPriceVariant = await db.productVariant.findFirst({
            where: {
                OR: [
                    { product: { category_id: category.id } },
                    { product: { sub_category_id: category.id } },
                    { product: { sub_sub_category_id: category.id } },
                ],
            },
            orderBy: { special_price: "desc" },
            select: { special_price: true }
        });


        //console.log(maxPriceVariant?.special_price, minPriceVariant?.special_price)

        return NextResponse.json(
            {
                mssg: variantsWithAverage,
                total: TotalVariants,
                page,
                limit,
                minPrice: minPriceVariant?.special_price || 0,
                maxPrice: maxPriceVariant?.special_price || 0,
                categoryCoupons: category.coupons,
                category
            },
            { status: 200 }
        );
    } catch (error: any) {
        logger.error(`Failed to fetch variants of category ${params.categoryName}`, {
            error: error?.config?.data ?? error?.message ?? "Unknown error"
        });
        return new NextResponse("Internal Server Error", { status: 500 });
    }
};



function tryParseInt(val: string) {
    const num = Number.parseInt(val, 10);
    return Number.isNaN(num) ? null : num;
}