export const MAIL_BILLING_HISTORY_PAGE_SIZE = 10;

export type MailBillingTab = "overview" | "history";
export type MailBillingHistoryRangePreset =
  | "7d"
  | "30d"
  | "90d"
  | "180d"
  | "365d"
  | "all"
  | "custom";

export type MailBillingHistoryState = {
  from: string | null;
  page: number;
  rangePreset: MailBillingHistoryRangePreset;
  to: string | null;
};

export const MAIL_BILLING_HISTORY_QUICK_RANGES: Array<{
  id: Exclude<MailBillingHistoryRangePreset, "custom">;
  label: string;
}> = [
  { id: "7d", label: "7일" },
  { id: "30d", label: "30일" },
  { id: "90d", label: "3개월" },
  { id: "180d", label: "6개월" },
  { id: "365d", label: "1년" },
  { id: "all", label: "전체" },
];

function formatLocalDateInputValue(value: Date) {
  const year = value.getFullYear();
  const month = String(value.getMonth() + 1).padStart(2, "0");
  const date = String(value.getDate()).padStart(2, "0");
  return `${year}-${month}-${date}`;
}

function normalizeDateInput(value: string | null | undefined) {
  const trimmed = value?.trim() ?? "";

  if (!/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
    return null;
  }

  const [year, month, date] = trimmed.split("-").map(Number);
  const normalized = new Date(year, month - 1, date);

  if (
    normalized.getFullYear() !== year ||
    normalized.getMonth() !== month - 1 ||
    normalized.getDate() !== date
  ) {
    return null;
  }

  return trimmed;
}

function startOfLocalDay(value: Date) {
  return new Date(value.getFullYear(), value.getMonth(), value.getDate());
}

function subtractDays(value: Date, days: number) {
  const next = new Date(value);
  next.setDate(next.getDate() - days);
  return next;
}

function resolvePresetRange(
  preset: Exclude<MailBillingHistoryRangePreset, "all" | "custom">,
  now: Date,
) {
  const daysByPreset = {
    "7d": 7,
    "30d": 30,
    "90d": 90,
    "180d": 180,
    "365d": 365,
  } satisfies Record<Exclude<MailBillingHistoryRangePreset, "all" | "custom">, number>;
  const today = startOfLocalDay(now);
  const from = subtractDays(today, daysByPreset[preset] - 1);

  return {
    from: formatLocalDateInputValue(from),
    to: formatLocalDateInputValue(today),
  };
}

export function pickMailBillingTab(value: string | string[] | undefined): MailBillingTab {
  const picked = Array.isArray(value) ? value[0] : value;
  return picked === "history" ? "history" : "overview";
}

export function pickMailBillingHistoryRangePreset(
  value: string | string[] | undefined,
): MailBillingHistoryRangePreset {
  const picked = Array.isArray(value) ? value[0] : value;

  if (
    picked === "7d" ||
    picked === "30d" ||
    picked === "90d" ||
    picked === "180d" ||
    picked === "365d" ||
    picked === "custom"
  ) {
    return picked;
  }

  return "all";
}

export function pickMailBillingHistoryPage(value: string | string[] | undefined) {
  const picked = Number(Array.isArray(value) ? value[0] : value ?? "1");

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

  return Math.floor(picked);
}

export function resolveMailBillingHistoryState(input: {
  from?: string | null;
  now?: Date;
  page?: number;
  rangePreset?: MailBillingHistoryRangePreset;
  to?: string | null;
}): MailBillingHistoryState {
  const page =
    typeof input.page === "number" && Number.isFinite(input.page) && input.page > 0
      ? Math.floor(input.page)
      : 1;
  const rangePreset = input.rangePreset ?? "all";
  const now = input.now ?? new Date();

  if (
    rangePreset === "7d" ||
    rangePreset === "30d" ||
    rangePreset === "90d" ||
    rangePreset === "180d" ||
    rangePreset === "365d"
  ) {
    const resolved = resolvePresetRange(rangePreset, now);

    return {
      from: resolved.from,
      page,
      rangePreset,
      to: resolved.to,
    };
  }

  if (rangePreset === "all") {
    return {
      from: null,
      page,
      rangePreset,
      to: null,
    };
  }

  let from = normalizeDateInput(input.from);
  let to = normalizeDateInput(input.to);

  if (from && to && from > to) {
    [from, to] = [to, from];
  }

  if (!from && !to) {
    return {
      from: null,
      page,
      rangePreset: "all",
      to: null,
    };
  }

  return {
    from,
    page,
    rangePreset: "custom",
    to,
  };
}

export function buildMailBillingSetupHref(input: {
  from?: string | null;
  now?: Date;
  page?: number;
  rangePreset?: MailBillingHistoryRangePreset;
  tab?: MailBillingTab;
  to?: string | null;
}) {
  const tab = input.tab ?? "overview";
  const resolved = resolveMailBillingHistoryState({
    from: input.from,
    now: input.now,
    page: input.page,
    rangePreset: input.rangePreset,
    to: input.to,
  });
  const params = new URLSearchParams({
    panel: "setup",
    section: "billing",
  });

  if (tab === "history") {
    params.set("billingTab", "history");
  }

  if (resolved.page > 1) {
    params.set("billingPage", String(resolved.page));
  }

  if (resolved.rangePreset !== "all") {
    params.set("billingRange", resolved.rangePreset);
  }

  if (resolved.from) {
    params.set("billingFrom", resolved.from);
  }

  if (resolved.to) {
    params.set("billingTo", resolved.to);
  }

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