import type { NextApiRequest, NextApiResponse } from "next";
import { app, storage } from "@/firebase";
import {
  getFirestore,
  doc,
  getDoc,
  deleteDoc,
  updateDoc,
} from "firebase/firestore";
import { withIronSessionApiRoute } from "iron-session/next";
import { sessionOptions } from "@/lib/session";
import ReactPDF from "@react-pdf/renderer";
import PDFReport from "@/exams/pdf";
import {
  ref,
  uploadBytes,
  deleteObject,
  getDownloadURL,
} from "firebase/storage";
import blobStream from "blob-stream";
import { Stat } from "@/interfaces/user";
import { User } from "@/interfaces/user";

const db = getFirestore(app);

export default withIronSessionApiRoute(handler, sessionOptions);

async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === "POST") return post(req, res);
}

export const streamToBuffer = async (
    stream: NodeJS.ReadableStream,
  ): Promise<Buffer> => {
   return new Promise((resolve, reject) => {
    const chunks: Buffer[] = [];
    stream.on('data', (data) => {
      chunks.push(data);
    });
    stream.on('end', () => {
      resolve(Buffer.concat(chunks));
    });
    stream.on('error', reject);
   });
  };

async function post(req: NextApiRequest, res: NextApiResponse) {
  // debugger;
  if (req.session.user) {
    const { id } = req.query as { id: string };

    const docRef = doc(db, "stats", id);
    const docSnap = await getDoc(docRef);

    if (docSnap.exists()) {
      const stat = docSnap.data() as Stat;

      if (stat.user !== req.session.user.id) {
        res.status(401).json(undefined);
        return;
      }

    //   if (stat.pdf) {
    //     res.status(200).end(docSnap.pdf);
    //     return;
    //   }
      const docUser = await getDoc(doc(db, "users", stat.user));

      if (docUser.exists()) {
        const user = docUser.data() as User;
        const fileName = `${Date.now().toString()}.pdf`;
        const fileRef = ref(storage, `exam_report/${fileName}`);
        const pdfStream = await ReactPDF.renderToStream(
          <PDFReport
            date={new Date(stat.date).toString()}
            name={user.name}
            email={user.email}
            id={user.id}
            gender={user.demographicInformation?.gender}
          />
        );

        const pdfBuffer = await streamToBuffer(pdfStream);
        const snapshot = await uploadBytes(fileRef, pdfBuffer, {
            contentType: 'application/pdf',
        });
        await updateDoc(docRef, {
          pdf: snapshot.ref.fullPath,
        });
        res.status(200).end(snapshot.ref.fullPath);
        return;
      }
    }

    res.status(500).json({ ok: false });
    return;
  }

  res.status(401).json(undefined);
}
