import { db, JudgementTable } from "@/lib/mastoauth/kysely";
import { cookies } from "next/headers";
import { NextRequest } from "next/server";

export async function GET(request: NextRequest, {params}: {params: {content:string, judgement:string}}) {
  const cid = params.content;
  if (cid == null) return new Response('', {
    status: 400
  });
  let content = await db
    .selectFrom('content')
    .where('content.id', '=', cid)
    .select('id')
    .executeTakeFirst();

  if (content == null) return new Response('', {
    status: 404
  });

  const jid = params.judgement;
  if (jid == null) return new Response('', {
    status: 400
  });
  let judgement = await db
    .selectFrom('judgements')
    .where('judgements.content_id', '=', cid)
    .where('judgements.id', '=', jid)
    .selectAll()
    .executeTakeFirst();

  if (judgement == null) return new Response('', {
    status: 404
  });

  return Response.json(judgement);
}

export async function PATCH(request: NextRequest, {params}: {params: {content:string, judgement:string}}) {
  const cid = params.content;
  if (cid == null) return new Response('', {
    status: 400
  });
  let content = await db
    .selectFrom('content')
    .where('content.id', '=', cid)
    .select('id')
    .executeTakeFirst();

  if (content == null) return new Response('', {
    status: 404
  });

  // verify user
  const cookieStore = cookies();
  const token = cookieStore.get('token')?.value;

  if (token == null) return new Response('', {
    status: 401
  });

  let existingToken = await db
    .selectFrom('tokens')
    .where('tokens.id', '=', token)
    .select('owner')
    .executeTakeFirst();

  if (existingToken == null) return new Response('', {
    status: 401
  });

  let existingUser = await db
    .selectFrom('users')
    .where('users.id', '=', existingToken.owner)
    .select(['admin', 'id', 'banned'])
    .executeTakeFirst();

  if (existingUser == null) return new Response('', {
    status: 401
  });

  if (existingUser.banned) return new Response('U banned motherfucka!', {
    status: 403
  });

  const id = params.judgement;

  if (id == null) return new Response('', {
    status: 400
  });
  
  let updatingJudgement = await db
    .selectFrom('judgements')
    .where('judgements.content_id', '=', cid)
    .where('judgements.id', '=', id)
    .select(['author_id'])
    .executeTakeFirst();

  console.log(cid, id, updatingJudgement, existingUser)

  if (updatingJudgement == null) return new Response('', {
    status: 400
  });

  if (!existingUser?.admin && updatingJudgement.author_id != existingUser.id) return new Response('you are NOT that guy.', {
    status: 401
  });

  let body;
  try { 
    body = await request.json();
  } catch (err) {
    return new Response('', {
      status: 400
    })
  }

  let newBody:Partial<JudgementTable> = {};

  if (body.content != null && typeof body.content === 'string' && body.content.length >= 10 && body.content.length <= 10000) newBody.content = body.content;
  
  let res;
  try {
    res = await db
      .updateTable('judgements')
      .set(newBody)
      .where('content_id', '=', cid)
      .where('id', '=', id)
      .executeTakeFirstOrThrow();
  } catch (err) {
    return new Response('', {
      status: 500
    });
  }

  return new Response(null, {
    status: 204
  });
}

export async function DELETE(request: NextRequest, {params}: {params: {content:string, judgement:string}}) {
  const cid = params.content;
  if (cid == null) return new Response('', {
    status: 400
  });
  let content = await db
    .selectFrom('content')
    .where('content.id', '=', cid)
    .select('id')
    .executeTakeFirst();

  if (content == null) return new Response('', {
    status: 404
  });

  // verify user
  const cookieStore = cookies();
  const token = cookieStore.get('token')?.value;

  if (token == null) return new Response('', {
    status: 401
  });

  let existingToken = await db
    .selectFrom('tokens')
    .where('tokens.id', '=', token)
    .select('owner')
    .executeTakeFirst();

  if (existingToken == null) return new Response('', {
    status: 401
  });

  let existingUser = await db
    .selectFrom('users')
    .where('users.id', '=', existingToken.owner)
    .select(['admin', 'id', 'banned'])
    .executeTakeFirst();

  if (existingUser == null) return new Response('', {
    status: 401
  });

  if (existingUser.banned) return new Response('U banned motherfucka!', {
    status: 403
  });

  const id = params.judgement;

  if (id == null) return new Response('', {
    status: 400
  });
  
  let deletingJudgement = await db
  .selectFrom('judgements')
  .where('judgements.content_id', '=', cid)
  .where('judgements.id', '=', id)
  .select(['author_id', 'content_id'])
  .executeTakeFirst();

  if (existingUser == null) return new Response('', {
    status: 401
  });

  console.log(cid, id, deletingJudgement, existingUser)

  if (deletingJudgement == null) return new Response('', {
    status: 400
  });

  let contentParent = await db
    .selectFrom('content')
    .where('content.id', '=', deletingJudgement.content_id)
    .select(['author_id', 'jam_id'])
    .executeTakeFirst();

  if (contentParent == null) return new Response('', {
    status: 500
  });

  let contentParentOwner = await db
    .selectFrom('users')
    .where('users.id', '=', contentParent.author_id)
    .select('id')
    .executeTakeFirst();

  if (contentParentOwner == null) return new Response('', {
    status: 500
  });

  let jamParent = await db
    .selectFrom('jams')
    .where('jams.id', '=', contentParent.jam_id)
    .select('author_id')
    .executeTakeFirst();

  if (jamParent == null) return new Response('', {
    status: 500
  });

  let jamParentOwner = await db
    .selectFrom('users')
    .where('users.id', '=', jamParent.author_id)
    .select('id')
    .executeTakeFirst();

  if (jamParentOwner == null) return new Response('', {
    status: 500
  });

  if (
    !existingUser?.admin 
    && contentParentOwner.id != existingUser.id 
    && jamParentOwner.id != existingUser.id 
    && deletingJudgement.author_id != existingUser.id
  ) return new Response('you are NOT that guy.', {
    status: 401
  });

  try {
    await db
      .deleteFrom('judgements')
      .where('judgements.id', '=', id)
      .executeTakeFirstOrThrow();
  } catch (err) {
    return new Response('', {
      status: 500
    });
  }

  return new Response(null, {
    status: 204
  });
}