import { existsSync, readFileSync } from "node:fs";
import { createServer } from "node:https";
import http from "node:http";
import net from "node:net";
import path from "node:path";
import { fileURLToPath } from "node:url";

const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const hostname = process.env.API_PROXY_HOST ?? "0.0.0.0";
const port = Number(process.env.API_PROXY_PORT ?? 4000);
const target = new URL(process.env.API_PROXY_TARGET ?? "http://127.0.0.1:4001");
const keyPath = process.env.HTTPS_KEY_PATH ?? path.join(root, "certs/inventory2026-local.key");
const certPath = process.env.HTTPS_CERT_PATH ?? path.join(root, "certs/inventory2026-local.pem");

if (!existsSync(keyPath) || !existsSync(certPath)) {
  console.error(`Missing HTTPS certificate files:
  ${keyPath}
  ${certPath}`);
  process.exit(1);
}

const server = createServer(
  {
    key: readFileSync(keyPath),
    cert: readFileSync(certPath)
  },
  (clientRequest, clientResponse) => {
    const proxyRequest = http.request(
      {
        hostname: target.hostname,
        port: target.port,
        path: clientRequest.url,
        method: clientRequest.method,
        headers: {
          ...clientRequest.headers,
          host: `${target.hostname}:${target.port}`,
          "x-forwarded-proto": "https"
        }
      },
      (proxyResponse) => {
        clientResponse.writeHead(proxyResponse.statusCode ?? 502, proxyResponse.headers);
        proxyResponse.pipe(clientResponse);
      }
    );

    proxyRequest.on("error", () => {
      clientResponse.writeHead(502, { "content-type": "application/json" });
      clientResponse.end(JSON.stringify({ error: "API proxy could not reach the backend." }));
    });

    clientRequest.pipe(proxyRequest);
  }
);

server.on("upgrade", (request, socket, head) => {
  const upstream = net.connect(Number(target.port), target.hostname, () => {
    upstream.write(`${request.method} ${request.url} HTTP/${request.httpVersion}\r\n`);
    for (const [name, value] of Object.entries(request.headers)) {
      if (Array.isArray(value)) {
        for (const item of value) upstream.write(`${name}: ${item}\r\n`);
      } else if (value !== undefined) {
        upstream.write(`${name}: ${value}\r\n`);
      }
    }
    upstream.write(`host: ${target.hostname}:${target.port}\r\n`);
    upstream.write("x-forwarded-proto: https\r\n");
    upstream.write("\r\n");
    if (head.length) upstream.write(head);
    upstream.pipe(socket);
    socket.pipe(upstream);
  });

  upstream.on("error", () => socket.destroy());
});

server.listen(port, hostname, () => {
  console.log(`SSS Inventory API HTTPS proxy listening at https://${hostname}:${port} -> ${target.href}`);
});
