import { authOptions } from "@/app/api/auth/[...nextauth]/auth-options";
import db from "@/lib/db";
import { getLogger } from "@/utils/logger";
import { DiscountType, UserRole } from "@prisma/client";
import { getServerSession } from "next-auth";
import { NextResponse } from "next/server"


const logger = getLogger("api/admin/coupons/[id]/route.ts");

export async function DELETE(request: Request, { params }: { params: { id: string } }) {
    const { id } = params

    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 });
    }


    try {
        const deletedCoupon = await db.coupon.delete({
            where: {
                id: Number(id)
            }
        })

        if (!deletedCoupon) {
            return NextResponse.json({ message: "Coupon not found" }, { status: 404 });
        }

        return NextResponse.json({ message: `Coupon with id ${id} deleted` }, { status: 200 });
    }
    catch (error: any) {

        logger.error("Error deleting coupon:", error?.config ?? error?.message);

        return new NextResponse("Internal Server Error", { status: 500 })
    }

}

export async function GET(request: Request, { params }: { params: { id: string } }) {
    const { id } = params

    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 });
    }


    try {
        const coupon = await db.coupon.findUnique({
            where: {
                id: Number(id)
            },
            include: {
                products: true,
                variants: true,
                categories: true,
                collections: true,
            }
        })

        return NextResponse.json({ coupon }, { status: 200 });
    }

    catch (error: any) {
        logger.error("Error fetching coupon:", error?.config ?? error?.message)

        return new NextResponse("Internal Server Error", { status: 500 })

    }
}

export async function PUT(req: Request, { params }: { params: { id: string } }) {
    const { id } = params

    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");

        // console.log(code)
        // console.log(type)
        // console.log(value)
        // console.log(maxDiscount)
        // console.log(minPurchaseAmount)
        // console.log(startDate)
        // console.log(endDate)
        // console.log(usageLimit)
        // console.log(usageLimit)
        // console.log(usageCount)
        // console.log(perUserLimit)
        // console.log(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" || type == "PERCENTAGE") discountType = DiscountType.PERCENTAGE;
        else if (type === "Fixed" || type == 'FIXED_AMOUNT') discountType = DiscountType.FIXED_AMOUNT;
        else if (type === "Free Shipping" || type == "FreeShipping" || type == "FREE_SHIPPING") discountType = DiscountType.FREE_SHIPPING;
        else return new NextResponse("Invalid discount type", { status: 400 });


        const couponExists = await db.coupon.findUnique({
            where: {
                id: Number(id),
            }
        })

        if (!couponExists){
            return NextResponse.json({message: "Coupon not found!"}, { status: 404 });
        }

        const coupon = await db.coupon.update({
            where: {
                id: Number(id)
            },
            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: couponExists.usageCount,
                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,
            },
        });


        return NextResponse.json({ coupon }, { status: 200 });

    }
    catch (error: any) {
        console.log(error)

        logger.error("Failed to update coupon", { errorMsg: error?.message, errorData: error?.config?.data });
        return new NextResponse("Internal Server Error", { status: 500 })
    }

}