// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next";
import { app } from "@/firebase";
import {
  getFirestore,
  collection,
  getDocs,
  query,
  where,
} from "firebase/firestore";
import { withIronSessionApiRoute } from "iron-session/next";
import { sessionOptions } from "@/lib/session";
import { Payment } from "@/interfaces/paypal";
import { PaymentsStatus } from "@/interfaces/user.payments";

const db = getFirestore(app);

export default withIronSessionApiRoute(handler, sessionOptions);

async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === "GET") return await get(req, res);

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

// user can fetch payments assigned to him as an agent
async function get(req: NextApiRequest, res: NextApiResponse) {
  if (!req.session.user) {
    res.status(401).json({ ok: false });
    return;
  }

  // if it's an admin, don't apply query filters
  const whereClauses = ["admin", "developer"].includes(req.session.user.type)
    ? []
    : [
        // where("agent", "==", "xRMirufz6PPQqxKBgvPTWiWKBD63"),
        where(req.session.user.type, "==", req.session.user.id),
        // Based on the logic of query we should be able to do this:
        // where("isPaid", "==", paid === "paid"),
        // but for some reason it is ignoring all but the first clause
        // I opted into only fetching relevant content for the user
        // and then filter it with JS
      ];

  const codeQuery = query(collection(db, "payments"), ...whereClauses);

  const snapshot = await getDocs(codeQuery);
  if (snapshot.empty) {
    res.status(200).json({
      pending: [],
      done: [],
    });
    return;
  }

  const docs = snapshot.docs.map((doc) => ({
    id: doc.id,
    ...doc.data(),
  })) as Payment[];

  const paidStatusEntries = docs.reduce(
    (acc: PaymentsStatus, doc) => {
      if (doc.isPaid) {
        return {
          ...acc,
          done: [...acc.done, doc.corporate],
        };
      }

      return {
        ...acc,
        pending: [...acc.pending, doc.corporate],
      };
    },
    {
      pending: [],
      done: [],
    }
  );
  res.status(200).json({
    pending: [...new Set(paidStatusEntries.pending)],
    done: [...new Set(paidStatusEntries.done)],
  });
}
