import { NextRequest, NextResponse } from "next/server";

import { verifyDeviceUrlToken } from "@/lib/device-url-auth";
import { createRunContextToken, saveRunContext } from "@/lib/run-context";

export const runtime = "nodejs";

type DeviceUrlRequest = {
  data?: {
    imei?: unknown;
    partner_name?: unknown;
    redirect_url?: unknown;
  };
};

const IMEI_PATTERN = /^\d{15,17}$/;

function response(message: string, status: number, data: object = {}) {
  return NextResponse.json(
    {
      status: status < 400 ? "success" : "error",
      code: status,
      message,
      data,
    },
    { status },
  );
}

export async function POST(request: NextRequest) {
  const authorization = request.headers.get("authorization");

  const token = authorization?.startsWith("Bearer ")
    ? authorization.slice("Bearer ".length).trim()
    : authorization?.trim();

  if (!token) {
    return response("Authorization token is required", 401);
  }

  try {
    verifyDeviceUrlToken(token);
  } catch {
    return response("The authorization token is invalid or expired", 401);
  }

  let body: DeviceUrlRequest;

  try {
    body = (await request.json()) as DeviceUrlRequest;
  } catch {
    return response("The request body must be valid JSON", 400);
  }

  const partnerName =
    typeof body.data?.partner_name === "string"
      ? body.data.partner_name.trim().toLowerCase()
      : "";
  const imei =
    typeof body.data?.imei === "string" ||
    typeof body.data?.imei === "number"
      ? String(body.data.imei).trim()
      : "";
  const redirectUrl =
    typeof body.data?.redirect_url === "string"
      ? body.data.redirect_url.trim()
      : "";

  if (!IMEI_PATTERN.test(imei)) {
    return response("imei must contain between 15 and 17 digits", 400);
  }

  const runContext = {
    imei,
    redirect_url: redirectUrl,
    partner_name: partnerName,
    savedAt: new Date().toISOString(),
  };
  const urlParams = new URLSearchParams({ imei });

  if (redirectUrl) {
    urlParams.set("redirect_url", redirectUrl);
  }

  urlParams.set("context_token", createRunContextToken(runContext));

  const url = new URL(
    `/devicetest/${encodeURIComponent(partnerName)}?${urlParams.toString()}`,
    process.env.DIAGNOSTIC_APP_ORIGIN!
  ).toString();

  let contextSaved = false;

  try {
    contextSaved = await saveRunContext(runContext);
  } catch (error) {
    console.error("Failed to save generated URL run context:", error);

    return response(
      "Unable to create test URL because run context storage failed",
      500,
    );
  }

  return response("Request successful", 200, {
    url,
    context_saved: contextSaved,
    context_mode: contextSaved ? "stored" : "signed-token",
    data: {
      imei,
      redirect_url: redirectUrl,
    },
  });
}
