import { buildRequestDescriptor, handleHttpError } from "./http.js";

export async function requestJson(pathname, options = {}) {
  const descriptor = buildRequestDescriptor(options.method || "GET", pathname, options);
  const init = {
    method: descriptor.method,
    headers: descriptor.headers,
    credentials: "same-origin",
  };

  if (options.body != null) {
    init.body = typeof options.body === "string" ? options.body : JSON.stringify(options.body);
  }

  const response = await fetch(descriptor.url, init);
  let payload = null;
  try {
    payload = await response.json();
  } catch (error) {
    payload = null;
  }

  if (!response.ok) {
    handleHttpError(response.status);
    const message = payload && (payload.message || payload.error) ? (payload.message || payload.error) : "Request failed";
    const err = new Error(message);
    err.status = response.status;
    err.payload = payload;
    throw err;
  }

  return payload;
}

export function normalizePagination(payload) {
  const pagination = payload && payload.pagination ? payload.pagination : {};
  return {
    current: Number(pagination.current || 1),
    last_page: Number(pagination.last_page || 1),
    per_page: Number(pagination.per_page || 20),
    total: Number(pagination.total || 0),
  };
}

export function formatCurrencyFen(value) {
  const amount = Number(value || 0) / 100;
  return `¥${amount.toFixed(2)}`;
}

export function formatBytes(value) {
  let size = Number(value || 0);
  const units = ["B", "KB", "MB", "GB", "TB"];
  let index = 0;

  while (size >= 1024 && index < units.length - 1) {
    size /= 1024;
    index += 1;
  }

  return `${size.toFixed(size >= 100 || index === 0 ? 0 : 1)} ${units[index]}`;
}

export function formatUnixSeconds(value) {
  const seconds = Number(value || 0);
  if (!seconds) {
    return "-";
  }
  const date = new Date(seconds * 1000);
  if (Number.isNaN(date.getTime())) {
    return "-";
  }
  return date.toLocaleString();
}

export function unixToDatetimeLocal(value) {
  const seconds = Number(value || 0);
  if (!seconds) {
    return "";
  }
  const date = new Date(seconds * 1000);
  const pad = (num) => String(num).padStart(2, "0");
  return [
    date.getFullYear(),
    "-",
    pad(date.getMonth() + 1),
    "-",
    pad(date.getDate()),
    "T",
    pad(date.getHours()),
    ":",
    pad(date.getMinutes()),
  ].join("");
}

export function datetimeLocalToUnix(value) {
  if (!value) {
    return null;
  }
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return null;
  }
  return Math.floor(date.getTime() / 1000);
}

export function compactText(value) {
  return String(value == null ? "" : value).trim();
}
