"use server";

import { cookies, headers } from "next/headers";
import { redirect } from "next/navigation";
import { getAuthRequestMetadata, recordUserAuthActivity } from "@/lib/auth-activity";
import {
  clearRememberDeviceCookies,
  clearSession,
  configureRememberDevice,
  getMailAuthUrlForCurrentRequest,
  getMailEntryUrlForCurrentRequest,
  getSessionUser,
  revokeAllRememberDevicesByEmail,
  saveSessionUser
} from "@/lib/auth";
import {
  createMailboxSenderMoveRuleByEmail,
  createMailboxFolderByEmail,
  createMailboxMessage,
  createPendingSignupRegistration,
  finalizePendingSignupRegistration,
  getMailSetupOverviewByEmail,
  loginOrCreateUser,
  markMailboxMessagesAsReadByEmail,
  moveMailboxMessagesByEmail,
  provisionMailSetup,
  regenerateMailSetupDkim,
  requestFindIdEmail,
  requestPasswordResetLink,
  refreshMailboxByEmail,
  resetPasswordByToken,
  saveMailboxCredentialsByEmail,
  toggleMailboxMessageStarByEmail,
  updateMailboxSenderSpamRuleByEmail,
  updateMailboxDisplayNameByEmail,
  updateMailSetupDkimUsageByEmail,
  updateRepresentativePasswordByEmail,
  verifyMailSetup
} from "@/lib/official-mail";
import {
  saveAiAssistSettingsByOwnerEmail,
  updateManagedMemberByOwnerEmail
} from "@/lib/mail-automation";
import { saveAutoSendSettingsByOwnerEmail } from "@/lib/mail-auto-send";
import {
  createManagedMemberWithImmediateChargeByOwnerEmail,
  deleteManagedMemberWithBillingByOwnerEmail,
} from "@/lib/mail-member-billing";
import { getPublicMailTransportErrorMessage } from "@/lib/mail-error-messages";
import { canManageMailBillingByEmail } from "@/lib/toss-pay";
import { MARKETING_VISITOR_COOKIE, recordMarketingLifecycleEvent } from "@/lib/marketing-analytics";
import { isValidDomainInput } from "@/lib/domain-input";

