import { getServerSession } from "next-auth";
import { authOptions } from "@/app/api/auth/[...nextauth]/auth-options";
import { UserRole } from "@prisma/client";
import { NextRequest, NextResponse } from "next/server";
import db from "@/lib/db";
import { UploadFIle } from "@/utils/backblaze";
import { getLogger } from "@/utils/logger";


const logger = getLogger("/api/admin/variants");

export const POST = async (req: NextRequest) => {

    try {
        const session = await getServerSession(authOptions);
        if (!session || session.user.role !== UserRole.ADMIN) {
            return new NextResponse("Forbidden", { status: 403 });
        }

        const formData = await req.formData()
        const name = formData.get("name")
        const onSell = formData.get("onSell") === "true" ? true : false
        const productId = formData.get("productId")
        const regular_price = formData.get("regular_price")
        const purchase_cost = formData.get("purchase_cost")
        const special_price = formData.get("special_price")
        const quantity = formData.get("quantity")
        const imagesCount = formData.get("imagesCount")
        const wareHouseInfo = formData.get("wareHouseInfo")
        const specifications = formData.get("specifications")

        const images = []

        for (let i = 0; i < parseInt(imagesCount as string); i++) {
            const image = formData.get(`images_${i}`)
            images.push(image)
        }
        const images2 = []

        for (let i = 0; i < images.length; i++) {
            const image = images[i] as File
            const fileName = image.name
            const fileType = image.type
            const fileContent = await image.arrayBuffer()
            const response = await UploadFIle(fileName, fileType, fileContent, process.env.BACKBLAZE_PUBLIC_BUCKET_ID ?? "")

            const imageUrl = response.fileUrl
            const fileId = response.fileId

            images2.push({
                imageUrl: imageUrl,
                fileId: fileId,
                fileName: fileName,
                fileType: fileType,
                fileContent: fileContent,
                uniqueFileName: response.UniqueFileName,
            })
        }

        const variant = await db.productVariant.create({
            data: {
                product: { connect: { id: parseInt(productId as string) } },
                name: name as string,
                on_sell: onSell,
                regular_price: parseFloat(regular_price as string),
                purchase_cost: parseFloat(purchase_cost as string),
                special_price: parseFloat(special_price as string),
                quantity: parseInt(quantity as string),
                specs: specifications ? JSON.parse(specifications as string) : undefined,
                wareHouseInfo: wareHouseInfo as string,
                sku: generateUUIDWithTime(),
                variant_images: {
                    create: images2.map((image) => ({
                        original_name: image.fileName,
                        file_name: image.uniqueFileName ?? "",
                        file_url: image.imageUrl ?? "",
                        file_id: image.fileId ?? "",
                        file_type: image.fileType,
                    }))
                },
            },
            include: {
                product: {
                    select: {
                        id: true,
                        category: true,
                    },
                },
            },
        })

        const sku = generateSKU(variant.product_id, variant.product.category.name, variant.id)
        await db.productVariant.update({
            where: {
                id: variant.id,
            },
            data: {
                sku: sku,
            },
        })

        return NextResponse.json({ mssg: 'VARIANT CREATE API' }, { status: 200 })
    }
    catch (error: any) {
        logger.error("Failed to create a variant", {
            error: error?.config?.data ?? error?.message ?? "Unknown error"
        });

        return NextResponse.json({ mssg: 'Internal Server error' }, { status: 500 })
    }


}

function generateSKU(pid: number, category: string, vid: number) {
    return `${pid}-${category}-${vid}`
}


function generateUUIDWithTime() {
    const now = Date.now(); // milliseconds since Unix epoch
    const timePart = now.toString(16); // convert to hex for compactness

    const randomPart = 'xxxxxxxxxxxx'.replace(/[x]/g, function () {
        return (Math.random() * 16 | 0).toString(16);
    });

    return `${timePart}-${randomPart}`;
}



export const GET = async (req: NextRequest) => {
    try {

        const { searchParams } = new URL(req.url)
        const page = parseInt(searchParams.get("page") || "1")
        const limit = parseInt(searchParams.get("limit") || "10")


        const session = await getServerSession(authOptions);
        if (!session || session.user.role !== UserRole.ADMIN) {
            return new NextResponse("Forbidden", { status: 403 });
        }

        const variants = await db.productVariant.findMany({
            skip: (page - 1) * limit,
            take: limit,
            orderBy: {
                id: 'desc'
            },
            include: {
                variant_images: true
            }
        })

        const totalVariants = await db.productVariant.count()

        return NextResponse.json({ variants: variants, page: page, limit: limit, total: totalVariants }, { status: 200 })
    }
    catch (error: any) {
        logger.error("Failed to fetch variants", {
            error: error?.config?.data ?? error?.message ?? "Unknown error"
        });

        return NextResponse.json({ mssg: 'Internal Server error' }, { status: 500 })
    }

}