import { englishPage } from "./language"

async function handleRequest(request) {
    let {pathname} = new URL(request.url)
    pathname = pathname.toLowerCase()
    if (pathname.endsWith('/')) {
        pathname = pathname.substring(0, pathname.length - 1);
    }
    
    if (pathname === '/wsclick.html') {
        count = 0
        return new Response(englishPage(request) ? HOMEPAGE_EN : HOMEPAGE, {headers: {"Content-Type": "text/html; charset=utf-8"}})
    } else if (pathname === '/wsclick') {
        return websocketHandler(request) 
    }
}

async function websocketHandler(request) {
    const upgradeHeader = request.headers.get("Upgrade")
    if (upgradeHeader !== "websocket") {
        return new Response("Expected websocket", { status: 400 })
    }

    const [client, server] = Object.values(new WebSocketPair())
    let serverName = request.headers.get('x-ws-request-id')
    if (serverName) {
      serverName = serverName.match(/_(.*?)_/)[1]
    }
    await handleSession(server, serverName)

    return new Response(null, {
        status: 101,
        webSocket: client
    })
}

let count = 0

async function handleSession(websocket, serverName) {
    websocket.accept()
    websocket.addEventListener("message", async ({ data }) => {
        console.log('message', data)
        const now = (new Date()).toString().replace(' ()', '')
        if (data === "CLICK") {
            count += 1
            websocket.send(JSON.stringify({ count, tz: now, server: serverName }))
        } else {
            // An unknown message came into the server. Send back an error message
            websocket.send(JSON.stringify({ error: "Unknown message received", tz: now, server: serverName }))
        }
    })
  
    websocket.addEventListener("close", async evt => {
        // Handle when a client closes the WebSocket connection
        console.log('xxx:close', evt)
    })
}



const HOMEPAGE_EN = `
<html>
<head>
<title>WebSocket Click Counter Example</title>
<style>
  body {
    margin: 1rem;
    font-family: monospace;
    font-size: 16px;
  }
</style>
</head>
<body>
<p>Click count: <span id="num"></span></p>
<button id="click">Click to send a message to the server, which will record your clicks and respond accordingly</button>

<p>You can also send a message that the WebSocket server cannot recognize, which will cause the WebSocket server to return an error message to the client.</p>
<button id="unknown">Simulate sending an unrecognized message to the server</button>

<p>Once testing is complete, you can click the button below to close the connection. Further clicks will not work until the page is refreshed.</p>
<button id="close">Close Connection</button>

<p id="error" style="color: red;"></p>

<h4>Received WebSocket messages from server</h4>
<ul id="events"></ul>

<script>
  let ws

  async function websocket(url) {
    ws = new WebSocket(url)

    if (!ws) {
      throw new Error("server didn't accept ws")
    }

    ws.addEventListener("open", () => {
      console.log('Opened websocket')
      updateCount(0)
    })

    ws.addEventListener("message", ({ data }) => {
      const { count, tz, error } = JSON.parse(data)
      addNewEvent(data)
      if (error) {
        setErrorMessage(error)
      } else {
        setErrorMessage()
        updateCount(count)
      }
    })

    ws.addEventListener("close", () => {
      console.log('Closed websocket')

      const list = document.querySelector("#events")
      list.innerText = ""
      updateCount(0)
      setErrorMessage()
    })
  }

  const url = new URL(window.location)
  url.protocol = "ws"
  url.pathname = "/wsclick"
  websocket(url)

  document.querySelector("#click").addEventListener("click", () => {
    ws.send("CLICK")
  })

  const updateCount = (count) => {
    document.querySelector("#num").innerText = count
  }

  const addNewEvent = (data) => {
    const list = document.querySelector("#events")
    const item = document.createElement("li")
    item.innerText = data
    list.prepend(item)
  }

  const closeConnection = () => ws.close()

  document.querySelector("#close").addEventListener("click", closeConnection)
  document.querySelector("#unknown").addEventListener("click", () => ws.send("HUH"))

  const setErrorMessage = message => {
    document.querySelector("#error").innerHTML = message ? message : ""
  }
</script>
</body>
</html>
`
                    
addEventListener("fetch", event => {
    return event.respondWith(handleRequest(event.request))
})