function normalizeDomain(input: string) {
  return input
    .trim()
    .toLowerCase()
    .replace(/^https?:\/\//, "")
    .replace(/\/$/, "");
}

function normalizeLocalPart(input: string, domain: string) {
  const normalizedValue = input.trim().replace(/\s+/g, "").toLowerCase();

  if (!normalizedValue) {
    return "";
  }

  if (!normalizedValue.includes("@")) {
    return normalizedValue;
  }

  const [candidateLocalPart, candidateDomain] = normalizedValue.split("@");

  if (!candidateLocalPart || !candidateDomain || candidateDomain !== normalizeDomain(domain)) {
    throw new Error("invalid-local-part");
  }

  return candidateLocalPart;
}

function extractMailcowDetail(message: string) {
  const [prefix, ...rest] = message.split(":");

  if (!prefix.startsWith("mailcow-") || rest.length === 0) {
    return "";
  }

  return rest.join(":").trim().slice(0, 240);
}

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

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

export type RepresentativePasswordActionState = {
  status: "idle" | "success" | "error";
  message: string;
};

export type FindIdActionState = {
  status: "idle" | "success" | "error";
  message: string;
  accountCount?: number;
  attemptId?: number;
  hasSent: boolean;
  maskedRecoveryEmail?: string;
  retryAfterSeconds?: number;
};

export type MailboxDisplayNameActionState = {
  status: "idle" | "success" | "error";
  message: string;
  displayName?: string;
};

function parseUploadIdList(value: FormDataEntryValue | null) {
  return String(value ?? "")
    .split(",")
    .map((item) => Number(item.trim()))
    .filter((item) => Number.isInteger(item) && item > 0);
}

function parseMessageIds(formData: FormData) {
  const rawValue = String(formData.get("messageIds") ?? "").trim();
  const fallbackMessageId = String(formData.get("activeMessageId") ?? "").trim();
  const values = rawValue ? rawValue.split(",") : fallbackMessageId ? [fallbackMessageId] : [];

  return [...new Set(values.map((value) => Number(value)).filter((value) => Number.isInteger(value) && value > 0))];
}

function mailSetupRedirectUrl(query: string, section = "domain") {
  return `/mail?panel=setup&section=${section}${query}`;
}

function mailAutoSendRedirectUrl(query: string) {
  return `/mail?panel=auto-send${query}`;
}

function appendMailboxListContext(params: URLSearchParams, formData: FormData) {
  const page = String(formData.get("page") ?? "").trim();
  const pageSize = String(formData.get("pageSize") ?? "").trim();
  const tab = String(formData.get("tab") ?? "").trim();
  const field = String(formData.get("field") ?? "").trim();
  const query = String(formData.get("q") ?? "").trim();

  if (page) {
    params.set("page", page);
  }

  if (pageSize) {
    params.set("pageSize", pageSize);
  }

  if (tab && tab !== "all") {
    params.set("tab", tab);
  }

  if (query) {
    params.set("q", query);
  }

  if (query && field && field !== "all") {
    params.set("field", field);
  }
}

function appendActiveMessageContext(params: URLSearchParams, formData: FormData) {
  const activeMessageId = String(formData.get("activeMessageId") ?? "").trim();

  if (activeMessageId) {
    params.set("message", activeMessageId);
  }
}

export async function loginAction(formData: FormData) {
  const email = String(formData.get("email") ?? "")
    .trim()
    .toLowerCase();
  const password = String(formData.get("password") ?? "").trim();
  const rememberDevice = formData.get("rememberDevice") === "on";
  let user;

  if (!email || !password) {
    redirect(await getMailAuthUrlForCurrentRequest("/login?error=required"));
  }

  const authRequestMetadata = getAuthRequestMetadata(await headers(), "web");

  try {
    user = await loginOrCreateUser({ email, password });
    await saveSessionUser(user);
    await configureRememberDevice(user.email, rememberDevice);
    await recordUserAuthActivity({
      ...authRequestMetadata,
      eventType: "login",
      identityEmail: email,
      lookup: "login_email",
      outcome: "success"
    });
  } catch (error) {
    const outcome =
      error instanceof Error && error.message === "invalid-password"
        ? "invalid_credentials"
        : error instanceof Error && error.message === "growth-plan-required"
          ? "plan_restricted"
          : "error";
    await recordUserAuthActivity({
      ...authRequestMetadata,
      eventType: "login",
      identityEmail: email,
      lookup: "login_email",
      outcome
    });

    if (error instanceof Error && error.message === "invalid-password") {
      redirect(await getMailAuthUrlForCurrentRequest("/login?error=invalid"));
    }

    if (error instanceof Error && error.message === "growth-plan-required") {
      redirect(await getMailAuthUrlForCurrentRequest("/login?error=growth-plan-required"));
    }

    redirect(await getMailAuthUrlForCurrentRequest("/login?error=system"));
  }

  redirect(await getMailEntryUrlForCurrentRequest(user));
}

export async function signupAction(formData: FormData) {
  const companyName = String(formData.get("companyName") ?? "").trim();
  const domain = normalizeDomain(String(formData.get("domain") ?? ""));
  let localPart = "";
  let user;

  try {
    localPart = normalizeLocalPart(String(formData.get("localPart") ?? "owner"), domain);
  } catch (error) {
    if (error instanceof Error && error.message === "invalid-local-part") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=invalid-local-part"));
    }

    throw error;
  }

  const password = String(formData.get("password") ?? "").trim();
  const passwordConfirm = String(formData.get("passwordConfirm") ?? "").trim();
  const recoveryEmail = String(formData.get("recoveryEmail") ?? "")
    .trim()
    .toLowerCase();
  const recoveryVerificationId = Number(formData.get("recoveryVerificationId") ?? 0);
  const recoveryVerificationToken = String(formData.get("recoveryVerificationToken") ?? "").trim();
  const termsAccepted = formData.get("termsAccepted") === "on";
  const visitorId = (await cookies()).get(MARKETING_VISITOR_COOKIE)?.value ?? null;

  if (!companyName || !domain || !localPart || !password || !passwordConfirm) {
    redirect(await getMailAuthUrlForCurrentRequest("/signup?error=required"));
  }

  if (!isValidDomainInput(domain)) {
    redirect(await getMailAuthUrlForCurrentRequest("/signup?error=invalid-domain"));
  }

  if (!recoveryEmail) {
    redirect(await getMailAuthUrlForCurrentRequest("/signup?error=recovery-email-required"));
  }

  if (!recoveryVerificationId || !recoveryVerificationToken) {
    redirect(await getMailAuthUrlForCurrentRequest("/signup?error=recovery-email-unverified"));
  }

  if (password !== passwordConfirm) {
    redirect(await getMailAuthUrlForCurrentRequest("/signup?error=password-mismatch"));
  }

  if (!termsAccepted) {
    redirect(await getMailAuthUrlForCurrentRequest("/signup?error=terms-required"));
  }

  try {
    const pending = await createPendingSignupRegistration({
      companyName,
      domain,
      localPart,
      password,
      recoveryEmail,
      recoveryVerificationId,
      recoveryVerificationToken,
      termsAccepted
    });
    await recordMarketingLifecycleEvent({
      domainId: pending.domainId,
      eventType: "signup_completed",
      userId: pending.userId,
      visitorId
    });
    user = await finalizePendingSignupRegistration(pending);
    await saveSessionUser(user);
  } catch (error) {
    if (error instanceof Error && error.message === "recovery-email-required") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=recovery-email-required"));
    }

    if (error instanceof Error && error.message === "recovery-email-invalid") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=recovery-email-invalid"));
    }

    if (error instanceof Error && error.message === "recovery-email-unverified") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=recovery-email-unverified"));
    }

    if (error instanceof Error && error.message === "recovery-email-expired") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=recovery-email-expired"));
    }

    if (error instanceof Error && error.message === "email-exists") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=email-exists"));
    }

    if (error instanceof Error && error.message === "domain-taken") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=domain-taken"));
    }

    if (error instanceof Error && error.message === "invalid-local-part") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=invalid-local-part"));
    }

    if (error instanceof Error && error.message === "mailcow-config-missing") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=mail-config"));
    }

    if (error instanceof Error && error.message === "mailcow-config-invalid") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=mail-config"));
    }

    if (error instanceof Error && error.message === "mailcow-auth-failed") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=mail-auth"));
    }

    if (error instanceof Error && error.message === "mailcow-domain-exists") {
      redirect(await getMailAuthUrlForCurrentRequest("/signup?error=mail-domain-exists"));
    }

    if (
      error instanceof Error &&
      (error.message.startsWith("mailcow-provisioning-failed:") || error.message.startsWith("mailcow-request-failed:"))
    ) {
      console.error("Mailcow signup provisioning failed", error);
      const detail = extractMailcowDetail(error.message);
      redirect(
        await getMailAuthUrlForCurrentRequest(
          `/signup?error=mail-setup${detail ? `&details=${encodeURIComponent(detail)}` : ""}`
        )
      );
    }

    redirect(await getMailAuthUrlForCurrentRequest("/signup?error=system"));
  }

  redirect(await getMailEntryUrlForCurrentRequest(user));
}

export async function requestPasswordResetAction(formData: FormData) {
  const email = String(formData.get("email") ?? "")
    .trim()
    .toLowerCase();
  const companyName = String(formData.get("companyName") ?? "").trim();

  if (!email || !companyName) {
    redirect(await getMailAuthUrlForCurrentRequest("/reset-password?error=required"));
  }

  try {
    const mailAppUrl = new URL(await getMailAuthUrlForCurrentRequest("/login")).origin;
    const result = await requestPasswordResetLink({
      companyName,
      email,
      mailAppUrl
    });
    redirect(
      await getMailAuthUrlForCurrentRequest(
        `/reset-password?success=link-sent&masked=${encodeURIComponent(result.maskedRecoveryEmail)}`
      )
    );
  } catch (error) {
    if (error instanceof Error && error.message === "not-found") {
      redirect(await getMailAuthUrlForCurrentRequest("/reset-password?error=not-found"));
    }

    if (error instanceof Error && error.message === "recovery-email-missing") {
      redirect(await getMailAuthUrlForCurrentRequest("/reset-password?error=recovery-email-missing"));
    }

    redirect(await getMailAuthUrlForCurrentRequest("/reset-password?error=system"));
  }
}

