import NextCrud, { PrismaAdapter } from "@premieroctet/next-crud";
import { Prisma } from "@prisma/client";
import { NextApiRequest, NextApiResponse } from "next";
import { getServerSession } from "next-auth/next";
import { authOptions } from "../auth/[...nextauth]";
import { JWT } from "next-auth/jwt";
const common = require("../../../src/helpers/common");
import jwt from 'jsonwebtoken';
const logger = require('../../../src/logger');

interface SessionUser {
  email?: string;
  name?: string;
}

interface Session {
  user?: SessionUser;
  expires: string;
}

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
  const prismaClient = common.getPrismaClient();

  const nextCrudHandler = await NextCrud({
    adapter: new PrismaAdapter({ prismaClient }),
    models: {
      [Prisma.ModelName.CartEvent]: { name: "cartevents" },
      [Prisma.ModelName.Publisher]: { name: "publishers" },
      [Prisma.ModelName.Availability]: { name: "availabilities" },
      [Prisma.ModelName.Location]: { name: "locations" },
      [Prisma.ModelName.Shift]: { name: "shifts" },
      [Prisma.ModelName.Assignment]: { name: "assignments" },
      [Prisma.ModelName.Report]: { name: "reports" },
      [Prisma.ModelName.Message]: { name: "messages" },
      [Prisma.ModelName.Survey]: { name: "surveys" },
      [Prisma.ModelName.EventLog]: { name: "eventlogs" },
    },
  });

  //1: check session
  const session = (await getServerSession(req, res, authOptions)) as Session | null;
  const authHeader = req.headers.authorization || '';

  if (session && req.query.nextcrud) {
    //get target table
    const targetTable = req.query.nextcrud[0];
    //get target action
    if (req.method === 'DELETE') {
      switch (targetTable) {
        default:
          const targetId = req.query.nextcrud[1];
          logger.info('[nextCrud] ' + targetTable + ': ' + targetId + ' DELETED  by ' + session.user?.email);
          break;
      }
    }
    console.log('[nextCrud]: request for ' + targetTable + '. params:', req.query);
    return nextCrudHandler(req, res);
  }
  else {
    console.log('[nextCrud]: No session');
  }

  //2: check jwt
  const secret = process.env.NEXTAUTH_SECRET;
  const bearerHeader = req.headers['authorization'];
  if (bearerHeader && secret) {
    const token = bearerHeader.split(' ')[1]; // Assuming "Bearer <token>"
    // try {
    //   const decodedToken = await getToken({ req, secret });
    //   if (decodedToken) {
    //     return nextCrudHandler(req, res);
    //   }
    // } catch (err) {
    //   console.error('[nextCrud]: Error decoding token:', err);
    // }
    try {
      const verified = jwt.verify(token, secret);
      return nextCrudHandler(req, res);
    } catch (err) {
      console.error('[nextCrud]: Invalid token:', err);
    }
  }

  //3. check X-From-Server header
  const xFromServer = req.headers['x-from-server'];
  if (xFromServer) {
    return nextCrudHandler(req, res);
  }

  return res.status(401).json({ message: '[nextCrud]: Unauthorized' });
};

export default handler;
