import { jsonError, jsonResponse } from "../../../common.js";

export async function onRequestGet(context: RequestContext): Promise<any> {
  const type = context.params.type as string;
  const { searchParams } = new URL(context.request.url);
  const before = parseInt(searchParams.get("before") || `${Date.now()}`);
  const showClosed = searchParams.get("showClosed") === "true";
  const tables: { [k: string]: string } = {
    appeal: "appeals",
    gma: "game_appeals",
    inactivity: "inactivity_notices",
    report: "reports",
  };
  const permissions: { [k: string]: number[] } = {
    appeal: [1 << 0, 1 << 1],
    gma: [1 << 5],
    inactivity: [1 << 4, 1 << 6, 1 << 7, 1 << 11, 1 << 12],
    report: [1 << 5],
  };
  const { current_user: currentUser } = context.data;

  if (!tables[type]) return jsonError("Invalid filter type", 400);

  if (!permissions[type].find((p) => currentUser.permissions & p))
    return jsonError("You cannot use this filter", 403);

  if (isNaN(before)) return jsonError("Invalid `before` parameter", 400);

  let rows: D1Result<Record<string, any>>;

  switch (type) {
    case "appeal":
      rows = await context.env.D1.prepare(
        `SELECT *
         FROM appeals
         WHERE created_at < ?
           AND approved ${showClosed ? "IS NOT" : "IS"} NULL
         ORDER BY created_at DESC LIMIT 25;`,
      )
        .bind(before)
        .all();
      rows.results = rows.results.map((r) => {
        r.user = JSON.parse(r.user);
        delete r.user.email;

        return r;
      });
      break;

    case "gma":
      rows = await context.env.D1.prepare(
        "SELECT * FROM game_appeals WHERE created_at < ? ORDER BY created_at DESC LIMIT 25;",
      )
        .bind(before)
        .all();
      break;

    case "inactivity":
      rows = await context.env.D1.prepare(
        `SELECT *,
                (SELECT COUNT(*) FROM json_each(decisions)) as decision_count
         FROM inactivity_notices
         WHERE created_at < ?
           AND decision_count ${showClosed ? "=" : "!="} json_array_length(departments)`,
      )
        .bind(before)
        .all();

      rows.results.map((r) => {
        r.decisions = JSON.parse(r.decisions);
        r.departments = JSON.parse(r.departments);
        r.user = JSON.parse(r.user);

        delete r.user.email;

        return r;
      });
      break;

    case "report":
      rows = await context.env.D1.prepare(
        "SELECT * FROM reports WHERE created_at < ? AND open = ? ORDER BY created_at DESC LIMIT 25;",
      )
        .bind(before, !Number(showClosed))
        .all();

      rows.results = rows.results.map((r) => {
        r.attachments = JSON.parse(r.attachments);
        r.target_ids = JSON.parse(r.target_ids);
        r.target_usernames = JSON.parse(r.target_usernames);

        if (r.user) {
          r.user = JSON.parse(r.user);
          delete r.user.email;
        }

        return r;
      });

      break;

    default:
      return jsonError("Unknown filter error", 500);
  }

  return jsonResponse(JSON.stringify(rows.results));
}
