import { defineStore } from 'pinia'
import { ref } from 'vue'

/** Apps that set X-Frame-Options and/or don't support subpath proxy - open in new tab for correct display */
function mustOpenInNewTab(url: string): boolean {
  try {
    const u = new URL(url)
    return (
      u.port === '23000' || // BTCPay
      u.port === '8123' || // Home Assistant
      u.port === '8085' || // Nextcloud (subpath breaks CSS/assets)
      u.port === '2283'    // Immich (subpath breaks SPA)
    )
  } catch {
    return false
  }
}

/** Port → proxy path for apps (nginx strips X-Frame-Options) */
const PORT_TO_PROXY: Record<string, string> = {
  '81': '/app/nginx-proxy-manager/',
  '3000': '/app/grafana/',
  '3001': '/app/uptime-kuma/',
  '8080': '/app/endurain/',
  '8081': '/app/lnd/',
  '8082': '/app/vaultwarden/',
  '8083': '/app/filebrowser/',
  '8085': '/app/nextcloud/',
  '8096': '/app/jellyfin/',
  '8123': '/app/homeassistant/',
  '8240': '/app/tailscale/',
  '8334': '/app/bitcoin-ui/',
  '8888': '/app/searxng/',
  '9000': '/app/portainer/',
  '9001': '/app/penpot/',
  '9980': '/app/onlyoffice/',
  '11434': '/app/ollama/',
  '2283': '/app/immich/',
  '23000': '/app/btcpay/',
  '2342': '/app/photoprism/',
  '4080': '/app/mempool/',
  '50002': '/app/electrs/',
  '8175': '/app/fedimint/',
}

/** Rewrite to same-origin proxy so iframe can embed (avoids mixed content on HTTPS) */
function toEmbeddableUrl(url: string): string {
  try {
    const u = new URL(url)
    const origin = window.location.origin
    const proxyPath = PORT_TO_PROXY[u.port]
    const sameHost = u.hostname === window.location.hostname
    const needsProxy = window.location.protocol === 'https:' && u.protocol === 'http:'
    // Use proxy when: (a) mixed content, or (b) vaultwarden/penpot always (subpath required)
    if (proxyPath && sameHost && (needsProxy || u.port === '8082' || u.port === '9001')) {
      return `${origin}${proxyPath}`
    }
  } catch {
    /* ignore */
  }
  return url
}

export const useAppLauncherStore = defineStore('appLauncher', () => {
  const isOpen = ref(false)
  const url = ref('')
  const title = ref('')
  let previousActiveElement: HTMLElement | null = null

  function open(payload: { url: string; title: string; openInNewTab?: boolean }) {
    const embeddableUrl = toEmbeddableUrl(payload.url)
    if (payload.openInNewTab || mustOpenInNewTab(payload.url)) {
      window.open(embeddableUrl, '_blank', 'noopener,noreferrer')
      return
    }
    previousActiveElement = (document.activeElement as HTMLElement) || null
    url.value = embeddableUrl
    title.value = payload.title
    isOpen.value = true
  }

  function close() {
    const toRestore = previousActiveElement
    previousActiveElement = null
    isOpen.value = false
    url.value = ''
    title.value = ''
    if (toRestore && typeof toRestore.focus === 'function') {
      requestAnimationFrame(() => {
        toRestore.focus()
      })
    }
  }

  return {
    isOpen,
    url,
    title,
    open,
    close,
  }
})