export async function requestFindIdAction(
  _previousState: FindIdActionState,
  formData: FormData
): Promise<FindIdActionState> {
  const recoveryEmail = String(formData.get("recoveryEmail") ?? "")
    .trim()
    .toLowerCase();

  if (!recoveryEmail) {
    return {
      status: "error",
      message: "보조 이메일을 입력해주세요.",
      hasSent: _previousState.hasSent
    };
  }

  const authRequestMetadata = getAuthRequestMetadata(await headers(), "web");

  try {
    const loginUrl = await getMailAuthUrlForCurrentRequest("/login");
    const result = await requestFindIdEmail({ recoveryEmail, loginUrl });
    await recordUserAuthActivity({
      ...authRequestMetadata,
      eventType: "find_id",
      identityEmail: recoveryEmail,
      lookup: "recovery_email",
      outcome: "success"
    });

    return {
      status: "success",
      message: "아이디 안내 메일을 보냈습니다.",
      accountCount: result.accountCount,
      hasSent: true,
      maskedRecoveryEmail: result.maskedRecoveryEmail
    };
  } catch (error) {
    const outcome =
      error instanceof Error && error.message === "not-found"
        ? "not_found"
        : error instanceof Error && error.message === "invalid-email"
          ? "invalid_email"
          : error instanceof Error && error.message.startsWith("find-id-rate-limit:")
            ? "rate_limited"
            : "error";
    await recordUserAuthActivity({
      ...authRequestMetadata,
      eventType: "find_id",
      identityEmail: recoveryEmail,
      lookup: "recovery_email",
      outcome
    });

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

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

    if (error instanceof Error && error.message.startsWith("find-id-rate-limit:")) {
      const retryAfterSeconds = Math.max(1, Number(extractErrorDetail(error.message, "find-id-rate-limit:")) || 1);
      return {
        status: "error",
        message: `${retryAfterSeconds}초 뒤 다시 시도해주세요.`,
        attemptId: Date.now(),
        hasSent: _previousState.hasSent,
        retryAfterSeconds
      };
    }

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

export async function completePasswordResetAction(formData: FormData) {
  const token = String(formData.get("token") ?? "").trim();
  const password = String(formData.get("password") ?? "").trim();
  const passwordConfirm = String(formData.get("passwordConfirm") ?? "").trim();
  const encodedToken = encodeURIComponent(token);

  if (!token || !password || !passwordConfirm) {
    redirect(await getMailAuthUrlForCurrentRequest(`/reset-password/${encodedToken}?error=required`));
  }

  if (password !== passwordConfirm) {
    redirect(await getMailAuthUrlForCurrentRequest(`/reset-password/${encodedToken}?error=password-mismatch`));
  }

  try {
    const snapshot = await resetPasswordByToken({ token, password });
    await revokeAllRememberDevicesByEmail(snapshot.email);
    await clearRememberDeviceCookies();
  } catch (error) {
    if (error instanceof Error && error.message === "invalid-token") {
      redirect(await getMailAuthUrlForCurrentRequest(`/reset-password/${encodedToken}?error=invalid-token`));
    }

    if (error instanceof Error && error.message === "used-token") {
      redirect(await getMailAuthUrlForCurrentRequest(`/reset-password/${encodedToken}?error=used-token`));
    }

    if (error instanceof Error && error.message === "expired-token") {
      redirect(await getMailAuthUrlForCurrentRequest(`/reset-password/${encodedToken}?error=expired-token`));
    }

    redirect(await getMailAuthUrlForCurrentRequest(`/reset-password/${encodedToken}?error=system`));
  }

  redirect(await getMailAuthUrlForCurrentRequest("/login?success=password-reset"));
}

export async function logoutAction() {
  await clearSession();
  redirect("https://mail.officialsite.kr/login");
}

export async function completeMailSetupAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const domain = normalizeDomain(String(formData.get("domain") ?? ""));
  const dkimKeySize = formData.get("dkimKeySize") === "1024" ? 1024 : 2048;
  let localPart = "";

  try {
    localPart = normalizeLocalPart(String(formData.get("localPart") ?? "owner"), domain);
  } catch (error) {
    if (error instanceof Error && error.message === "invalid-local-part") {
      redirect(mailSetupRedirectUrl("&error=invalid-local-part"));
    }

    throw error;
  }

  if (!domain || !localPart) {
    redirect(mailSetupRedirectUrl("&error=domain-required"));
  }

  try {
    const snapshot = await provisionMailSetup(user.email, domain, localPart, undefined, dkimKeySize);
    await saveSessionUser(snapshot);
  } catch (error) {
    if (error instanceof Error && error.message === "email-exists") {
      redirect(mailSetupRedirectUrl("&error=mailbox-taken"));
    }

    if (error instanceof Error && error.message === "domain-taken") {
      redirect(mailSetupRedirectUrl("&error=domain-taken"));
    }

    if (error instanceof Error && error.message === "invalid-local-part") {
      redirect(mailSetupRedirectUrl("&error=invalid-local-part"));
    }

    if (error instanceof Error && error.message === "mailbox-auth-missing") {
      redirect(mailSetupRedirectUrl("&error=security-password-required", "account"));
    }

    if (error instanceof Error && error.message === "mailcow-config-missing") {
      redirect(mailSetupRedirectUrl("&error=mail-config"));
    }

    if (error instanceof Error && error.message === "mailcow-config-invalid") {
      redirect(mailSetupRedirectUrl("&error=mail-config"));
    }

    if (error instanceof Error && error.message === "mailcow-auth-failed") {
      redirect(mailSetupRedirectUrl("&error=mail-auth"));
    }

    if (error instanceof Error && error.message === "mailcow-domain-exists") {
      redirect(mailSetupRedirectUrl("&error=mail-domain-exists"));
    }

    if (
      error instanceof Error &&
      (error.message.startsWith("mailcow-provisioning-failed:") || error.message.startsWith("mailcow-request-failed:"))
    ) {
      console.error("Mailcow provisioning failed", error);
      const detail = extractMailcowDetail(error.message);
      redirect(mailSetupRedirectUrl(`&error=mail-setup${detail ? `&details=${encodeURIComponent(detail)}` : ""}`));
    }

    console.error("Mail setup failed", error);
    redirect(mailSetupRedirectUrl("&error=system"));
  }

  redirect(mailSetupRedirectUrl("&success=provisioned"));
}

export async function regenerateMailSetupDkimAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const dkimKeySize = formData.get("dkimKeySize") === "1024" ? 1024 : 2048;

  try {
    const snapshot = await regenerateMailSetupDkim(user.email, dkimKeySize);
    await saveSessionUser(snapshot);
  } catch (error) {
    if (
      error instanceof Error &&
      (error.message === "mailcow-config-missing" || error.message === "mailcow-config-invalid")
    ) {
      redirect(mailSetupRedirectUrl("&error=mail-config"));
    }

    if (error instanceof Error && error.message === "mailcow-auth-failed") {
      redirect(mailSetupRedirectUrl("&error=mail-auth"));
    }

    if (
      error instanceof Error &&
      (error.message.startsWith("mailcow-provisioning-failed:") || error.message.startsWith("mailcow-request-failed:"))
    ) {
      console.error("Mailcow DKIM regeneration failed", error);
      const detail = extractMailcowDetail(error.message);
      redirect(
        mailSetupRedirectUrl(`&error=dkim-regeneration${detail ? `&details=${encodeURIComponent(detail)}` : ""}`)
      );
    }

    console.error("Mail DKIM regeneration failed", error);
    redirect(mailSetupRedirectUrl("&error=dkim-regeneration"));
  }

  redirect(mailSetupRedirectUrl("&success=dkim-regenerated"));
}

export async function updateMailSetupDkimUsageAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const dkimEnabled = String(formData.get("dkimEnabled") ?? "") === "1";

  try {
    const snapshot = await updateMailSetupDkimUsageByEmail(user.email, dkimEnabled);
    await saveSessionUser(snapshot);
  } catch (error) {
    console.error("Mail DKIM usage update failed", error);
    redirect(mailSetupRedirectUrl("&error=dkim-usage"));
  }

  redirect(mailSetupRedirectUrl(`&success=${dkimEnabled ? "dkim-enabled" : "dkim-disabled"}`));
}

export async function updateRepresentativePasswordAction(
  _previousState: RepresentativePasswordActionState,
  formData: FormData
): Promise<RepresentativePasswordActionState> {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const currentPassword = String(formData.get("currentPassword") ?? "").trim();
  const password = String(formData.get("password") ?? "").trim();
  const passwordConfirm = String(formData.get("passwordConfirm") ?? "").trim();

  if (!currentPassword) {
    return {
      status: "error",
      message: "현재 비밀번호를 입력해주세요."
    };
  }

  if (!password || !passwordConfirm) {
    return {
      status: "error",
      message: "새 비밀번호와 확인 값을 모두 입력해주세요."
    };
  }

  if (password !== passwordConfirm) {
    return {
      status: "error",
      message: "비밀번호와 확인 값이 서로 다릅니다."
    };
  }

  try {
    const snapshot = await updateRepresentativePasswordByEmail(user.email, currentPassword, password);
    await revokeAllRememberDevicesByEmail(user.email);
    await clearRememberDeviceCookies();
    await saveSessionUser(snapshot);
  } catch (error) {
    if (error instanceof Error && error.message === "current-password-invalid") {
      return {
        status: "error",
        message: "현재 비밀번호가 올바르지 않습니다."
      };
    }

    if (error instanceof Error && error.message === "mailcow-config-missing") {
      return {
        status: "error",
        message: "메일 서버 연결 설정이 누락되어 있습니다. 관리자에게 문의해주세요."
      };
    }

    if (error instanceof Error && error.message === "mailcow-config-invalid") {
      return {
        status: "error",
        message: "메일 서버 연결 설정이 누락되어 있습니다. 관리자에게 문의해주세요."
      };
    }

    if (error instanceof Error && error.message === "mailcow-auth-failed") {
      return {
        status: "error",
        message: "메일 서버 인증에 실패했습니다. 잠시 후 다시 시도해주세요."
      };
    }

    if (
      error instanceof Error &&
      (error.message.startsWith("mailcow-provisioning-failed:") || error.message.startsWith("mailcow-request-failed:"))
    ) {
      console.error("Mailcow representative password update failed", error);
      const detail = extractMailcowDetail(error.message);
      return {
        status: "error",
        message: detail
          ? `메일함 설정 반영 중 오류가 발생했습니다. ${detail}`
          : "메일함 설정 반영 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요."
      };
    }

    return {
      status: "error",
      message: "비밀번호 변경 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요."
    };
  }

  return {
    status: "success",
    message: "대표 메일 비밀번호를 변경했습니다."
  };
}

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

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  let snapshot;

  try {
    snapshot = await verifyMailSetup(user.email);
    await saveSessionUser(snapshot);
  } catch (error) {
    if (error instanceof Error && error.message === "mailcow-config-missing") {
      redirect(mailSetupRedirectUrl("&error=mail-config"));
    }

    if (error instanceof Error && error.message === "mailcow-config-invalid") {
      redirect(mailSetupRedirectUrl("&error=mail-config"));
    }

    if (error instanceof Error && error.message === "mailcow-auth-failed") {
      redirect(mailSetupRedirectUrl("&error=mail-auth"));
    }

    redirect(mailSetupRedirectUrl("&error=verify-pending"));
  }

  if (!snapshot.mailConfigured) {
    redirect(mailSetupRedirectUrl("&error=verify-pending"));
  }

  const overview = await getMailSetupOverviewByEmail(user.email);
  const requiredDnsMismatch = overview?.dnsRecords.some(
    (record) =>
      !record.host.endsWith("._domainkey") && record.status !== "verified",
  );

  if (requiredDnsMismatch) {
    redirect(mailSetupRedirectUrl("&error=verify-pending"));
  }

  const dkimRecord = overview?.dnsRecords.find((record) =>
    record.host.endsWith("._domainkey"),
  );

  if (overview?.dkimEnabled && dkimRecord?.status !== "verified") {
    redirect(mailSetupRedirectUrl("&success=verified-with-warning"));
  }

  redirect(mailSetupRedirectUrl("&success=verified"));
}

export async function saveAiAssistSettingsAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const enabled = String(formData.get("enabled") ?? "").trim() === "1";
  const notificationEmail = String(formData.get("notificationEmail") ?? "");

  try {
    await saveAiAssistSettingsByOwnerEmail(user.email, {
      enabled,
      notificationEmail
    });
  } catch (error) {
    if (error instanceof Error && error.message === "ai-assist-notification-required") {
      redirect(mailSetupRedirectUrl("&error=ai-assist-notification-required", "assistant"));
    }

    if (error instanceof Error && error.message === "ai-assist-invalid-email") {
      redirect(mailSetupRedirectUrl("&error=ai-assist-invalid-email", "assistant"));
    }

    if (error instanceof Error && error.message === "ai-assist-plan-required") {
      redirect(mailSetupRedirectUrl("&error=ai-assist-plan-required", "assistant"));
    }

    if (
      error instanceof Error &&
      (error.message === "ai-assist-config-missing" ||
        error.message === "mailcow-config-missing" ||
        error.message === "mailcow-config-invalid")
    ) {
      redirect(mailSetupRedirectUrl("&error=ai-assist-config-missing", "assistant"));
    }

    if (error instanceof Error && error.message === "mailcow-auth-failed") {
      redirect(mailSetupRedirectUrl("&error=mail-auth", "assistant"));
    }

    if (
      error instanceof Error &&
      (error.message.startsWith("mailcow-provisioning-failed:") || error.message.startsWith("mailcow-request-failed:"))
    ) {
      const detail = extractMailcowDetail(error.message);
      redirect(
        mailSetupRedirectUrl(`&error=mail-setup${detail ? `&details=${encodeURIComponent(detail)}` : ""}`, "assistant")
      );
    }

    redirect(mailSetupRedirectUrl("&error=system", "assistant"));
  }

  redirect(mailSetupRedirectUrl(enabled ? "&success=ai-assist-saved" : "&success=ai-assist-disabled", "assistant"));
}

