import prismadb from "@/lib/prisma";
import { NextResponse } from "next/server";

import { getServerSession } from "next-auth";

function countOccurrences(str: string, char: string) {
  return str.split(char).length - 1;
}

function strNoAccentNoSlash(a: string) {
  //enlever les accents
  let withoutAccents = a.normalize('NFD').replace(/[\u0300-\u036f]/g, '');

  //remplacer les '/' par '-'
  return withoutAccents.replace(/\//g, '-');
}

const corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Methods": "GET, OPTIONS",
  "Access-Control-Allow-Headers": "Content-Type, Authorization",
};

export async function OPTIONS() {
  return NextResponse.json({}, { headers: corsHeaders });
}

export async function GET(
  req: Request,
  { params }: { params: { productId: string } }
) {
  try {

    if (!params.productId) {
      return new NextResponse("Product id is required", { status: 400, headers: corsHeaders });
    }

    const product = await prismadb.product.findUnique({
      where: {
        id: params.productId,
        isArchived: false
      },
      include: {
        images: {
          orderBy: {
            order: 'asc'
          }
        },
        category: true,
        brand: true,
        promotion: true,
        featureValueToProduct: {
          include: {
            featureValue: {
              include: {
                feature: true
              }
            }
          }
        }
      }
    });

    return NextResponse.json(product, { headers: corsHeaders });
  } catch (error) {
    console.log('[PRODUCT_GET]', error);
    return new NextResponse("Internal error", { status: 500, headers: corsHeaders })
  }
};

export async function PATCH(
  req: Request,
  { params }: { params: { storeId: string, productId: string } }
) {
  try {
    const session = await getServerSession();
    const userId = session?.user?.email;

    const body = await req.json();

    const {
      name,
      reference,
      itemCode,
      shortDescription,
      description,
      price,
      purchasePrice,
      categoryId,
      brandId,
      featureValueToProduct,
      weight,
      carrierSurplus,
      stock,
      showMsgTwoLastStock,
      msgOutOfStock,
      showOutOfStock,
      orderOutOfStock,
      images,
      promotion,
      isFeatured,
      isArchived
    } = body;

    let brand = brandId;
    let slug = '';

    if (!userId) {
      return new NextResponse("Non connecté", { status: 401 });
    }

    if (!name) {
      return new NextResponse("Nom requis", { status: 400 });
    }

    if (!description) {
      return new NextResponse("Brève description requise", { status: 400 });
    }

    if (!description) {
      return new NextResponse("Description requise", { status: 400 });
    }

    if (!images || !images.length) {
      return new NextResponse("Images requises", { status: 400 });
    }

    if (!price) {
      return new NextResponse("Prix requis", { status: 400 });
    }

    if (!purchasePrice) {
      return new NextResponse("Prix d'achat requis", { status: 400 });
    }

    if (!categoryId) {
      return new NextResponse("Catégorie requise", { status: 400 });
    }

    if (!weight && weight !== 0) {
      return new NextResponse("Poids requis", { status: 400 });
    }

    if (!stock && stock !== 0) {
      return new NextResponse("Stock requis", { status: 400 });
    }

    if (!msgOutOfStock) {
      return new NextResponse("Message hors stock requis", { status: 400 });
    }

    if (!params.productId) {
      return new NextResponse("Id de produit requise", { status: 400 });
    }

    if (brandId == undefined || brandId == '') {
      brand = null;
    }

    const storeByUserId = await prismadb.store.findFirst({
      where: {
        id: params.storeId,
      },
      include: {
        userToStore: {
          where: {
            userId: userId
          }
        }
      }
    });

    if (!storeByUserId) {
      return new NextResponse("Non autorisé", { status: 403 });
    }

    //création du slug
    const productExist = await prismadb.product.findFirst({
      where: {
        name,
        categoryId,
        NOT: {
          id: params.productId
        }
      }
    })

    if (productExist) {
      return new NextResponse("Ce produit existe déjà dans cette catégorie", { status: 400 });
    }
    else {
      const category = await prismadb.category.findFirst({
        where: {
          id: categoryId
        }
      })
      slug = category?.slug + "-" + strNoAccentNoSlash(name).toLowerCase().replace(/\s+/g, '-');
    }

    //on fait une liste des featureValues non undefined ou = à ''
    const filteredFeatureValues = featureValueToProduct
      .filter((feature: any) => feature.featureValue && feature.featureValue.value !== undefined && feature.featureValue.value.length > 0)
      .map((feature: any) => ({
        featureValueId: (feature.featureValue.value.length == 36 && countOccurrences(feature.featureValue.value, '-') === 4 && !feature.featureValue.value.includes(' ')) ? feature.featureValue.value : feature.featureValue.id,
      }));

    const product = await prismadb.product.update({
      where: {
        id: params.productId
      },
      data: {
        name,
        slug,
        reference,
        itemCode,
        shortDescription,
        description,
        price,
        purchasePrice,
        weight,
        carrierSurplus,
        stock,
        showMsgTwoLastStock,
        msgOutOfStock,
        categoryId,
        brandId: brand,
        images: {
          deleteMany: {},
          createMany: {
            data: [
              ...images.map((image: { url: string, order: number }) => image),
            ]
          }
        },
        featureValueToProduct: {
          deleteMany: {},
          createMany: {
            data: filteredFeatureValues.map((featureId: any) => ({
              featureValueId: featureId.featureValueId
            }))
          }
        },
        promotion: {
          deleteMany: {},
          ...(promotion.unit !== '' && {
            create: {
              unit: promotion.unit,
              amount: promotion.amount,
              finishAt: promotion.finishAt
            }
          }),
        },
        isFeatured,
        isArchived,
        showOutOfStock,
        orderOutOfStock,
      }
    });

    return NextResponse.json(product);
  } catch (error) {
    console.log('[PRODUCT_PATCH]', error);
    return new NextResponse("Internal error", { status: 500 })
  }
};

export async function DELETE(
  req: Request,
  { params }: { params: { storeId: string, productId: string } }
) {
  try {
    const session = await getServerSession();
    const userId = session?.user?.email;

    if (!userId) {
      return new NextResponse("Non connecté", { status: 401 });
    }

    if (!params.productId) {
      return new NextResponse("Id de produit requis", { status: 400 });
    }

    const storeByUserId = await prismadb.store.findFirst({
      where: {
        id: params.storeId,
      },
      include: {
        userToStore: {
          where: {
            userId: userId
          }
        }
      }
    });

    if (!storeByUserId) {
      return new NextResponse("Non autorisé", { status: 403 });
    }

    await prismadb.featureValueToProduct.deleteMany({
      where: {
        productId: params.productId
      }
    })

    const product = await prismadb.product.deleteMany({
      where: {
        id: params.productId,
      }
    });

    return NextResponse.json(product);
  } catch (error) {
    console.log('[PRODUCT_DELETE]', error);
    return new NextResponse("Internal error", { status: 500 })
  }
};