import clientPromise, { database, objectId } from "@/db.config";
import { normalizeMongoDoc, ProcessPostLock } from "@/models/helper";
import { JWT } from "@/utils/jwt";
import { NextResponse } from "next/server";

export async function POST(request) {
  try {
    const jwt = new JWT();
    const { searchParams } = new URL(request.url);
    const post_id = searchParams.get("post_id");
    const uid = searchParams.get("uid");
    const session = new ProcessPostLock(post_id);

    // cookies
    const cookies = request.cookies.get("refreshToken")?.value;
    const userData = jwt.decodeToken(cookies);

    const client = await clientPromise;
    const db = client.db(database);
    const postslock = db.collection("posts_lock");

    return await session.execute(async () => {
      console.log({ post_id, userid: userData._id });

      // check user
      const currentLock = await postslock.findOne({
        post_id: objectId(post_id),
      });

      if (currentLock && currentLock.uid !== uid) {
        const user = await db
          .collection("users")
          .findOne(
            { _id: objectId(currentLock.user_id) },
            { projection: { name: 1 } }
          );

        return NextResponse.json(
          { status: "unauthorize", user: normalizeMongoDoc(user) },
          { status: 401 }
        );
      }

      await postslock.updateOne(
        { uid, post_id: objectId(post_id) },
        {
          $set: { heartBeat: new Date() },
          $setOnInsert: {
            uid,
            post_id: objectId(post_id),
            lockedSince: new Date(),
            user_id: objectId(userData._id),
          },
        },
        { upsert: true }
      );

      const indexes = await postslock.listIndexes().toArray();

      if (!indexes.map((i) => i?.name).includes("heartBeat_1"))
        // create ttl when not update on 10s will be deleted
        await postslock.createIndex(
          { heartBeat: 1 },
          { expireAfterSeconds: 10 }
        );

      return NextResponse.json({ status: "success" }, { status: 200 });
    });
  } catch (error) {
    console.log(error);
    return NextResponse.json({ error: error.message }, { status: 500 });
  }
}
