mixin guild-menuitem(guild)
  - let bridgedRoomCount = from("channel_room").selectUnsafe("count(*) as count").where({guild_id: guild.id}).and("AND thread_parent IS NULL").get().count
  li(role="menuitem")
    a.s-topbar--item.s-user-card.d-flex.p4(href=rel(`/guild?guild_id=${guild.id}`) class={"bg-purple-200": bridgedRoomCount === 0, "h:bg-purple-300": bridgedRoomCount === 0})
      +guild(guild, bridgedRoomCount)

mixin guild(guild, bridgedRoomCount)
  span.s-avatar.s-avatar__32.s-user-card--avatar
    if guild.icon
      img.s-avatar--image(src=`https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.png?size=32` alt="")
    else
      .s-avatar--letter.bg-silver-400.bar-md(aria-hidden="true")= guild.name[0]
  .s-user-card--info.ai-start
    strong= guild.name
    if bridgedRoomCount != null
      ul.s-user-card--awards
        if bridgedRoomCount
          li #{bridgedRoomCount} bridged rooms
        else
          li.fc-purple Not yet linked

mixin define-theme(name, h, s, l)
  style.
    :root {
      --#{name}-h: #{h};
      --#{name}-s: #{s};
      --#{name}-l: #{l};
      --#{name}: var(--#{name}-400);
      --#{name}-100: hsl(var(--#{name}-h), calc(var(--#{name}-s) + 0 * 1%), clamp(70%, calc(var(--#{name}-l) + 50 * 1%), 95%));
      --#{name}-200: hsl(var(--#{name}-h), calc(var(--#{name}-s) + 0 * 1%), clamp(55%, calc(var(--#{name}-l) + 35 * 1%), 90%));
      --#{name}-300: hsl(var(--#{name}-h), calc(var(--#{name}-s) + 0 * 1%), clamp(35%, calc(var(--#{name}-l) + 15 * 1%), 75%));
      --#{name}-400: hsl(var(--#{name}-h), calc(var(--#{name}-s) + 0 * 1%), clamp(20%, calc(var(--#{name}-l) + 0 * 1%), 60%));
      --#{name}-500: hsl(var(--#{name}-h), calc(var(--#{name}-s) + 0 * 1%), clamp(15%, calc(var(--#{name}-l) + -14 * 1%), 45%));
      --#{name}-600: hsl(var(--#{name}-h), calc(var(--#{name}-s) + 0 * 1%), clamp(5%, calc(var(--#{name}-l) + -26 * 1%), 30%));
    }

