import { NextRequest, NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "@/app/api/auth/[...nextauth]/auth-options";
import db from "@/lib/db";
import { DeleteFileById, UploadFIle } from "@/utils/backblaze";
import {Prisma, UserRole} from "@prisma/client";
import {getLogger} from "@/utils/logger";

const logger = getLogger("/api/admin/collections/[collectionUUID]");

export const DELETE = async (req: NextRequest, { params }: { params: { collectionUUID: string } }) => {
  try {
    const session = await getServerSession(authOptions);

    if (!session || session.user.role !== UserRole.ADMIN) {
      logger.warn("Forbidden", { status: 403, session: session, userRole: session?.user.role });
      return new NextResponse("Forbidden", { status: 403 });
    }

    const collection = await db.collections.findFirst({
      where: {
        uuid: params.collectionUUID,
      }
    })

    if (collection) {
      const attachments = await db.attachments.findMany({
        where: {
          collection_id: collection.id,
        }
      })

      for (let i = 0; i < attachments.length; i++) {
        const uploadRes = DeleteFileById(attachments[i].file_id as string, attachments[i].file_name as string, process.env.BACKBLAZE_PUBLIC_BUCKET_ID as string)
      }

      await db.attachments.deleteMany({
        where: {
          collection_id: collection.id,
        }
      })

      await db.collections.delete({
        where: {
          id: collection.id,
        }
      })

      logger.info("Collection Deleted Successfully", {uuid: params.collectionUUID});
      return NextResponse.json({msg: 'Collection Deleted Successfully'}, {status: 200})
    } else {
      logger.error("Collection Not found", {uuid: params.collectionUUID});
      return NextResponse.json({msg: 'Collection Not found'}, {status: 200})
    }
  } catch (error: any) {
    if (error instanceof Prisma.PrismaClientValidationError) {
      logger.error("Prisma Validation Error ", {error: error.message});
    } else {
      logger.error("Error occurred while deleting collection and associated images", {
        errorMsg: error.message,
        errorData: error.config.data
      });
    }
    return new NextResponse("Internal Server Error", {status: 500});
  }
};

export const GET = async (req: NextRequest, { params }: { params: { collectionUUID: string } }) => {
  try {
    const collection = await db.collections.findFirst({
      where: {
        uuid: params.collectionUUID,
      },
      select: {
        id: true,
        uuid: true,
        title: true,
        description: true,
        collection_images: {
          select: {
            uuid: true,
            file_id: true,
            file_url: true,
            file_name: true,
            file_type: true
          }
        }
      }
    })

    return NextResponse.json(collection, {status: 200})
  } catch (error: any) {
    if (error instanceof Prisma.PrismaClientValidationError) {
      logger.error("Prisma Validation Error ", {error: error.message});
    } else {
      logger.error("Error fetching collection data", {
        errorMsg: error.message,
        errorData: error.config.data
      });
    }
    return new NextResponse("Internal server Error", { status: 500 });
  }
};

export const PUT = async (req: NextRequest, { params }: { params: { collectionUUID: string } }) => {
  try {
    const session = await getServerSession(authOptions);

    const formData = await req.formData()

    const title = formData.get('title')
    const description = formData.get('description')
    const imagesCount = formData.get('imagesCount')?.toString() ?? ''
    let images = []
    let deleteImages = []

    const deleteImageCount = formData.get('deleteImageCount')?.toString() ?? ''

    for (let i=0; i<parseInt(deleteImageCount); i++){
      deleteImages.push(formData.get(`deleteImageId_${i}`) as string)
    }
    
    if (!session || session.user.role !== UserRole.ADMIN) {
      logger.warn("Forbidden", { status: 403, session: session, userRole: session?.user.role });
      return new NextResponse("Forbidden", { status: 403 });
    }

    for (let i = 0; i < parseInt(imagesCount.toString()); i++) {
      const image = formData.get(`image_${i}`)
      images.push(image)
    }

    let attachments;

    if (deleteImages.length > 0){
      attachments = await db.attachments.findMany({
        where: {
          uuid: { in: deleteImages}
        },
        select: {
          file_id: true,
          file_name: true
        }

      })

      for (let i=0; i<attachments.length; i++){
        try {
          const deleteRes = await DeleteFileById(attachments[i].file_id as string, attachments[i].file_name as string, process.env.BACKBLAZE_PUBLIC_BUCKET_ID as string)

        } catch (error:any){
          logger.warn("Error deleting file from Backblaze", { function: DeleteFileById})
          // console.log('Error deleting file from backblaze')
        }
      }

      await db.attachments.deleteMany({
        where: {
          uuid: {in: deleteImages}
        }
      })
    }

    const updateResponse = await db.collections.update({
      where: {
        uuid: params.collectionUUID
      },
      data: {
        title: title?.toString(),
        description: description?.toString()
      }
    })

    for (let i=0 ; i < images.length; i++){
      const imageFile = images[i] as File;
      const fileName = imageFile.name
      const fileType = imageFile.type
      const fileContent = await imageFile.arrayBuffer()

      const response = await UploadFIle(fileName, fileType, fileContent, process.env.BACKBLAZE_PUBLIC_BUCKET_ID ?? '')

      const collectionAttachment = await db.attachments.create({
        data: {
          original_name: fileName,
          file_name: response.UniqueFileName?? '',
          file_url: response.fileUrl?? '', // Fix this code later
          file_id: response.fileId,
          file_type: fileType,
          collection_id: updateResponse.id
        }
      })
    }

    logger.info("Collection updated successfully ", {uuid: params.collectionUUID});
    return new NextResponse("Collection updated successfully", { status: 200 });
  } catch (error: any) {
    if (error instanceof Prisma.PrismaClientValidationError) {
      logger.error("Prisma Validation Error ", {error: error.message});
    } else {
      logger.error("An error occurred while updating collection", {
        errorMsg: error.message,
        errorData: error.config.data
      });
    }
    return new NextResponse("Internal server error", { status: 500 });
  }
};
