const MERCHANT_TOKEN_KEY = "merchant_token";
const MERCHANT_ID_KEY = "merchant_id";
const MERCHANT_USER_KEY = "merchant_user";
const MERCHANT_AUTH_MODE_KEY = "merchant_auth_mode";

function merchantFormatMoney(value) {
  const number = Number(value || 0);
  if (!Number.isFinite(number)) {
    return "Rp 0";
  }
  return new Intl.NumberFormat("id-ID", {
    style: "currency",
    currency: "IDR",
    maximumFractionDigits: 0
  }).format(number);
}

function merchantFormatDateTime(value) {
  if (!value) {
    return "-";
  }
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return value;
  }
  return new Intl.DateTimeFormat("en-GB", {
    dateStyle: "medium",
    timeStyle: "short"
  }).format(date);
}

function merchantBuildQuery(query) {
  const search = new URLSearchParams();
  Object.entries(query || {}).forEach(([key, val]) => {
    if (val !== undefined && val !== null && val !== "") {
      search.append(key, String(val));
    }
  });
  return search.toString();
}

async function merchantFetch(path, options = {}) {
  const token = localStorage.getItem(MERCHANT_TOKEN_KEY);
  const merchantId = localStorage.getItem(MERCHANT_ID_KEY);
  const {
    method = "GET",
    query,
    body,
    headers: extraHeaders = {},
    auth = true
  } = options;
  const suffix = merchantBuildQuery(query || {});
  const headers = { ...extraHeaders };

  if (auth) {
    if (!token) {
      throw new Error("MERCHANT_AUTH_MISSING");
    }
    headers.Authorization = `Bearer ${token}`;
    if (merchantId) {
      headers["X-Merchant-Id"] = merchantId;
    }
  }
  if (method !== "GET" && body !== undefined) {
    headers["Content-Type"] = "application/json";
  }

  const response = await fetch(suffix ? `${path}?${suffix}` : path, {
    method,
    headers,
    body: method === "GET" || body === undefined ? undefined : JSON.stringify(body)
  });
  const raw = await response.text();
  let payload;
  try {
    payload = raw ? JSON.parse(raw) : {};
  } catch (error) {
    payload = {};
  }
  if (!response.ok) {
    throw new Error(payload?.message || payload?.error || `Request failed with status ${response.status}`);
  }
  return payload?.data !== undefined ? payload.data : payload;
}

window.MerchantUIAPI = {
  MERCHANT_TOKEN_KEY,
  MERCHANT_ID_KEY,
  setSession: ({ token, merchant, user, auth_mode }) => {
    localStorage.setItem(MERCHANT_TOKEN_KEY, token);
    localStorage.setItem(MERCHANT_ID_KEY, merchant.id);
    if (user) {
      localStorage.setItem(MERCHANT_USER_KEY, JSON.stringify(user));
    }
    if (auth_mode) {
      localStorage.setItem(MERCHANT_AUTH_MODE_KEY, auth_mode);
    }
  },
  clearSession: () => {
    localStorage.removeItem(MERCHANT_TOKEN_KEY);
    localStorage.removeItem(MERCHANT_ID_KEY);
    localStorage.removeItem(MERCHANT_USER_KEY);
    localStorage.removeItem(MERCHANT_AUTH_MODE_KEY);
  },
  getSessionUser: () => {
    try {
      return JSON.parse(localStorage.getItem(MERCHANT_USER_KEY) || "null");
    } catch (_error) {
      return null;
    }
  },
  getAuthMode: () => localStorage.getItem(MERCHANT_AUTH_MODE_KEY),
  requireSession: () => {
    const token = localStorage.getItem(MERCHANT_TOKEN_KEY);
    const merchantId = localStorage.getItem(MERCHANT_ID_KEY);
    if (!token || !merchantId) {
      window.location.href = "/ui/merchant-login";
      throw new Error("MERCHANT_AUTH_MISSING");
    }
    return { token, merchantId };
  },
  login: async ({ username, password }) => {
    const data = await merchantFetch("/merchant/login", {
      method: "POST",
      auth: false,
      body: { username, password }
    });
    if (data?.token && data?.merchant) {
      window.MerchantUIAPI.setSession(data);
    }
    return data;
  },
  getProfile: async () => {
    const profile = await merchantFetch("/merchant/profile");
    return profile?.merchant || profile;
  },
  getSettlementSummary: () => merchantFetch("/merchant/settlement-summary"),
  listSettlementBatches: (query) => merchantFetch("/merchant/settlement-batches", { query }),
  getSettlementBatch: (id) => merchantFetch(`/merchant/settlement-batches/${id}`),
  formatMoney: merchantFormatMoney,
  formatDateTime: merchantFormatDateTime
};
