import https from "https";
import http from "http";
import { URL } from "url";

type Param = {
    scheme?: string;
    url?: string;
    method?: string;
    hostname?: string;
    path?: string;
    port?: number | string;
    headers?: object;
    body?: object;
};

/**
 * # Make Https Request
 */
export default function httpsRequest({
    url,
    method,
    hostname,
    path,
    headers,
    body,
    port,
    scheme,
}: Param) {
    const reqPayloadString = body ? JSON.stringify(body) : null;

    const PARSED_URL = url ? new URL(url) : null;

    ////////////////////////////////////////////////
    ////////////////////////////////////////////////
    ////////////////////////////////////////////////

    /** @type {any} */
    let requestOptions: any = {
        method: method || "GET",
        hostname: PARSED_URL ? PARSED_URL.hostname : hostname,
        port: scheme?.match(/https/i)
            ? 443
            : PARSED_URL
            ? PARSED_URL.protocol?.match(/https/i)
                ? 443
                : PARSED_URL.port
            : port
            ? Number(port)
            : 80,
        headers: {},
    };

    if (path) requestOptions.path = path;
    // if (href) requestOptions.href = href;

    if (headers) requestOptions.headers = headers;
    if (body) {
        requestOptions.headers["Content-Type"] = "application/json";
        requestOptions.headers["Content-Length"] = reqPayloadString
            ? Buffer.from(reqPayloadString).length
            : undefined;
    }

    ////////////////////////////////////////////////
    ////////////////////////////////////////////////
    ////////////////////////////////////////////////

    return new Promise((res, rej) => {
        const httpsRequest = (
            scheme?.match(/https/i)
                ? https
                : PARSED_URL?.protocol?.match(/https/i)
                ? https
                : http
        ).request(
            /* ====== Request Options object ====== */
            requestOptions,

            ////////////////////////////////////////////////
            ////////////////////////////////////////////////
            ////////////////////////////////////////////////

            /* ====== Callback function ====== */
            (response) => {
                var str = "";

                // ## another chunk of data has been received, so append it to `str`
                response.on("data", function (chunk) {
                    str += chunk;
                });

                // ## the whole response has been received, so we just print it out here
                response.on("end", function () {
                    res(str);
                });

                response.on("error", (error) => {
                    console.log("HTTP response error =>", error.message);
                    rej(`HTTP response error =>, ${error.message}`);
                });

                response.on("close", () => {
                    console.log("HTTP(S) Response Closed Successfully");
                });
            }
        );

        if (body) httpsRequest.write(reqPayloadString);

        httpsRequest.on("error", (error) => {
            console.log("HTTPS request ERROR =>", error.message);
            rej(`HTTP request error =>, ${error.message}`);
        });

        httpsRequest.end();
    });
}