import { getSessionUser } from "@/lib/auth";
import {
  createMailboxDeveloperApiKey,
  listMailboxDeveloperApiKeys,
  revokeMailboxDeveloperApiKey,
} from "@/lib/mail-integrations";
import {
  disableMailboxPop3AccessByEmail,
  disableMailboxExternalAccessByEmail,
  disableLegacyNativeAppCompatibility,
  setMailboxExternalAccessPasswordByEmail,
  setMailboxPop3PasswordByEmail,
  synchronizeMailboxExternalAccessByEmail,
} from "@/lib/mail-external-access";

function errorResponse(error: unknown) {
  const code = error instanceof Error ? error.message : "integration-request-failed";

  if (code === "mailbox-not-ready") {
    return Response.json(
      { error: code, message: "도메인 연결과 메일함 활성화를 완료한 뒤 외부 연동을 설정할 수 있습니다." },
      { status: 409 },
    );
  }

  if (code === "growth-plan-required") {
    return Response.json(
      { error: code, message: "외부 연동은 성장 플랜부터 이용할 수 있습니다." },
      { status: 403 },
    );
  }

  if (code === "external-access-password-required") {
    return Response.json(
      { error: code, message: "외부 연결에 사용할 비밀번호를 입력해주세요." },
      { status: 400 },
    );
  }

  if (code === "external-password-must-differ") {
    return Response.json(
      { error: code, message: "외부 연결 비밀번호는 오피셜메일 로그인 비밀번호와 다르게 설정해주세요." },
      { status: 400 },
    );
  }

  if (code.startsWith("mailcow-password-policy:")) {
    const minLength = Number(code.split(":")[1]) || 8;
    return Response.json(
      {
        error: "external-access-password-policy",
        message: `외부 연결 비밀번호는 ${minLength}자 이상이며 영문 대·소문자, 숫자, 특수문자를 포함해야 합니다.`,
      },
      { status: 400 },
    );
  }

  if (code === "api-key-name-required") {
    return Response.json(
      { error: code, message: "API 키를 구분할 이름을 입력해주세요." },
      { status: 400 },
    );
  }

  if (code === "api-key-limit-reached") {
    return Response.json(
      { error: code, message: "활성 API 키는 계정당 최대 10개까지 만들 수 있습니다." },
      { status: 409 },
    );
  }

  if (code === "api-key-not-found") {
    return Response.json(
      { error: code, message: "이미 폐기되었거나 존재하지 않는 API 키입니다." },
      { status: 404 },
    );
  }

  console.error("[mailbox-integrations] request failed", error);
  return Response.json(
    { error: "integration-request-failed", message: "외부 연동 설정을 처리하지 못했습니다." },
    { status: 500 },
  );
}

export async function GET() {
  const user = await getSessionUser();

  if (!user) {
    return Response.json({ error: "unauthorized" }, { status: 401 });
  }

  try {
    const externalAccess = await synchronizeMailboxExternalAccessByEmail(user.email);

    return Response.json({
      ok: true,
      ...(await listMailboxDeveloperApiKeys(user.email)),
      mailAppAccessEnabled: externalAccess.enabled,
      legacyAppCompatibilityEnabled: externalAccess.legacyAppCompatibilityEnabled,
      pop3AccessEnabled: externalAccess.pop3Enabled,
    });
  } catch (error) {
    return errorResponse(error);
  }
}

export async function PUT(request: Request) {
  const user = await getSessionUser();

  if (!user) {
    return Response.json({ error: "unauthorized" }, { status: 401 });
  }

  let body: { accessType?: unknown; password?: unknown };

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

  try {
    if (body.accessType === "pop3") {
      const result = await setMailboxPop3PasswordByEmail(
        user.email,
        typeof body.password === "string" ? body.password : "",
      );
      return Response.json({ ok: true, pop3AccessEnabled: result.enabled });
    }

    const result = await setMailboxExternalAccessPasswordByEmail(
      user.email,
      typeof body.password === "string" ? body.password : "",
    );
    return Response.json({
      ok: true,
      mailAppAccessEnabled: result.enabled,
      pop3AccessEnabled: result.pop3Enabled,
    });
  } catch (error) {
    return errorResponse(error);
  }
}

export async function PATCH(request: Request) {
  const user = await getSessionUser();

  if (!user) {
    return Response.json({ error: "unauthorized" }, { status: 401 });
  }

  let body: { legacyAppCompatibilityEnabled?: unknown; mailAppAccessEnabled?: unknown; pop3AccessEnabled?: unknown };

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

  try {
    if (body.legacyAppCompatibilityEnabled === false) {
      await disableLegacyNativeAppCompatibility(user.email);
      const status = await synchronizeMailboxExternalAccessByEmail(user.email);
      return Response.json({
        ok: true,
        legacyAppCompatibilityEnabled: status.legacyAppCompatibilityEnabled,
        mailAppAccessEnabled: status.enabled,
      });
    }

    if (body.pop3AccessEnabled === false) {
      const result = await disableMailboxPop3AccessByEmail(user.email);
      return Response.json({ ok: true, pop3AccessEnabled: result.enabled });
    }

    if (body.mailAppAccessEnabled === false) {
      const result = await disableMailboxExternalAccessByEmail(user.email);
      return Response.json({
        ok: true,
        mailAppAccessEnabled: result.enabled,
        pop3AccessEnabled: result.pop3Enabled,
      });
    }

    return Response.json(
      { error: "invalid-operation", message: "변경할 외부 연동 설정을 확인해주세요." },
      { status: 400 },
    );
  } catch (error) {
    return errorResponse(error);
  }
}

export async function POST(request: Request) {
  const user = await getSessionUser();

  if (!user) {
    return Response.json({ error: "unauthorized" }, { status: 401 });
  }

  let body: { name?: unknown };

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

  try {
    const result = await createMailboxDeveloperApiKey(
      user.email,
      typeof body.name === "string" ? body.name : "",
    );

    return Response.json({ ok: true, ...result }, { status: 201 });
  } catch (error) {
    return errorResponse(error);
  }
}

export async function DELETE(request: Request) {
  const user = await getSessionUser();

  if (!user) {
    return Response.json({ error: "unauthorized" }, { status: 401 });
  }

  let body: { id?: unknown };

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

  try {
    await revokeMailboxDeveloperApiKey(user.email, Number(body.id));
    return Response.json({ ok: true });
  } catch (error) {
    return errorResponse(error);
  }
}
