const { inspect } = require('util');

const { version } = require('../package.json');

/**
 * @param {string} url
 * @param {RequestInit=} options
 * @param {Record<string, any>=} params
 */
module.exports = async function kaskoFetch(url, options = {}, params = {}) {
  const baseUrl = url.split('?')[0];
  const searchParams = new URLSearchParams(url.slice(baseUrl.length + 1));
  for (const [key, value] of Object.entries(params)) {
    searchParams.set(key, value);
  }

  if (searchParams.size > 0) {
    // rome-ignore lint/style/noParameterAssign: <explanation>
    url = `${url.split('?')[0]}?${searchParams.toString()}`;
  }

  const response = await fetch(url, {
    ...options,
    headers: {
      'User-Agent': `kasko/fe-toolbelt/${version}`,
      ...options.headers,
    },
  });

  if (response.status >= 400 || response.status < 200) {
    let error;
    try {
      error = `${response.statusText} (${response.status}) ${inspect(
        {
          method: options?.method || 'get',
          url: {
            href: url,
            baseUrl,
            searchParams,
          },
          response: await response.json(),
        },
        {
          compact: false,
          showHidden: false,
          breakLength: 20,
          colors: false,
        },
      ).replace(/\n/g, '\n  ')}`;
    } catch (e) {
      error = new Error(response.statusText);
    }

    throw new Error(error || 'fetch failed');
  }

  return response.json();
};