function parseAutoSendPayload(value: FormDataEntryValue | null) {
  const raw = String(value ?? "").trim();

  if (!raw) {
    return [];
  }

  const parsed: unknown = JSON.parse(raw);

  if (!Array.isArray(parsed)) {
    throw new Error("auto-send-invalid-payload");
  }

  return parsed;
}

export async function saveAutoSendSettingsAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const enabled = String(formData.get("enabled") ?? "").trim() === "1";
  const randomEnabled = String(formData.get("randomEnabled") ?? "").trim() === "1";
  const subject = String(formData.get("subject") ?? "");
  const sendIntervalPreset = String(formData.get("sendIntervalPreset") ?? "");
  const sendIntervalMinutes = Number(formData.get("sendIntervalMinutes") ?? "");
  const dailySendLimit = Number(formData.get("dailySendLimit") ?? formData.get("maxSendCount") ?? "");
  const sendBatchSize = Number(formData.get("sendBatchSize") ?? "");
  const recipientDuplicateScope = String(formData.get("recipientDuplicateScope") ?? "");

  try {
    const recipientsPayload = parseAutoSendPayload(formData.get("recipientsJson"));
    const phrasesPayload = parseAutoSendPayload(formData.get("phrasesJson"));

    await saveAutoSendSettingsByOwnerEmail(user.email, {
      enabled,
      phrases: phrasesPayload.map((item) => {
        const row = item as {
          active?: unknown;
          bodyText?: unknown;
          selected?: unknown;
          subjectText?: unknown;
        };

        return {
          active: row.active !== false,
          bodyText: String(row.bodyText ?? ""),
          selected: row.selected !== false,
          subjectText: String(row.subjectText ?? "")
        };
      }),
      randomEnabled,
      recipientDuplicateScope,
      recipients: recipientsPayload.map((item) => {
        const row = item as {
          active?: unknown;
          displayName?: unknown;
          email?: unknown;
        };

        return {
          active: row.active !== false,
          displayName: String(row.displayName ?? ""),
          email: String(row.email ?? "")
        };
      }),
      sendIntervalMinutes,
      sendIntervalPreset,
      dailySendLimit,
      sendBatchSize,
      subject
    });
  } catch (error) {
    if (error instanceof Error) {
      if (error.message === "auto-send-invalid-payload" || error.message === "auto-send-invalid-date") {
        redirect(mailAutoSendRedirectUrl("&error=auto-send-invalid"));
      }

      if (error.message === "auto-send-invalid-email") {
        redirect(mailAutoSendRedirectUrl("&error=auto-send-invalid-email"));
      }

      if (
        error.message === "auto-send-subject-required" ||
        error.message === "auto-send-recipient-required" ||
        error.message === "auto-send-phrase-required" ||
        error.message === "auto-send-random-phrase-required"
      ) {
        redirect(mailAutoSendRedirectUrl("&error=auto-send-required"));
      }

      if (error.message === "auto-send-plan-required") {
        redirect(mailAutoSendRedirectUrl("&error=auto-send-plan-required"));
      }
    }

    redirect(mailAutoSendRedirectUrl("&error=system"));
  }

  redirect(mailAutoSendRedirectUrl(enabled ? "&success=auto-send-saved" : "&success=auto-send-disabled"));
}

export async function createManagedMemberAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  if (!(await canManageMailBillingByEmail(user.email))) {
    redirect(mailSetupRedirectUrl("&error=member-management-forbidden", "account"));
  }

  const displayName = String(formData.get("displayName") ?? "");
  const localPart = String(formData.get("localPart") ?? "");
  const password = String(formData.get("password") ?? "");
  const passwordConfirm = String(formData.get("passwordConfirm") ?? "");

  if (password.trim() !== passwordConfirm.trim()) {
    redirect(mailSetupRedirectUrl("&error=member-password-mismatch", "members"));
  }

  try {
    await createManagedMemberWithImmediateChargeByOwnerEmail(user.email, {
      displayName,
      localPart,
      password
    });
  } catch (error) {
    if (error instanceof Error && error.message === "member-required") {
      redirect(mailSetupRedirectUrl("&error=member-required", "members"));
    }

    if (error instanceof Error && error.message === "invalid-local-part") {
      redirect(mailSetupRedirectUrl("&error=invalid-local-part", "members"));
    }

    if (error instanceof Error && error.message === "member-mailbox-taken") {
      redirect(mailSetupRedirectUrl("&error=member-mailbox-taken", "members"));
    }

    if (error instanceof Error && error.message === "growth-plan-required") {
      redirect(mailSetupRedirectUrl("&error=member-plan-required", "members"));
    }

    if (error instanceof Error && error.message === "billing-profile-inactive") {
      redirect(mailSetupRedirectUrl("&error=member-billing-inactive", "members"));
    }

    if (error instanceof Error && error.message === "member-charge-failed") {
      redirect(mailSetupRedirectUrl("&error=member-charge-failed", "members"));
    }

    if (error instanceof Error && error.message === "member-create-refunded") {
      redirect(mailSetupRedirectUrl("&error=member-create-refunded", "members"));
    }

    if (error instanceof Error && error.message === "member-charge-refund-failed") {
      redirect(mailSetupRedirectUrl("&error=member-charge-refund-failed", "members"));
    }

    if (error instanceof Error && error.message === "mailcow-auth-failed") {
      redirect(mailSetupRedirectUrl("&error=mail-auth", "members"));
    }

    if (
      error instanceof Error &&
      (error.message.startsWith("mailcow-provisioning-failed:") || error.message.startsWith("mailcow-request-failed:"))
    ) {
      const detail = extractMailcowDetail(error.message);
      redirect(
        mailSetupRedirectUrl(`&error=mail-setup${detail ? `&details=${encodeURIComponent(detail)}` : ""}`, "members")
      );
    }

    redirect(mailSetupRedirectUrl("&error=system", "members"));
  }

  redirect(mailSetupRedirectUrl("&success=member-created", "members"));
}

