import { doubleQuote, indent } from '@/requests/string-utils';
import type { CodeUsageGenerator } from '@/requests/generators';
import { resolveMediaAdapter } from '@/requests/media/adapter';

export const javascript: CodeUsageGenerator = {
  label: 'JavaScript',
  lang: 'js',
  generate(data, { mediaAdapters }) {
    const s: string[] = [];
    const options = new Map<string, string>();
    const headers: Record<string, string> = {};

    options.set('method', `"${data.method.toUpperCase()}"`);
    if (data.bodyMediaType) {
      headers['Content-Type'] = data.bodyMediaType;
    }

    for (const [k, v] of Object.entries(data.header)) {
      headers[k] = v.value;
    }

    const cookies = Object.entries(data.cookie);
    if (cookies.length > 0) {
      headers['cookie'] = cookies.map(([key, param]) => `${key}=${param.value}`).join('; ');
    }

    if (Object.keys(headers).length > 0) {
      options.set('headers', JSON.stringify(headers, null, 2));
    }

    let body: string | undefined;
    if (data.body && data.bodyMediaType) {
      const adapter = resolveMediaAdapter(data.bodyMediaType, mediaAdapters);
      body = adapter?.generateExample(data as { body: unknown }, {
        lang: 'js',
        addImport(from, name) {
          s.unshift(`import { ${name} } from "${from}"`);
        },
      });
    }

    if (body) {
      s.push(body);
      options.set('body', 'body');
    }

    const params = [doubleQuote(data.url)];
    if (options.size > 0) {
      const str = Array.from(options.entries())
        .map(([k, v]) => indent(k === v ? k : `${k}: ${v}`))
        .join(',\n');

      params.push(`{\n${str}\n}`);
    }

    s.push(`fetch(${params.join(', ')})`);

    return s.join('\n\n');
  },
};
