// If you want to use Phoenix channels, run `mix help phx.gen.channel`
// to get started and then uncomment the line below.
// import "./user_socket.js"

// You can include dependencies in two ways.
//
// The simplest option is to put them in assets/vendor and
// import them using relative paths:
//
//     import "../vendor/some-package.js"
//
// Alternatively, you can `npm install some-package --prefix assets` and import
// them using a path starting with the package name:
//
//     import "some-package"
//
// If you have dependencies that try to import CSS, esbuild will generate a separate `app.css` file.
// To load it, simply add a second `<link>` to your `root.html.heex` file.

// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
import "phoenix_html"
// Establish Phoenix Socket and LiveView configuration.
import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"
import {hooks as colocatedHooks} from "phoenix-colocated/who_need_help"
import topbar from "../vendor/topbar"
import {Hooks} from "./hooks"

const systemTheme = () =>
  matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"

const setTheme = theme => {
  if (theme === "system") {
    localStorage.removeItem("phx:theme")
    document.documentElement.setAttribute("data-theme", systemTheme())
    document.documentElement.setAttribute("data-theme-source", "system")
  } else {
    localStorage.setItem("phx:theme", theme)
    document.documentElement.setAttribute("data-theme", theme)
    document.documentElement.setAttribute("data-theme-source", "user")
  }
}

if (!document.documentElement.hasAttribute("data-theme")) {
  setTheme(localStorage.getItem("phx:theme") || "system")
}

window.addEventListener("storage", event => {
  if (event.key === "phx:theme") setTheme(event.newValue || "system")
})
window.addEventListener("phx:set-theme", event => setTheme(event.target.dataset.phxTheme))
matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
  if (document.documentElement.getAttribute("data-theme-source") === "system") {
    document.documentElement.setAttribute("data-theme", systemTheme())
  }
})

const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")

const activateProtectedTokenFragment = () => {
  if (!window.location.hash.startsWith("#token=")) return

  const token = new URLSearchParams(window.location.hash.slice(1)).get("token")
  window.history.replaceState(null, "", `${window.location.pathname}${window.location.search}`)

  if (!token || !/^[A-Za-z0-9_-]{43}$/.test(token)) return

  const candidates = [
    {
      form: document.getElementById("magic-link-fragment-form"),
      input: document.getElementById("magic-link-fragment-token"),
      options: document.getElementById("standard-login-options")
    },
    {
      form: document.getElementById("email-change-fragment-form"),
      input: document.getElementById("email-change-fragment-token")
    }
  ]

  const candidate = candidates.find(({form, input}) =>
    form instanceof HTMLFormElement && input instanceof HTMLInputElement
  )

  if (!candidate) return

  candidate.input.value = token
  candidate.form.hidden = false
  if (candidate.options instanceof HTMLElement) candidate.options.hidden = true
  candidate.form.querySelector("button")?.focus()
}

activateProtectedTokenFragment()
window.addEventListener("hashchange", activateProtectedTokenFragment)

const liveSocket = new LiveSocket("/live", Socket, {
  longPollFallbackMs: 2500,
  params: {
    _csrf_token: csrfToken,
    client_type: typeof window.WhoNeedHelpAndroid?.postMessage === "function" ? "android" : "browser"
  },
  hooks: {...colocatedHooks, ...Hooks},
})

// Show progress bar on live navigation and form submits
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
window.addEventListener("phx:page-loading-stop", _info => topbar.hide())
window.addEventListener("phx:reset-message-form", ({detail}) => {
  const form = document.getElementById(detail.id)
  if (form instanceof HTMLFormElement) form.reset()
})
window.addEventListener("phx:native-tracking-start", ({detail}) => {
  window.WhoNeedHelpAndroid?.postMessage?.(JSON.stringify({
    action: "start",
    assignment_id: detail.assignment_id,
    csrf_token: csrfToken
  }))
})
window.addEventListener("phx:native-tracking-stop", () => {
  window.WhoNeedHelpAndroid?.postMessage?.(JSON.stringify({action: "stop"}))
})

// connect if there are any LiveViews on the page
liveSocket.connect()

// expose liveSocket on window for web console debug logs and latency simulation:
// >> liveSocket.enableDebug()
// >> liveSocket.enableLatencySim(1000)  // enabled for duration of browser session
// >> liveSocket.disableLatencySim()
window.liveSocket = liveSocket

if ("serviceWorker" in navigator) {
  window.addEventListener("load", () => {
    navigator.serviceWorker.register("/sw.js").catch(error => {
      console.warn("Service worker registration failed", error)
    })
  })
}

// The lines below enable quality of life phoenix_live_reload
// development features:
//
//     1. stream server logs to the browser console
//     2. click on elements to jump to their definitions in your code editor
//
if (process.env.NODE_ENV === "development") {
  window.addEventListener("phx:live_reload:attached", ({detail: reloader}) => {
    // Enable server log streaming to client.
    // Disable with reloader.disableServerLogs()
    reloader.enableServerLogs()

    // Open configured PLUG_EDITOR at file:line of the clicked element's HEEx component
    //
    //   * click with "c" key pressed to open at caller location
    //   * click with "d" key pressed to open at function component definition location
    let keyDown
    window.addEventListener("keydown", e => keyDown = e.key)
    window.addEventListener("keyup", _e => keyDown = null)
    window.addEventListener("click", e => {
      if(keyDown === "c"){
        e.preventDefault()
        e.stopImmediatePropagation()
        reloader.openEditorAtCaller(e.target)
      } else if(keyDown === "d"){
        e.preventDefault()
        e.stopImmediatePropagation()
        reloader.openEditorAtDef(e.target)
      }
    }, true)

    window.liveReloader = reloader
  })
}
