import { getSessionUser } from "@/lib/auth";
import { normalizeSupportedLocale } from "@/lib/i18n-config";
import type { MailListSortOrder } from "@/lib/mail-layout";
import { getCachedMailboxMessageTranslationForEmail } from "@/lib/mail-message-translation";
import { normalizeMailboxPageSize } from "@/lib/mailbox-page-size";
import {
  getMailAppOverviewByEmail,
  refreshMailboxByEmail,
  refreshMailboxIfStaleByEmail,
  type MailMessageFilter,
  type MailSearchField,
} from "@/lib/official-mail";

type MailboxNotice = {
  tone: "error" | "success";
  message: string;
};

function pickMessageFilter(value: string | null): MailMessageFilter {
  if (value === "unread" || value === "important" || value === "attachments") {
    return value;
  }

  return "all";
}

function pickPositivePage(value: string | null) {
  const page = Number(value ?? "1");

  if (!Number.isFinite(page) || page < 1) {
    return 1;
  }

  return Math.floor(page);
}

function pickSearchField(value: string | null): MailSearchField {
  if (value === "correspondent" || value === "from" || value === "to" || value === "subject" || value === "body") {
    return value;
  }

  return "all";
}

function pickSortOrder(value: string | null): MailListSortOrder {
  return value === "oldest" ? "oldest" : "latest";
}

function extractErrorDetail(message: string, prefix: string) {
  if (!message.startsWith(prefix)) {
    return "";
  }

  return message.slice(prefix.length).trim().slice(0, 240);
}

function isMailboxLockContention(error: unknown) {
  if (!(error instanceof Error)) {
    return false;
  }

  const message = error.message.toLowerCase();

  return (
    message.includes("deadlock found") ||
    message.includes("lock wait timeout") ||
    message.includes("total number of locks exceeds") ||
    message.includes("er_lock_deadlock") ||
    message.includes("er_lock_wait_timeout") ||
    message.includes("er_lock_table_full")
  );
}

function mapRefreshError(error: unknown): MailboxNotice {
  if (
    error instanceof Error &&
    (error.message === "mailbox-auth-missing" || error.message === "mailbox-auth-invalid")
  ) {
    return {
      tone: "error",
      message: "메일함 인증 정보가 없거나 올바르지 않습니다.",
    };
  }

  if (error instanceof Error && error.message.startsWith("mailbox-imap-failed:")) {
    const detail = extractErrorDetail(error.message, "mailbox-imap-failed:");

    return {
      tone: "error",
      message: detail
        ? `메일함 새로고침 중 오류가 발생했습니다. (${detail})`
        : "메일함 새로고침 중 오류가 발생했습니다.",
    };
  }

  if (isMailboxLockContention(error)) {
    return {
      tone: "error",
      message: "다른 메일 작업과 동기화가 겹쳐 잠시 지연되고 있습니다. 잠시 후 다시 시도해주세요.",
    };
  }

  return {
    tone: "error",
    message: "메일함 새로고침 중 오류가 발생했습니다.",
  };
}

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

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

  const { searchParams } = new URL(request.url);
  const folder = searchParams.get("folder")?.trim() || "inbox";
  const page = pickPositivePage(searchParams.get("page"));
  const pageSize = normalizeMailboxPageSize(searchParams.get("pageSize"));
  const messageFilter = pickMessageFilter(searchParams.get("tab"));
  const sortOrder = pickSortOrder(searchParams.get("sort"));
  const searchField = pickSearchField(searchParams.get("field"));
  const searchQuery = searchParams.get("q")?.trim() ?? "";
  const message = searchParams.get("message");
  const messageId = message ? Number(message) : null;
  const refreshMode = searchParams.get("refresh");
  const targetLocale = normalizeSupportedLocale(searchParams.get("locale"));
  const shouldRefresh = refreshMode === "1";
  const shouldRefreshIfStale = refreshMode === "stale";
  let notice: MailboxNotice | null = null;

  if (shouldRefresh || shouldRefreshIfStale) {
    try {
      if (shouldRefresh) {
        await refreshMailboxByEmail(user.email, { folder });
        notice = {
          tone: "success",
          message: "메일함을 다시 동기화했습니다.",
        };
      } else {
        await refreshMailboxIfStaleByEmail(user.email, { folder });
      }
    } catch (error) {
      notice = mapRefreshError(error);
    }
  }

  const data = await getMailAppOverviewByEmail(user.email, {
    folder,
    messageId: Number.isFinite(messageId) ? messageId : null,
    messageFilter,
    sortOrder,
    searchField,
    searchQuery,
    page,
    pageSize,
    markMessageRead: false,
  });
  const cachedTranslation =
    targetLocale && data?.selectedMessage?.direction === "inbound"
      ? await getCachedMailboxMessageTranslationForEmail({
          email: user.email,
          messageId: data.selectedMessage.id,
          targetLocale,
        }).catch(() => null)
      : null;

  return Response.json({
    cachedTranslation,
    ok: notice?.tone !== "error",
    data,
    notice,
  });
}
