﻿
// ReSharper disable InconsistentNaming

import axios, { AxiosError } from 'axios';
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, CancelToken } from 'axios';

export interface IUrlEncodedRequestConsumingClient {
    addMessage(message: Foo | null | undefined, messageId: string | null | undefined, signal?: AbortSignal): Promise<void>;
    getMessage(messageId: string | null, signal?: AbortSignal): Promise<Foo | null>;
}

export class UrlEncodedRequestConsumingClient implements IUrlEncodedRequestConsumingClient {
    protected instance: AxiosInstance;
    protected baseUrl: string;
    protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;

    constructor(baseUrl?: string, instance?: AxiosInstance) {

        this.instance = instance || axios.create();

        this.baseUrl = baseUrl ?? "";

    }

    addMessage(message: Foo | null | undefined, messageId: string | null | undefined, signal?: AbortSignal): Promise<void> {
        let url_ = this.baseUrl + "/api/UrlEncodedRequestConsuming";
        url_ = url_.replace(/[?&]$/, "");

        let content_ = "";
        if (message !== undefined)
            content_ += encodeURIComponent("message") + "=" + encodeURIComponent("" + message) + "&";
        if (messageId !== undefined)
            content_ += encodeURIComponent("messageId") + "=" + encodeURIComponent("" + messageId) + "&";
        content_ = content_.replace(/&$/, "");

        let options_: AxiosRequestConfig = {
            data: content_,
            method: "POST",
            url: url_,
            headers: {
                "Content-Type": "application/x-www-form-urlencoded",
            },
            signal
        };

        return this.instance.request(options_).catch((_error: any) => {
            if (isAxiosError(_error) && _error.response) {
                return _error.response;
            } else {
                throw _error;
            }
        }).then((_response: AxiosResponse) => {
            return this.processAddMessage(_response);
        });
    }

    protected processAddMessage(response: AxiosResponse): Promise<void> {
        const status = response.status;
        let _headers: any = {};
        if (response.headers && typeof response.headers === "object") {
            for (const k in response.headers) {
                if (response.headers.hasOwnProperty(k)) {
                    _headers[k] = response.headers[k];
                }
            }
        }
        if (status === 204) {
            const _responseText = response.data;
            return Promise.resolve<void>(null as any);

        } else if (status !== 200 && status !== 204) {
            const _responseText = response.data;
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
        }
        return Promise.resolve<void>(null as any);
    }

    getMessage(messageId: string | null, signal?: AbortSignal): Promise<Foo | null> {
        let url_ = this.baseUrl + "/api/UrlEncodedRequestConsuming?";
        if (messageId === undefined)
            throw new globalThis.Error("The parameter 'messageId' must be defined.");
        else if(messageId !== null)
            url_ += "messageId=" + encodeURIComponent("" + messageId) + "&";
        url_ = url_.replace(/[?&]$/, "");

        let options_: AxiosRequestConfig = {
            method: "GET",
            url: url_,
            headers: {
                "Accept": "application/json"
            },
            signal
        };

        return this.instance.request(options_).catch((_error: any) => {
            if (isAxiosError(_error) && _error.response) {
                return _error.response;
            } else {
                throw _error;
            }
        }).then((_response: AxiosResponse) => {
            return this.processGetMessage(_response);
        });
    }

    protected processGetMessage(response: AxiosResponse): Promise<Foo | null> {
        const status = response.status;
        let _headers: any = {};
        if (response.headers && typeof response.headers === "object") {
            for (const k in response.headers) {
                if (response.headers.hasOwnProperty(k)) {
                    _headers[k] = response.headers[k];
                }
            }
        }
        if (status === 200) {
            const _responseText = response.data;
            let result200: any = null;
            let resultData200  = _responseText;
            result200 = resultData200 ? Foo.fromJS(resultData200) : null as any;
            return Promise.resolve<Foo | null>(result200);

        } else if (status !== 200 && status !== 204) {
            const _responseText = response.data;
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
        }
        return Promise.resolve<Foo | null>(null as any);
    }
}

export class Foo implements IFoo {
    bar?: string | undefined;

    constructor(data?: IFoo) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (this as any)[property] = (data as any)[property];
            }
        }
    }

    init(_data?: any) {
        if (_data) {
            this.bar = _data["Bar"];
        }
    }

    static fromJS(data: any): Foo {
        data = typeof data === 'object' ? data : {};
        let result = new Foo();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["Bar"] = this.bar;
        return data;
    }
}

export interface IFoo {
    bar?: string | undefined;
}

export class ApiException extends Error {
    override message: string;
    status: number;
    response: string;
    headers: { [key: string]: any; };
    result: any;

    constructor(message: string, status: number, response: string, headers: { [key: string]: any; }, result: any) {
        super();

        this.message = message;
        this.status = status;
        this.response = response;
        this.headers = headers;
        this.result = result;
    }

    protected isApiException = true;

    static isApiException(obj: any): obj is ApiException {
        return obj.isApiException === true;
    }
}

function throwException(message: string, status: number, response: string, headers: { [key: string]: any; }, result?: any): any {
    if (result !== null && result !== undefined)
        throw result;
    else
        throw new ApiException(message, status, response, headers, null);
}

function isAxiosError(obj: any): obj is AxiosError {
    return obj && obj.isAxiosError === true;
}