export async function updateManagedMemberAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  if (!(await canManageMailBillingByEmail(user.email))) {
    redirect(mailSetupRedirectUrl("&error=member-management-forbidden", "account"));
  }

  const memberId = Number(String(formData.get("memberId") ?? "").trim());
  const displayName = String(formData.get("displayName") ?? "");
  const password = String(formData.get("password") ?? "");
  const passwordConfirm = String(formData.get("passwordConfirm") ?? "");

  if (password.trim() && password.trim() !== passwordConfirm.trim()) {
    redirect(mailSetupRedirectUrl("&error=member-password-mismatch", "members"));
  }

  try {
    await updateManagedMemberByOwnerEmail(user.email, {
      displayName,
      memberId,
      password
    });
  } catch (error) {
    if (error instanceof Error && error.message === "member-required") {
      redirect(mailSetupRedirectUrl("&error=member-required", "members"));
    }

    if (error instanceof Error && error.message === "member-not-found") {
      redirect(mailSetupRedirectUrl("&error=member-not-found", "members"));
    }

    if (error instanceof Error && error.message === "mailbox-auth-missing") {
      redirect(mailSetupRedirectUrl("&error=security-password-required", "members"));
    }

    if (error instanceof Error && error.message === "mailcow-auth-failed") {
      redirect(mailSetupRedirectUrl("&error=mail-auth", "members"));
    }

    if (
      error instanceof Error &&
      (error.message.startsWith("mailcow-provisioning-failed:") || error.message.startsWith("mailcow-request-failed:"))
    ) {
      const detail = extractMailcowDetail(error.message);
      redirect(
        mailSetupRedirectUrl(`&error=mail-setup${detail ? `&details=${encodeURIComponent(detail)}` : ""}`, "members")
      );
    }

    redirect(mailSetupRedirectUrl("&error=system", "members"));
  }

  redirect(mailSetupRedirectUrl("&success=member-updated", "members"));
}

export async function deleteManagedMemberAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  if (!(await canManageMailBillingByEmail(user.email))) {
    redirect(mailSetupRedirectUrl("&error=member-management-forbidden", "account"));
  }

  const memberId = Number(String(formData.get("memberId") ?? "").trim());

  try {
    await deleteManagedMemberWithBillingByOwnerEmail(user.email, memberId);
  } catch (error) {
    if (error instanceof Error && error.message === "member-not-found") {
      redirect(mailSetupRedirectUrl("&error=member-not-found", "members"));
    }

    if (error instanceof Error && error.message === "mailcow-auth-failed") {
      redirect(mailSetupRedirectUrl("&error=mail-auth", "members"));
    }

    if (
      error instanceof Error &&
      (error.message.startsWith("mailcow-provisioning-failed:") || error.message.startsWith("mailcow-request-failed:"))
    ) {
      const detail = extractMailcowDetail(error.message);
      redirect(
        mailSetupRedirectUrl(`&error=mail-setup${detail ? `&details=${encodeURIComponent(detail)}` : ""}`, "members")
      );
    }

    redirect(mailSetupRedirectUrl("&error=system", "members"));
  }

  redirect(mailSetupRedirectUrl("&success=member-deleted", "members"));
}

export async function submitMailboxMessageAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const to = String(formData.get("to") ?? "");
  const cc = String(formData.get("cc") ?? "");
  const bcc = String(formData.get("bcc") ?? "");
  const subject = String(formData.get("subject") ?? "");
  const body = String(formData.get("body") ?? "");
  const bodyHtml = String(formData.get("bodyHtml") ?? "");
  const sendIndividually = String(formData.get("sendIndividually") ?? "") === "1";
  const attachmentUploadIds = parseUploadIdList(formData.get("attachmentUploadIds"));
  const attachmentFiles = formData.getAll("attachmentFiles").filter((entry): entry is File => entry instanceof File);
  const inlineImageUploadIds = parseUploadIdList(formData.get("inlineImageUploadIds"));
  const intent = String(formData.get("intent") ?? "send") === "draft" ? "draft" : "send";
  const sourceDraftMessageIdValue = Number(String(formData.get("sourceDraftMessageId") ?? ""));
  const sourceDraftMessageId =
    Number.isInteger(sourceDraftMessageIdValue) && sourceDraftMessageIdValue > 0 ? sourceDraftMessageIdValue : null;
  let result;

  try {
    result = await createMailboxMessage(user.email, {
      attachmentUploadIds,
      bcc,
      body,
      bodyHtml,
      cc,
      inlineImageUploadIds,
      intent,
      rawAttachmentFiles: await Promise.all(
        attachmentFiles.map(async (file) => ({
          buffer: Buffer.from(await file.arrayBuffer()),
          contentType: file.type || "application/octet-stream",
          filename: file.name || "attachment",
          sizeBytes: file.size
        }))
      ),
      sendIndividually,
      sourceDraftMessageId,
      subject,
      to
    });
  } catch (error) {
    if (error instanceof Error && error.message === "compose-required") {
      redirect("/mail?view=compose&error=compose-required");
    }

    if (error instanceof Error && error.message === "invalid-recipient") {
      redirect("/mail?view=compose&error=invalid-recipient");
    }

    if (
      error instanceof Error &&
      (error.message === "mailbox-auth-missing" || error.message === "mailbox-auth-invalid")
    ) {
      redirect("/mail?view=compose&error=mailbox-auth");
    }

    if (error instanceof Error && error.message === "free-send-limit-daily") {
      redirect("/mail?view=compose&error=free-send-limit-daily");
    }

    if (error instanceof Error && error.message.startsWith("send-cooldown-active:")) {
      const detail = extractErrorDetail(error.message, "send-cooldown-active:");
      redirect(
        `/mail?view=compose&error=send-cooldown-active${detail ? `&details=${encodeURIComponent(detail)}` : ""}`
      );
    }

    if (error instanceof Error && error.message.startsWith("mailbox-smtp-failed:")) {
      const detail = getPublicMailTransportErrorMessage(error.message, "smtp");
      redirect(`/mail?view=compose&error=smtp-failed${detail ? `&details=${encodeURIComponent(detail)}` : ""}`);
    }

    if (error instanceof Error && error.message.startsWith("mailbox-imap-failed:")) {
      const detail = getPublicMailTransportErrorMessage(error.message, "imap");
      redirect(`/mail?view=compose&error=imap-failed${detail ? `&details=${encodeURIComponent(detail)}` : ""}`);
    }

    redirect("/mail?view=compose&error=compose-failed");
  }

  const params = new URLSearchParams();
  params.set("folder", result.folder);
  params.set("success", result.success);

  if (result.messageId) {
    params.set("message", String(result.messageId));
  }

  redirect(`/mail?${params.toString()}`);
}

