import http from "k6/http";
import type { Params, Response } from "k6/http";

{% if HasOperations -%}
{% if GenerateClientInterfaces -%}
{% if ExportTypes %}export {% endif %}interface I{{ Class }} {
{%    for operation in Operations %}

  {% template Client.Method.Documentation %}
  {{ operation.MethodAccessModifier }}{{ operation.ActualOperationName }}({% for parameter in operation.Parameters %}{{ parameter.VariableName }}{% if GenerateOptionalParameters and parameter.IsOptional %}?{% endif %}: {{ parameter.Type }}{{ parameter.TypePostfix }}{% if parameter.IsLast == false %}, {% endif %}{% endfor %}{% if operation.Parameters.size > 0 %}, {% endif %}requestParameters?: Params): {% if operation.ResultType != "void" %}{ response: Response; data: {{ operation.ResultType }} }{% else %}Response{% endif %};
{%-    endfor %}}
{%- endif -%}

{% if UseAureliaHttpInjection -%}
@inject({% if HasConfigurationClass %}{{ ConfigurationClass }}, {% endif %}String, HttpClient)
{%- endif -%}
{% if ExportTypes %}export {% endif %}class {{ Class }} {% if HasBaseClass %}extends {{ BaseClass }} {% endif %}{% if GenerateClientInterfaces %}implements I{{ Class }} {% endif %}{
  private baseUrl: string;
  private commonRequestParameters: Params;
{{ '' }}
{%- if HasExtendedConstructor == false -%}
  constructor({% if HasConfigurationClass %}configuration: {{ ConfigurationClass }}, {% endif %}baseUrl: string,commonRequestParameters?: Params) {
{%-    if HasBaseClass -%}
      super({% if HasConfigurationClass %}configuration{% endif %});
{%-    endif -%}
{%-    if UseGetBaseUrlMethod -%}
      this.baseUrl = this.getBaseUrl("{{ BaseUrl }}", baseUrl.replace(/\/+$/, ""));
{%-    else -%}
      this.baseUrl = baseUrl.replace(/\/+$/, "") ?? "{{ BaseUrl }}";
{%-    endif -%}
      this.commonRequestParameters = commonRequestParameters || {};
    }
{%- endif -%}

{%- if HasExtensionCode -%}

    {{ ExtensionCode }}
{%- endif -%}
{% for operation in Operations %}
    {% template Client.Method.Documentation %}
    {{ operation.MethodAccessModifier }}{{ operation.ActualOperationName }}({% for parameter in operation.Parameters %}{{ parameter.VariableName }}{% if GenerateOptionalParameters and parameter.IsOptional %}?{% endif %}: {{ parameter.Type }}{{ parameter.TypePostfix }}{% if parameter.IsLast == false %}, {% endif %}{% endfor %}{% if UseAbortSignal %}{% if operation.Parameters.size > 0 %}, {% endif %}signal?: AbortSignal{% endif %}{% if operation.Parameters.size > 0 %}, {% endif %}requestParameters?: Params): {% if operation.ResultType != "void" %}{ response: Response; data: {{ operation.ResultType }} }{% else %}Response {% endif %} {
      const mergedRequestParameters = this._mergeRequestParameters(
        requestParameters || {},
        this.commonRequestParameters,
      );
        {% template Client.RequestUrl %}

{%     if operation.HasBody -%}
      {% template Client.RequestBody %}
{%     endif -%}

{%-   if operation.HasBody -%}
      const response = http.request(
        "{{ operation.HttpMethodUpper | upcase }}",
        url_.toString(),
        content_,
        {
          ...mergedRequestParameters,
          headers: {
            ...mergedRequestParameters?.headers,
{%-    if operation.HasContent or operation.ConsumesOnlyFormUrlEncoded -%}
            "Content-Type": "{{ operation.Consumes }}",
{%-    endif -%}
{%-    if operation.HasResultType and operation.HasAcceptHeaderParameterParameter == false -%}
            "Accept": "{{ operation.Produces }}"
{%-    endif -%}
          },
        }
      );
{%-   else -%}
      const response = http.request("{{ operation.HttpMethodUpper | upcase }}", url_.toString(), undefined, {
        ...mergedRequestParameters,
      });
{%-   endif -%}

{%-   if operation.ResultType != "void" -%}
      let data;
      try {
        data = response.json();
      } catch {
        data = response.body;
      }
      return {
        response,
        data,
      };
{%-   else -%}
      return response;
{%-   endif -%}
    }
{% endfor -%}
  /**
  * Merges the provided request parameters with default parameters for the client.
  *
  * @param {Params} requestParameters - The parameters provided specifically for the request
  * @param {Params} commonRequestParameters - Common parameters for all requests
  * @returns {Params} - The merged parameters
  */
  private _mergeRequestParameters(
    requestParameters?: Params,
    commonRequestParameters?: Params,
  ): Params {
    return {
      ...commonRequestParameters, // Default to common parameters
      ...requestParameters, // Override with request-specific parameters
      headers: {
        ...(commonRequestParameters?.headers || {}), // Ensure headers are defined
        ...(requestParameters?.headers || {}),
      },
      cookies: {
        ...(commonRequestParameters?.cookies || {}), // Ensure cookies are defined
        ...(requestParameters?.cookies || {}),
      },
      tags: {
        ...(commonRequestParameters?.tags || {}), // Ensure tags are defined
        ...(requestParameters?.tags || {}),
      },
    };
  }
}
{%- endif -%}