mixin define-themed-button(name, theme)
  style.
    .s-btn.s-btn__#{name} {
      --_bu-bg-active: var(--#{theme}-300);
      --_bu-bg-hover: var(--#{theme}-200);
      --_bu-bg-selected: var(--#{theme}-300);
      --_bu-fc: var(--#{theme}-500);
      --_bu-fc-active: var(--_bu-fc);
      --_bu-fc-hover: var(--#{theme}-500);
      --_bu-fc-selected: var(--#{theme}-600);
      --_bu-filled-bc: transparent;
      --_bu-filled-bc-selected: var(--_bu-filled-bc);
      --_bu-filled-bg: var(--#{theme}-400);
      --_bu-filled-bg-active: var(--#{theme}-500);
      --_bu-filled-bg-hover: var(--#{theme}-500);
      --_bu-filled-bg-selected: var(--#{theme}-600);
      --_bu-filled-fc: var(--white);
      --_bu-filled-fc-active: var(--_bu-filled-fc);
      --_bu-filled-fc-hover: var(--_bu-filled-fc);
      --_bu-filled-fc-selected: var(--_bu-filled-fc);
      --_bu-outlined-bc: var(--#{theme}-400);
      --_bu-outlined-bc-selected: var(--#{theme}-500);
      --_bu-outlined-bg-selected: var(--_bu-bg-selected);
      --_bu-outlined-fc-selected: var(--_bu-fc-selected);
      --_bu-number-fc: var(--white);
      --_bu-number-fc-filled: var(--#{theme});
    }

doctype html
html(lang="en")
  head
    block title
      title Out Of Your Element
    <meta name="viewport" content="width=device-width, initial-scale=1">
    link(rel="stylesheet" type="text/css" href=rel("/static/stacks.min.css"))
    //- Please use responsibly!!!!!
    link(rel="stylesheet" type="text/css" href=rel("/custom.css"))
    <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 80%22><text y=%22.83em%22 font-size=%2283%22>💬</text></svg>">
    meta(name="htmx-config" content='{"requestClass":"is-loading"}')
    style.
      .s-prose a {
        text-decoration: underline;
      }
      .themed {
        --theme-base-primary-color-h: 266;
        --theme-base-primary-color-s: 53%;
        --theme-base-primary-color-l: 63%;
        --theme-dark-primary-color-h: 266;
        --theme-dark-primary-color-s: 53%;
        --theme-dark-primary-color-l: 63%;
      }
      .s-toggle-switch.s-toggle-switch__multiple.s-toggle-switch__incremental input[type="radio"]:checked ~ label:not(.s-toggle-switch--label-off) {
        --_ts-multiple-bg: var(--green-400);
        --_ts-multiple-fc: var(--white);
      }
      .s-avatar {
        --_av-bg: var(--white);
      }
      .s-avatar .s-avatar--letter {
        color: var(--white);
      }
      .s-btn__dropdown:has(+ :popover-open) {
        background-color: var(--theme-topbar-item-background-hover, var(--black-200)) !important;
      }
      .s-btn__dropdown.s-tag:has(+ :popover-open) .s-tag--dismiss {
        background-color: var(--black-500) !important;
        color: var(--black-150) !important;
      }
      .s-tag .is-loading {
        margin-right: -4px;
      }
      .s-tag .is-loading + .s-tag--dismiss {
        display: none !important;
      }
      a.s-block-link, .s-block-link {
        --_bl-bs-color: var(--green-400);
      }
      @media (prefers-color-scheme: dark) {
        body.theme-system .s-popover {
          --_po-bg: var(--black-100);
          --_po-bc: var(--bc-light);
          --_po-bs: var(--bs-lg);
          --_po-arrow-fc: var(--black-100);
        }
      }
    +define-themed-button("matrix", "black")
  body.themed.theme-system
    header.s-topbar
      a.s-topbar--skip-link(href="#content") Skip to main content
      .s-topbar--container.wmx9
        a.s-topbar--logo(href=rel("/"))
          img.s-avatar.s-avatar__32(src=rel("/icon.png") alt="")
        nav.s-topbar--navigation
          ul.s-topbar--content
            li.ps-relative.g8
              if !session.data.mxid
                a.s-btn.s-btn__icon.s-btn__matrix.s-btn__outlined.as-center(href=rel("/log-in-with-matrix"))
                  != icons.Icons.IconSpeechBubble
                  = ` Log in`
                  span(class="sm:d-none")= ` with Matrix`
              if !session.data.userID
                a.s-btn.s-btn__icon.s-btn__featured.s-btn__outlined.as-center(href=rel("/oauth"))
                  != icons.Icons.IconDiscord
                  = ` Log in`
                  span(class="sm:d-none")= ` with Discord`
              if guild_id && managed.has(guild_id) && discord.guilds.has(guild_id)
                button.s-topbar--item.s-btn.s-btn__muted.s-btn__dropdown.pr32.bar0.s-user-card(popovertarget="guilds")
                  +guild(discord.guilds.get(guild_id))
              else if managed.size
                button.s-topbar--item.s-btn.s-btn__muted.s-btn__dropdown.pr24.s-user-card.bar0.fc-black(popovertarget="guilds")
                  | Your servers
              else if session.data.mxid || session.data.userID
                .d-flex.ai-center
                  .s-badge.s-badge__bot.py6.px16.bar-md
                    | No servers available
              #guilds(popover data-popper-placement="bottom" style="display: revert; width: revert;").s-popover.overflow-visible
                .s-popover--arrow.s-popover--arrow__tc
                .s-popover--content.overflow-y-auto.overflow-x-hidden
                  ul.s-menu(role="menu")
                    each guild in [...managed].map(id => discord.guilds.get(id)).filter(g => g).sort((a, b) => a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1)
                      +guild-menuitem(guild)
    //- Body
    .mx-auto.w100.wmx9.py24.px8.fs-body1#content
      block body
    //- Guild list popover
    script.
      document.querySelectorAll("[popovertarget]").forEach(e => {
        const target = document.getElementById(e.getAttribute("popovertarget"))
        e.addEventListener("click", calculate)
        target.addEventListener("toggle", calculate)
        function calculate() {
          const buttonRect = e.getBoundingClientRect()
          const targetRect = target.getBoundingClientRect()
          const t = `:popover-open { position: absolute; top: ${Math.floor(buttonRect.bottom + window.scrollY)}px; left: ${Math.floor(Math.max(targetRect.width / 2, buttonRect.left + buttonRect.width / 2))}px; width: ${Math.floor(buttonRect.width)}px; transform: translateX(-50%); box-sizing: content-box; margin: 0 }`
          document.styleSheets[0].insertRule(t, document.styleSheets[0].cssRules.length)
        }
      })
    //- Prevent default
    script.
      document.querySelectorAll("[cx-prevent-default]").forEach(e => {
        e.addEventListener("click", event => {
          event.preventDefault()
        })
      })
    script(src=rel("/static/htmx.js"))
    //- Error dialog
    aside.s-modal#server-error(aria-hidden="true")
      .s-modal--dialog
        h1.s-modal--header Server error
        pre.overflow-auto#server-error-content
        button.s-modal--close.s-btn.s-btn__muted(aria-label="Close" type="button" onclick="hideError()")!= icons.Icons.IconClearSm
        .s-modal--footer
          button.s-btn.s-btn__outlined.s-btn__muted(type="button" onclick="hideError()") OK
    script.
      function hideError() {
        document.getElementById("server-error").setAttribute("aria-hidden", "true")
      }
      document.body.addEventListener("htmx:responseError", event => {
        document.getElementById("server-error").setAttribute("aria-hidden", "false")
        document.getElementById("server-error-content").textContent = event.detail.xhr.responseText
      })
