import type { NextApiRequest, NextApiResponse } from "next";
import { app, storage } from "@/firebase";
import {
  getFirestore,
  doc,
  getDoc,
  deleteDoc,
  updateDoc,
  getDocs,
  query,
  collection,
  where,
} 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";
import { Module } from "@/interfaces";
import { ModuleScore } from "@/interfaces/module.scores";
import fs from 'fs';
import path from 'path';
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);
  });
};

const getExamSummary = (score: number) => {
  if (score > 0.8) {
    return "Scoring between 81% and 100% on the English exam demonstrates an outstanding level of proficiency in writing, speaking, listening, and reading. Mastery of key concepts is evident across all language domains, showcasing not only a high level of skill but also a dedication to excellence. Continuing to challenge oneself with advanced material in writing, speaking, listening, and reading will further refine the already impressive command of the English language.";
  }

  if (score > 0.6) {
    return "Scoring between 61% and 80% on the English exam, encompassing writing, speaking, listening, and reading, reflects a commendable level of proficiency in each domain. There's evidence of a solid grasp of key concepts, and effective application of skills. Room for refinement and deeper exploration in writing, speaking, listening, and reading remains, presenting an opportunity for further mastery.";
  }

  if (score > 0.4) {
    return "Scoring between 41% and 60% on the English exam across writing, speaking, listening, and reading demonstrates a moderate level of understanding in each domain. While there's a commendable grasp of key concepts, refining fundamental skills in writing, speaking, listening, and reading can lead to notable improvement. Consistent effort and targeted focus on weaker areas are recommended.";
  }

  if (score > 0.2) {
    return "Scoring between 21% and 40% on the English exam, spanning writing, speaking, listening, and reading, indicates some understanding of key concepts in each domain. However, there's room for improvement in fundamental skills. Strengthening writing, speaking, listening, and reading abilities through consistent effort and focused study will contribute to overall proficiency.";
  }

  return "This student's performance on the English exam, encompassing writing, speaking, listening, and reading, reflects a significant need for improvement, scoring between 0% and 20%. There's a notable gap in understanding key concepts across all language domains. Strengthening fundamental skills in writing, speaking, listening, and reading is crucial. Developing a consistent study routine and seeking additional support in each area can contribute to substantial progress.";
};

const getLevelSummary = (score: number) => {
  if (score > 0.8) {
    return "Scoring between 81% and 100% on the English exam showcases an outstanding level of understanding and proficiency. Your performance reflects a mastery of key concepts, including grammar, vocabulary, and comprehension. You exhibit a high level of skill in applying these elements effectively. Your dedication to excellence is evident, and your consistent, stellar performance is commendable. Continue to challenge yourself with advanced material to further refine your already impressive command of the English language. Your commitment to excellence positions you as a standout student in English studies, and your achievements are a testament to your hard work and capability.";
  }

  if (score > 0.6) {
    return "Scoring between 61% and 80% on the English exam reflects a commendable level of understanding and proficiency. You have demonstrated a solid grasp of key concepts, including grammar, vocabulary, and comprehension. There's evidence of effective application of skills, but room for refinement and deeper exploration remains. Consistent effort in honing nuanced aspects of language will contribute to even greater mastery. Continue engaging with challenging material and seeking opportunities for advanced comprehension. With sustained dedication, you have the potential to elevate your performance to an exceptional level and further excel in your English studies.";
  }

  if (score > 0.4) {
    return "Scoring between 41% and 60% on the English exam reflects a moderate level of understanding. You demonstrate a grasp of some key concepts, but there's room for refinement in areas like grammar, vocabulary, and comprehension. Consistent effort and a strategic focus on weaker areas can lead to notable improvement. Engaging with supplementary resources and seeking feedback will further enhance your skills. With continued dedication, there's a solid foundation to build upon, and achieving a higher level of proficiency is within reach. Keep up the good work and aim for sustained progress in your English studies.";
  }

  if (score > 0.2) {
    return "Scoring between 21% and 40% on the English exam shows some understanding of key concepts, but there's still ample room for improvement. Strengthening foundational skills, such as grammar, vocabulary, and comprehension, is essential. Consistent effort and focused study can help bridge gaps in knowledge and elevate your performance. Consider seeking additional guidance or resources to refine your understanding of the material. With commitment and targeted improvements, you have the potential to make significant strides in your English proficiency.";
  }

  return "Your performance on the English exam falls within the 0% to 20% range, indicating a need for improvement. There's room to enhance your grasp of fundamental concepts like grammar, vocabulary, and comprehension. Establishing a consistent study routine and seeking extra support can be beneficial. With dedication and targeted efforts, you have the potential to significantly boost your performance in upcoming assessments.";
};

