import { NextRequest, NextResponse } from "next/server";
import { authOptions } from "@/app/api/auth/[...nextauth]/auth-options";
import { getServerSession } from "next-auth";
import db from "@/lib/db";
import { DiscountType, UserRole } from "@prisma/client";
import { getLogger } from "@/utils/logger";

const logger = getLogger("/api/admin/coupons")


export async function GET(req: NextRequest) {
    try {

        const { searchParams } = new URL(req.url)

        const limit = parseInt(searchParams.get("limit") || "10")
        const page = parseInt(searchParams.get("page") || "1")

        const session = await getServerSession(authOptions);

        if (!session || session.user.role !== UserRole.ADMIN) {
            logger.warn("Forbidden", { userRole: session?.user.role });
            return new NextResponse("Forbidden", { status: 403 });
        }

        const coupons = await db.coupon.findMany({
            skip: (page - 1) * limit,
            take: limit,
            orderBy: {
                createdAt: 'desc'
            }
        })

        const totalCoupons = await db.coupon.count();

        return NextResponse.json({ coupons, totalCoupons }, { status: 200 })

    }
    catch (error: any) {
        logger.error("Failed to fetch coupons", { errorMsg: error?.message, errorData: error?.config?.data });
        return new NextResponse("Internal Server Error", { status: 500 })
    }
}

export async function POST(req: NextRequest) {
    try {
        const body = await req.formData();
        const session = await getServerSession(authOptions);

        if (!session || session.user.role !== UserRole.ADMIN) {
            logger.warn("Forbidden", { userRole: session?.user.role });
            return new NextResponse("Forbidden", { status: 403 });
        }

        const code = body.get("code");
        const type = body.get("type");
        const value = body.get("value");
        const maxDiscount = body.get("maxDiscount");
        const minPurchaseAmount = body.get("minPurchaseAmount");
        const startDate = body.get("startDate");
        const endDate = body.get("endDate");
        const usageLimit = body.get("usageLimit");
        const usageCount = body.get("usageCount");
        const perUserLimit = body.get("perUserLimit");
        const isActive = body.get("isActive");

        const safeParse = (field: FormDataEntryValue | null) => {
            try {
                return field ? JSON.parse(field.toString()) : [];
            } catch {
                return [];
            }
        };

        const selectedProducts = safeParse(body.get("selectedProducts"));
        const selectedVariants = safeParse(body.get("selectedVariants"));
        const selectedCategories = safeParse(body.get("selectedCategories"));
        const selectedCollections = safeParse(body.get("selectedCollections"));


        let discountType;
        if (type === "Percentage") discountType = DiscountType.PERCENTAGE;
        else if (type === "Fixed") discountType = DiscountType.FIXED_AMOUNT;
        else if (type === "FreeShipping") discountType = DiscountType.FREE_SHIPPING;
        else return new NextResponse("Invalid discount type", { status: 400 });

        const couponExists = await db.coupon.findUnique({
            where: {
                code: code?.toString() || "",
            }
        })

        if (couponExists) {
            return NextResponse.json({message: "A coupon already exists with this code!"}, { status: 400 });
        }

        const coupon = await db.coupon.create({
            data: {
                code: code?.toString() || "",
                type: discountType,
                value: value ? parseFloat(value.toString()) : 0,
                maxDiscount: maxDiscount ? parseFloat(maxDiscount.toString()) : null,
                minPurchaseAmount: minPurchaseAmount ? parseFloat(minPurchaseAmount.toString()) : null,
                startDate: startDate ? new Date(startDate.toString()) : null,
                endDate: endDate ? new Date(endDate.toString()) : null,
                usageLimit: usageLimit ? parseInt(usageLimit.toString()) : null,
                usageCount: usageCount ? parseInt(usageCount.toString()) : 0,
                perUserLimit: perUserLimit ? parseInt(perUserLimit.toString()) : null,
                isActive: isActive === "true",

                products:
                    selectedProducts.length > 0
                        ? { connect: selectedProducts.map((id: string | number) => ({ id: parseInt(id as string, 10) })) }
                        : undefined,

                variants:
                    selectedVariants.length > 0
                        ? { connect: selectedVariants.map((id: string | number) => ({ id: parseInt(id as string, 10) })) }
                        : undefined,

                categories:
                    selectedCategories.length > 0
                        ? { connect: selectedCategories.map((id: string | number) => ({ id: parseInt(id as string, 10) })) }
                        : undefined,

                collections:
                    selectedCollections.length > 0
                        ? { connect: selectedCollections.map((id: string | number) => ({ id: parseInt(id as string, 10) })) }
                        : undefined,
            },
        });

        // console.log(coupon)

        return NextResponse.json({ coupon }, { status: 200 });
    } catch (error: any) {
        logger.error("Failed to create coupon", {
            errorMsg: error?.message,
            errorData: error?.config?.data,
        });
        return new NextResponse("Internal Server Error", { status: 500 });
    }
}