import { startSubdomainServers } from "./orchestrator"
import { nanoRemix } from "@workshop/nano-remix"
import { requireAuth } from "./auth"
import { join } from "node:path"

/**
 * Password-protected subdomain proxy server
 *
 * How it works:
 * 1. Starts multiple subdomain servers on different ports (3001+)
 * 2. Main server (port 3000) acts as a proxy that routes requests based on subdomain
 * 3. All requests are protected with Basic HTTP auth + persistent cookies
 * 4. Once authenticated, cookies work across all subdomains (*.theworkshop.cc)
 * 5. In development, uses subdomain:dev scripts if available for hot reloading
 *
 * This server is designed to be run in production with NODE_ENV=production. On development,
 * it allows unauthenticated access because YOLO.
 */

export const startServer = async () => {
  const portMap = await startSubdomainServers()

  const server = Bun.serve({
    port: 3000,
    routes: {
      // Handle main site routes through nano-remix
      "/*": requireAuth(async (req) => {
        const url = new URL(req.url)
        const hostname = url.hostname
        const subdomain = hostname.split(".")[0]

        const targetPort = subdomain && portMap[subdomain]
        if (!targetPort) {
          const routesDir = join(import.meta.dir, "routes")
          return nanoRemix(req, { routesDir })
        }

        try {
          const target = `http://127.0.0.1:${targetPort}${url.pathname}${url.search}`

          // Forward the request with auth headers preserved
          const forwardedReq = new Request(target, {
            method: req.method,
            headers: req.headers,
            body: req.body,
          })

          const upstream = await fetch(forwardedReq)

          return new Response(upstream.body, {
            status: upstream.status,
            headers: new Headers(upstream.headers),
          })
        } catch (error) {
          console.error(`Error forwarding request to subdomain "${subdomain}":`, error)
          return new Response(`Failed to forward request to "${subdomain}"`, { status: 500 })
        }
      }),
    },
  })

  logServerInfo(server, portMap)
}

const logServerInfo = (server: Bun.Server, portMap: Record<string, number>) => {
  console.log(`${server.url}`)
  const subdomainEntries = Object.entries(portMap)

  subdomainEntries.forEach(([subdomain, port], index) => {
    const subdomainUrl = new URL(server.url)
    subdomainUrl.hostname = `${subdomain}.${subdomainUrl.hostname}`
    subdomainUrl.port = port.toString()
    const isLast = index === subdomainEntries.length - 1
    const prefix = isLast ? "└─" : "├─"
    console.log(`${prefix} ${subdomainUrl}`)
  })
  console.log("")
}
