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

export async function GET(request: NextRequest, {params}: {params: {jam:string}}) {
  const cookieStore = cookies();
  const token = cookieStore.get('token')?.value;
  let existingUser;
  if (token != null) {
    let existingToken = await db
      .selectFrom('tokens')
      .where('tokens.id', '=', token)
      .select('owner')
      .executeTakeFirst();

    if (existingToken != null) {
      existingUser = await db
        .selectFrom('users')
        .where('users.id', '=', existingToken.owner)
        .selectAll()
        .executeTakeFirst();
    }
  }

  const id = params.jam;
  if (id == null) return new Response('', {
    status: 400
  });
  let jam = await db
    .selectFrom('jams')
    .where('jams.id', '=', id)
    .selectAll()
    .executeTakeFirst() as unknown as JSONJamTable;

  if (jam == null) return new Response('', {
    status: 404
  });
  
  const started = Date.now() >= parseInt(jam.date_start);

  if (!started && !existingUser?.admin && jam.author_id != existingUser?.id) {
    jam.theme = "";
    jam.theme_description = "";
  }

  return Response.json(jam);
}

export async function PATCH(request: NextRequest, {params}: {params: {jam:string}}) {
  // 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.jam;

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

  console.log(updatingJam, existingUser)

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

  if (!existingUser?.admin && updatingJam.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<JamTable> = {};

  if (body.name != null && typeof body.name === 'string' && body.name.length >= 10 && body.name.length <= 2048) newBody.name = body.name;
  if (body.description != null && typeof body.description === 'string' && body.description.length >= 10 && body.description.length <= 10000) newBody.description = body.description;
  if (body.theme != null && typeof body.theme === 'string' && body.theme.length >= 2 && body.theme.length <= 255) newBody.theme = body.theme;
  if (body.theme_description != null && typeof body.theme_description === 'string' && body.theme_description.length >= 10 && body.theme_description.length <= 10000) newBody.theme_description = body.theme_description;
  if (body.date_start != null && typeof body.date_start === 'number') newBody.date_start = body.date_start;
  if (body.date_end != null && typeof body.date_end === 'number') newBody.date_end = body.date_end;
  
  let res;
  try {
    res = await db
      .updateTable('jams')
      .set(newBody)
      .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: {jam:string}}) {
  // 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.jam;

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

  console.log(deletingJam, existingUser)

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

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

  try {
  await db
    .updateTable('content')
    .set('content.jam_id', '')
    .where('content.jam_id', '=', id)
    .execute();
  } catch (err) {
  }

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

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