export async function refreshMailboxAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const folder = String(formData.get("folder") ?? "inbox").trim() || "inbox";
  const message = String(formData.get("message") ?? "").trim();
  const detail = String(formData.get("detail") ?? "").trim();
  const view = String(formData.get("view") ?? "").trim();
  const params = new URLSearchParams();

  params.set("folder", folder);

  if (message) {
    params.set("message", message);
  }

  if (detail) {
    params.set("detail", detail);
  }

  if (view === "compose") {
    params.set("view", "compose");
  }

  appendMailboxListContext(params, formData);

  try {
    await refreshMailboxByEmail(user.email, { folder, fullMetadata: true });
    params.set("success", "refresh");
  } catch (error) {
    if (
      error instanceof Error &&
      (error.message === "mailbox-auth-missing" || error.message === "mailbox-auth-invalid")
    ) {
      params.set("error", "mailbox-auth");
      redirect(`/mail?${params.toString()}`);
    }

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

      if (detailMessage) {
        params.set("details", detailMessage);
      }

      redirect(`/mail?${params.toString()}`);
    }

    params.set("error", "refresh-failed");
  }

  redirect(`/mail?${params.toString()}`);
}

export async function saveMailboxCredentialsAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const folder = String(formData.get("folder") ?? "inbox").trim() || "inbox";
  const message = String(formData.get("message") ?? "").trim();
  const detail = String(formData.get("detail") ?? "").trim();
  const view = String(formData.get("view") ?? "").trim();
  const mailboxPassword = String(formData.get("mailboxPassword") ?? "");
  const params = new URLSearchParams();

  params.set("folder", folder);

  if (message) {
    params.set("message", message);
  }

  if (detail) {
    params.set("detail", detail);
  }

  if (view === "compose") {
    params.set("view", "compose");
  }

  appendMailboxListContext(params, formData);

  try {
    await saveMailboxCredentialsByEmail(user.email, mailboxPassword, {
      folder
    });
    params.set("success", "mailbox-connected");
  } catch (error) {
    if (error instanceof Error && error.message === "mailbox-password-required") {
      params.set("error", "mailbox-password-required");
      redirect(`/mail?${params.toString()}`);
    }

    if (error instanceof Error && error.message === "mailbox-password-must-differ") {
      params.set("error", "mailbox-password-must-differ");
      redirect(`/mail?${params.toString()}`);
    }

    if (
      error instanceof Error &&
      (error.message === "mailbox-auth-missing" || error.message === "mailbox-auth-invalid")
    ) {
      params.set("error", "mailbox-auth");
      redirect(`/mail?${params.toString()}`);
    }

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

      if (detailMessage) {
        params.set("details", detailMessage);
      }

      redirect(`/mail?${params.toString()}`);
    }

    params.set("error", "mailbox-connection-failed");
  }

  redirect(`/mail?${params.toString()}`);
}

export async function updateMailboxDisplayNameAction(
  _previousState: MailboxDisplayNameActionState,
  formData: FormData
): Promise<MailboxDisplayNameActionState> {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const displayName = String(formData.get("displayName") ?? "")
    .replace(/\s+/g, " ")
    .trim();

  if (!displayName) {
    return {
      status: "error",
      message: "표시 이름을 입력해주세요."
    };
  }

  if (displayName.length > 191) {
    return {
      status: "error",
      message: "표시 이름은 191자 이내로 입력해주세요."
    };
  }

  try {
    const snapshot = await updateMailboxDisplayNameByEmail(user.email, displayName);
    await saveSessionUser(snapshot);
  } catch (error) {
    if (error instanceof Error && error.message === "user-not-found") {
      return {
        status: "error",
        message: "계정 정보를 찾지 못했습니다. 다시 로그인한 뒤 시도해주세요."
      };
    }

    if (
      error instanceof Error &&
      (error.message === "mailcow-config-missing" ||
        error.message === "mailcow-config-invalid" ||
        error.message === "mailcow-auth-failed")
    ) {
      return {
        status: "error",
        message: "메일 서버 설정을 반영하지 못했습니다. 잠시 후 다시 시도해주세요."
      };
    }

    if (
      error instanceof Error &&
      (error.message.startsWith("mailcow-provisioning-failed:") || error.message.startsWith("mailcow-request-failed:"))
    ) {
      const detail = extractMailcowDetail(error.message);
      return {
        status: "error",
        message: detail
          ? `메일함 표시 이름을 반영하지 못했습니다. ${detail}`
          : "메일함 표시 이름을 반영하지 못했습니다. 잠시 후 다시 시도해주세요."
      };
    }

    console.error("Mailbox display name update failed", error);
    return {
      status: "error",
      message: "표시 이름을 변경하지 못했습니다. 잠시 후 다시 시도해주세요."
    };
  }

  return {
    status: "success",
    message: "표시 이름을 저장했습니다. 이후 보내는 메일부터 적용됩니다.",
    displayName
  };
}

export async function markMailboxMessagesReadAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const folder = String(formData.get("folder") ?? "inbox").trim() || "inbox";
  const detail = String(formData.get("detail") ?? "").trim();
  const message = String(formData.get("message") ?? "").trim();
  const readState = String(formData.get("readState") ?? "read")
    .trim()
    .toLowerCase();
  const nextReadState = readState !== "unread";
  const params = new URLSearchParams();
  const messageIds = parseMessageIds(formData);

  params.set("folder", folder);

  if (detail) {
    params.set("detail", detail);
  }

  if (message) {
    params.set("message", message);
  }

  appendMailboxListContext(params, formData);

  if (messageIds.length === 0) {
    redirect(`/mail?${params.toString()}`);
  }

  try {
    await markMailboxMessagesAsReadByEmail(user.email, messageIds, nextReadState);
    params.set("success", nextReadState ? "mark-read" : "mark-unread");
  } catch (error) {
    const detailMessage = error instanceof Error ? error.message : "mailbox read action failed";
    params.set("error", "read-failed");
    params.set("details", detailMessage.slice(0, 180));
  }

  redirect(`/mail?${params.toString()}`);
}

export async function toggleMailboxMessageStarAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const folder = String(formData.get("folder") ?? "inbox").trim() || "inbox";
  const detail = String(formData.get("detail") ?? "").trim();
  const message = String(formData.get("message") ?? "").trim();
  const messageId = Number(String(formData.get("messageId") ?? "").trim());
  const params = new URLSearchParams();

  params.set("folder", folder);

  if (detail) {
    params.set("detail", detail);
  }

  if (message) {
    params.set("message", message);
  }

  appendMailboxListContext(params, formData);

  if (!Number.isInteger(messageId) || messageId <= 0) {
    params.set("error", "star-failed");
    redirect(`/mail?${params.toString()}`);
  }

  try {
    await toggleMailboxMessageStarByEmail(user.email, messageId);
  } catch (error) {
    const detailMessage = error instanceof Error ? error.message : "mailbox star action failed";
    params.set("error", "star-failed");
    params.set("details", detailMessage.slice(0, 180));
  }

  redirect(`/mail?${params.toString()}`);
}

export async function moveMailboxMessagesAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const sourceFolder = String(formData.get("folder") ?? "inbox").trim() || "inbox";
  const detail = String(formData.get("detail") ?? "").trim();
  const messageIds = parseMessageIds(formData);
  const requestedTargetFolder = String(formData.get("targetFolder") ?? "").trim();
  const newFolderName = String(formData.get("newFolderName") ?? "").trim();
  const continueMove = String(formData.get("continueMove") ?? "").trim() === "1";
  const moveExistingMessages = String(formData.get("moveExistingMessages") ?? "").trim() === "1";
  const releaseSpam = String(formData.get("releaseSpam") ?? "").trim() === "1";
  const params = new URLSearchParams();

  if (detail) {
    params.set("detail", detail);
  }

  appendMailboxListContext(params, formData);

  if (messageIds.length === 0) {
    params.set("folder", sourceFolder);
    redirect(`/mail?${params.toString()}`);
  }

  try {
    let targetFolder = requestedTargetFolder;

    if ((!targetFolder || targetFolder === "__new__") && newFolderName) {
      const createdFolder = await createMailboxFolderByEmail(user.email, newFolderName);
      targetFolder = createdFolder.systemName;
    }

    if (!targetFolder) {
      targetFolder = "trash";
    }

    const moveResult = continueMove
      ? await createMailboxSenderMoveRuleByEmail(user.email, messageIds, targetFolder, { moveExistingMessages })
      : await moveMailboxMessagesByEmail(user.email, messageIds, targetFolder, {
          releaseSpam,
          sourceFolder
        });
    params.set("folder", continueMove ? sourceFolder : targetFolder);
    params.set(
      "success",
      continueMove
        ? moveExistingMessages
          ? "move-rule-existing"
          : "move-rule"
        : releaseSpam
          ? "move-unspam"
          : targetFolder === "spam"
            ? "move-spam"
            : targetFolder === "trash"
              ? moveResult.deletedCount > 0 && moveResult.movedCount > 0
                ? "move-trash-delete"
                : moveResult.deletedCount > 0
                  ? "delete-permanent"
                  : "move-trash"
              : "move-folder"
    );
  } catch (error) {
    const detailMessage = error instanceof Error ? error.message : "mailbox move action failed";
    params.set("folder", sourceFolder);
    if (detailMessage === "sent-folder-only-outbound") {
      params.set("error", "move-sent-only");
    } else if (
      detailMessage === "mailbox-move-failed" ||
      detailMessage === "mailbox-delete-failed" ||
      detailMessage.includes("Duplicate entry")
    ) {
      params.set("error", "move-conflict");
    } else if (detailMessage === "folder-name-required") {
      params.set("error", "folder-name-required");
    } else if (detailMessage === "folder-name-exists") {
      params.set("error", "folder-name-exists");
    } else if (detailMessage === "continue-move-custom-folder-only") {
      params.set("error", "continue-move-custom-folder-only");
    } else if (detailMessage === "continue-move-requires-one-sender") {
      params.set("error", "continue-move-requires-one-sender");
    } else {
      params.set("error", "move-failed");
    }
  }

  redirect(`/mail?${params.toString()}`);
}

export async function updateMailboxSenderSpamRuleAction(formData: FormData) {
  const user = await getSessionUser();

  if (!user) {
    redirect(await getMailAuthUrlForCurrentRequest("/login"));
  }

  const senderAddress = String(formData.get("senderAddress") ?? "")
    .trim()
    .toLowerCase();
  const sourceFolder = String(formData.get("folder") ?? "inbox").trim() || "inbox";
  const detail = String(formData.get("detail") ?? "").trim();
  const mode = String(formData.get("mode") ?? "spam").trim();
  const moveExistingMessages = String(formData.get("moveExistingMessages") ?? "").trim() === "1";
  const requestedTargetFolder = String(formData.get("targetFolder") ?? "").trim();
  const newFolderName = String(formData.get("newFolderName") ?? "").trim();
  const params = new URLSearchParams();

  if (detail) {
    params.set("detail", detail);
  }

  appendMailboxListContext(params, formData);
  appendActiveMessageContext(params, formData);

  if (!senderAddress) {
    params.set("folder", sourceFolder);
    params.set("error", "sender-spam-failed");
    redirect(`/mail?${params.toString()}`);
  }

  try {
    let targetFolder = requestedTargetFolder;

    if (mode === "unspam" && moveExistingMessages && (!targetFolder || targetFolder === "__new__") && newFolderName) {
      const createdFolder = await createMailboxFolderByEmail(user.email, newFolderName);
      targetFolder = createdFolder.systemName;
    }

    if (mode === "unspam") {
      await updateMailboxSenderSpamRuleByEmail(user.email, senderAddress, {
        enabled: false,
        moveExistingMessages,
        targetFolder: moveExistingMessages ? targetFolder || "inbox" : undefined
      });
      params.set("folder", moveExistingMessages ? targetFolder || "inbox" : sourceFolder);
      params.set("success", moveExistingMessages ? "sender-unspam-moved" : "sender-unspam");
    } else {
      await updateMailboxSenderSpamRuleByEmail(user.email, senderAddress, {
        enabled: true
      });
      params.set("folder", "spam");
      params.set("success", "sender-spam");
    }
  } catch (error) {
    const detailMessage = error instanceof Error ? error.message : "sender-spam-rule-failed";
    params.set("folder", sourceFolder);

    if (detailMessage === "folder-name-required") {
      params.set("error", "folder-name-required");
    } else if (detailMessage === "sent-folder-only-outbound") {
      params.set("error", "move-sent-only");
    } else {
      params.set("error", "sender-spam-failed");
      params.set("details", detailMessage.slice(0, 180));
    }
  }

  redirect(`/mail?${params.toString()}`);
}
