import { resolveMailAppUrlFromHeaders } from "@/lib/mail-urls";
import { requestFindIdEmail } from "@/lib/official-mail";
import {
  getAuthRequestMetadata,
  recordUserAuthActivity,
} from "@/lib/auth-activity";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

type FindIdRequestBody = {
  recoveryEmail?: string;
};

function mapRequestError(error: unknown) {
  if (!(error instanceof Error)) {
    return {
      error: "system",
      message: "아이디 안내 메일을 보내지 못했습니다. 잠시 후 다시 시도해주세요.",
      status: 500,
    };
  }

  if (error.message === "required") {
    return {
      error: "required",
      message: "보조 이메일을 입력해주세요.",
      status: 400,
    };
  }

  if (error.message === "invalid-email") {
    return {
      error: "invalid-email",
      message: "보조 이메일 형식을 확인해주세요.",
      status: 400,
    };
  }

  if (error.message === "not-found") {
    return {
      error: "not-found",
      message: "입력한 보조 이메일로 가입된 아이디를 찾을 수 없습니다.",
      status: 404,
    };
  }

  if (error.message.startsWith("find-id-rate-limit:")) {
    const retryAfterSeconds = Math.max(
      1,
      Number(error.message.replace("find-id-rate-limit:", "")) || 1,
    );
    return {
      error: "rate-limit",
      message: `${retryAfterSeconds}초 뒤 다시 시도해주세요.`,
      retryAfterSeconds,
      status: 429,
    };
  }

  return {
    error: "system",
    message: "아이디 안내 메일을 보내지 못했습니다. 잠시 후 다시 시도해주세요.",
    status: 500,
  };
}

export async function POST(request: Request) {
  let body: FindIdRequestBody | null = null;

  try {
    body = await request.json();
  } catch {
    return Response.json(
      {
        error: "invalid-json",
        message: "요청 형식이 올바르지 않습니다.",
      },
      { status: 400 },
    );
  }

  const recoveryEmail = String(body?.recoveryEmail ?? "").trim().toLowerCase();
  const authRequestMetadata = getAuthRequestMetadata(request.headers, "app");

  try {
    const mailAppUrl = resolveMailAppUrlFromHeaders(request.headers);
    const loginUrl = new URL("/login", `${mailAppUrl.replace(/\/$/, "")}/`).toString();
    const result = await requestFindIdEmail({
      recoveryEmail,
      loginUrl,
    });
    await recordUserAuthActivity({
      ...authRequestMetadata,
      eventType: "find_id",
      identityEmail: recoveryEmail,
      lookup: "recovery_email",
      outcome: "success",
    });

    return Response.json({
      ...result,
      message: "아이디 안내 메일을 보냈습니다.",
    });
  } catch (error) {
    console.error("App find ID request failed", error);
    const mapped = mapRequestError(error);
    await recordUserAuthActivity({
      ...authRequestMetadata,
      eventType: "find_id",
      identityEmail: recoveryEmail,
      lookup: "recovery_email",
      outcome:
        mapped.error === "rate-limit"
          ? "rate_limited"
          : mapped.error.replaceAll("-", "_").slice(0, 32),
    });

    return Response.json(
      {
        error: mapped.error,
        message: mapped.message,
        ...(mapped.retryAfterSeconds
          ? { retryAfterSeconds: mapped.retryAfterSeconds }
          : {}),
      },
      { status: mapped.status },
    );
  }
}
