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

export async function GET(request: NextRequest) {
  const cookieStore = cookies();
  const token = cookieStore.get('token')?.value;
  let existingUser:JSONUserTable | undefined;
  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() as unknown as JSONUserTable;
    }
  }
  
  const until = parseInt(request.nextUrl.searchParams.get("until") || Date.now().toString());
  let jams = await db
    .selectFrom('jams')
    .where('jams.created', '<', until)
    .limit(20)
    .orderBy('jams.created', 'desc')
    .selectAll()
    .execute() as unknown[] as JSONJamTable[];

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

  jams.forEach((jam) => {
    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(jams);
}

export async function POST(request: NextRequest) {
  // 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
  });

  if (!existingUser.admin) return new Response('you are NOT that guy.', {
    status: 401
  });

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

  const te = [];
  if (body.id != null) te.push("id");
  if (body.author_id != null) te.push("author_id");
  if (typeof body.name !== 'string' || body.name.length < 10 || body.name.length > 2048) te.push("name");
  if (typeof body.description !== 'string' || body.description.length < 10 || body.description.length > 10000) te.push("description");
  if (typeof body.theme !== 'string' || body.theme.length < 2 || body.theme.length > 255) te.push("theme");
  if (typeof body.theme_description !== 'string' || body.theme_description.length < 10 || body.theme_description.length > 10000) te.push("theme_description");
  if (typeof body.date_start !== 'number') te.push("date_start");
  if (typeof body.date_end !== 'number') te.push("date_end");
  if (body.created != null) te.push("created");
  

  if (te.length > 0) return new Response(JSON.stringify(te, null, 2), {
    status: 400
  })

  let newBody:JamTable = body;

  let curBody = {
    id: nanoid(21),
    author_id: existingUser.id,
    name: newBody.name,
    description: newBody.description,
    theme: newBody.theme,
    theme_description: newBody.theme_description,
    date_start: newBody.date_start,
    date_end: newBody.date_end,
    created: Date.now()
  };

  let res;
  try {
    res = await db
      .insertInto('jams')
      .values(curBody)
      .executeTakeFirstOrThrow();
  } catch (err) {
    return new Response('', {
      status: 500
    });
  }

  return new Response(curBody.id, {
    status: 200
  })
}