import { NextResponse } from "next/server";
import { getServerSession } from "next-auth";

import prismadb from "@/lib/prisma";
import { compare, hash } from "bcrypt";
import { sendNewPassword } from "../../email/forgotPassword/sendNewPassword";

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

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

//login un utilisateur AVEC compte
export async function POST(
  req: Request,
  { params }: { params: { storeId: string } }
) {
  try {
    const body = await req.json();

    const { email, password } = body;

    if (!email) {
      return new NextResponse("Adresse mail requise", { status: 400, headers: corsHeaders });
    }

    if (!password) {
      return new NextResponse("Mot de passe requis", { status: 400, headers: corsHeaders });
    }

    if (!params.storeId) {
      return new NextResponse("Boutique requise", { status: 400, headers: corsHeaders });
    }

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

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

    //on vérifie si l'adresse mail est utilisée pour un compte avec account exist
    const customerExist = await prismadb.customer.findFirst({
      where: {
        email,
        account: true,
        storeId: params.storeId
      }
    })

    //si utilisée :
    if (customerExist) {
      //comparaison du mdp en bdd et de celui envoyé par l'utilisateur
      if (await compare(password, customerExist?.password || '')) {
        return NextResponse.json(customerExist, { headers: corsHeaders });
      }
      else {
        return NextResponse.json("Mot de passe incorrect", {
          status: 400,
          headers: corsHeaders
        });
      }
    }
    //sinon
    return NextResponse.json("Aucun compte renseigné avec cette adresse mail", {
      status: 400,
      headers: corsHeaders
    });

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

//reset password : mdp oublié
export async function PATCH(
  req: Request,
  { params }: { params: { storeId: string } }
) {
  try {
    const body = await req.json();

    const { email } = body;

    if (!email) {
      return new NextResponse("Adresse mail requise", { status: 400, headers: corsHeaders });
    }

    if (!params.storeId) {
      return new NextResponse("Boutique requise", { status: 400, headers: corsHeaders });
    }

    //on vérifie si l'adresse mail est utilisée pour un compte avec account exist
    const customerExist = await prismadb.customer.findFirst({
      where: {
        email,
        storeId: params.storeId
      }
    })

    //si utilisée :
    if (customerExist) {
      //génération d'un nouveau mdp
      const password = generateRandomString(8);
      //hashage du mdp
      let passwordHash = await hash(password, 10);
      //insert en bd
      const customerExist = await prismadb.customer.updateMany({
        where: {
          email
        },
        data: {
          password: passwordHash,
          account: true
        }
      })

      //envoie mail
      sendNewPassword(params.storeId, email, password);
      //réponse web
      return NextResponse.json(customerExist, { headers: corsHeaders });
    }
    //sinon
    return NextResponse.json("Aucun compte renseigné avec cette adresse mail", {
      status: 400,
      headers: corsHeaders
    });

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

function generateRandomString(length: number) {
  const characters = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz123456789';
  let result = '';

  for (let i = 0; i < length; i++) {
    const randomIndex = Math.floor(Math.random() * characters.length);
    result += characters.charAt(randomIndex);
  }

  return result;
}