import { QueryClientProvider } from '@tanstack/react-query'
import { useEffect, useMemo, useState } from 'react'
import { DetailDrawer } from '@overdeck/deck-ui'
import { useCollectorState } from '../../lib/collector-queries'
import { createOverdeckQueryClient } from '../../lib/query-client'
import { toAgentSessionRow, type SessionsPanelData } from '../../lib/session-types'
import { SessionAttachDrawer } from './SessionAttachDrawer'
import { subscribeToSessionTerminal } from './session-terminal'

/**
 * App-level terminal owner. Base.astro persists this island through Astro client-side
 * navigation, keeping the capture query mounted while the reader changes pages.
 */
function sessionFromUrl(): string | null {
  return new URLSearchParams(window.location.search).get('session')
}

function replaceSessionInUrl(sessionId: string | null): void {
  const url = new URL(window.location.href)
  if (sessionId) url.searchParams.set('session', sessionId)
  else url.searchParams.delete('session')
  window.history.replaceState(window.history.state, '', `${url.pathname}${url.search}${url.hash}`)
}

export function SessionTerminalModal() {
  const [queryClient] = useState(createOverdeckQueryClient)
  const [sessionId, setSessionId] = useState<string | null>(null)

  useEffect(() => {
    setSessionId(sessionFromUrl())
    return subscribeToSessionTerminal((next) => {
    setSessionId(next)
    replaceSessionInUrl(next)
    })
  }, [])
  useEffect(() => {
    const sync = () => setSessionId(sessionFromUrl())
    window.addEventListener('popstate', sync)
    return () => window.removeEventListener('popstate', sync)
  }, [])

  if (sessionId === null) return null

  return (
    <QueryClientProvider client={queryClient}>
      <SessionTerminal sessionId={sessionId} onClose={() => { setSessionId(null); replaceSessionInUrl(null) }} />
    </QueryClientProvider>
  )
}

function SessionTerminal({ sessionId, onClose }: { sessionId: string; onClose(): void }) {
  const stateQuery = useCollectorState()

  const session = useMemo(() => {
    const panel = stateQuery.data?.panels.find((entry) => entry.id === 'sessions')
    const data = panel?.data as SessionsPanelData | undefined
    return data?.sessions.find((entry) => entry.id === sessionId) ?? null
  }, [stateQuery.data, sessionId])

  if (session) return <SessionAttachDrawer row={toAgentSessionRow(session)} onClose={onClose} />

  return (
    <DetailDrawer
      draggable
      modal={false}
      eyebrow="Session terminal"
      title={sessionId}
      titleId={`session-terminal-${sessionId}`}
      onClose={onClose}
    >
      <p className="mt-5 text-sm text-fg-muted">
        {stateQuery.isPending
          ? 'Reading this session from the collector…'
          : stateQuery.isError
            ? `The collector did not answer, so nothing about ${sessionId} can be shown.`
            : `The ledger no longer lists ${sessionId}, so nothing about it can be shown.`}
      </p>
    </DetailDrawer>
  )
}