const getPerformanceSummary = (module: Module, score: number) => {
  if (module === "level") return getLevelSummary(score);
  return getExamSummary(score);
};

const getListeningFeedback = () =>
  "Your listening skills are exceptional. You display a high level of attentiveness, accurately understanding spoken information across various contexts. Your ability to follow instructions and discern details from spoken content reflects a strong foundation in auditory comprehension. To further refine this skill, continue exposing yourself to diverse listening materials, including podcasts, interviews, and authentic conversations.";
const getReadingFeedback = () =>
  "Your reading skills are advanced, demonstrating a keen ability to comprehend and analyse written texts. You not only grasp the main ideas effectively but also excel in identifying supporting details and drawing inferences from context. Your enthusiasm for reading is evident, and I encourage you to explore more diverse and challenging materials to further expand your vocabulary and enhance your critical thinking skills.";
const getWritingFeedback = () =>
  "In the realm of writing, you showcase a commendable command of language. Your ability to construct well-organized and coherent sentences is notable. You exhibit a strong grasp of grammar and punctuation, contributing to the overall clarity of your written expression. Continue refining your writing style, and consider experimenting with different genres to unleash your creative potential.";
const getSpeakingFeedback = () =>
  "Your oral communication skills are a standout feature of your language proficiency. You articulate ideas with clarity and confidence, actively participating in discussions. Your ability to express yourself verbally is a valuable asset. To enhance your speaking skills even further, consider taking on leadership roles in group activities and engaging in more challenging speaking tasks, such as presentations and debates.";

const getFeedback = (module: Module) => {
  switch (module) {
    case "listening":
      return getListeningFeedback();
    case "reading":
      return getReadingFeedback();
    case "writing":
      return getWritingFeedback();
    case "speaking":
      return getSpeakingFeedback();
    default:
      return "";
  }
};
async function post(req: NextApiRequest, res: NextApiResponse) {
  if (req.session.user) {
    const { id } = req.query as { id: string };
    // const codeCheckerRef = await getDocs(
    //   query(collection(db, "codes"), where("checkout", "==", checkout))
    // );

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

    const docsSnap = await getDocs(
      query(
        collection(db, "stats"),
        where("session", "==", id),
        where("user", "==", req.session.user.id)
      )
    );

    if (docsSnap.empty) {
      res.status(404).end();
      return;
    }

    const docUser = await getDoc(doc(db, "users", req.session.user.id));

    if (docUser.exists()) {
      const user = docUser.data() as User;

      const stats = docsSnap.docs.map((d) => d.data());
      const results = stats.reduce((accm: ModuleScore[], { module, score }) => {
        const fixedModuleStr = module[0].toUpperCase() + module.substring(1)
        if (accm.find((e: ModuleScore) => e.module === fixedModuleStr)) {
          return accm.map((e: ModuleScore) => {
            if (e.module === fixedModuleStr) {
              return {
                ...e,
                score: e.score + score.correct,
                total: e.total + score.total,
              };
            }

            return e;
          });
        }

        return [
          ...accm,
          {
            module: fixedModuleStr,
            score: score.correct,
            total: score.total,
            feedback: getFeedback(module),
          },
        ];
      }, []) as ModuleScore[];

      const [stat] = stats as Stat[];

      const fileName = `${Date.now().toString()}.pdf`;
      const fileRef = ref(storage, `exam_report/${fileName}`);
      const overallScore = results.reduce((accm, { score }) => accm + score, 0);
      const overallTotal = results.reduce((accm, { total }) => accm + total, 0);
      const overallResult = overallScore / overallTotal;
      const performanceSummary = getPerformanceSummary("level", overallResult);
      // const logo = fs.readFileSync(path.resolve(__dirname, './logo_title.png'));
      const pdfStream = await ReactPDF.renderToStream(
        <PDFReport
          date={new Date(stat.date).toLocaleString()}
          name={user.name}
          email={user.email}
          id={user.id}
          gender={user.demographicInformation?.gender}
          summary={performanceSummary}
          testDetails={[
            {
              module: "Overall",
              score: overallScore,
              total: overallTotal,
            },
            ...results,
          ]}
          logo={"public/logo_title.png"}
        />
      );

      const pdfBuffer = await streamToBuffer(pdfStream);
      const snapshot = await uploadBytes(fileRef, pdfBuffer, {
        contentType: "application/pdf",
      });
      docsSnap.docs.forEach(async (doc) => {
        await updateDoc(doc.ref, {
          pdf: snapshot.ref.fullPath,
        });
      });
      res.status(200).end(snapshot.ref.fullPath);
      return;
    }
  }

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