'use client'

import { useState, useEffect, useRef, useCallback } from 'react'

interface StageliveSseState {
  isConnected: boolean
  activeProject: {
    id: string
    title: string
    teamName: string | null
    description: string | null
  } | null
  openCohorts: Array<{
    id: string
    name: string
    isOpen: boolean
    projectIds: string[]
  }>
  isPaused: boolean
  error: string | null
}

interface UseStageliveSseOptions {
  enabled?: boolean
}

export function useStageliveSse(
  sessionId: string | null,
  options: UseStageliveSseOptions = {}
) {
  const { enabled = true } = options
  const [state, setState] = useState<StageliveSseState>({
    isConnected: false,
    activeProject: null,
    openCohorts: [],
    isPaused: false,
    error: null,
  })

  const eventSourceRef = useRef<EventSource | null>(null)
  const reconnectTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  const retryCountRef = useRef(0)
  const maxRetries = 10

  const connect = useCallback(() => {
    if (!sessionId || !enabled) return

    // Clean up existing connection
    if (eventSourceRef.current) {
      eventSourceRef.current.close()
    }

    const url = `/api/sse/stage-live/${sessionId}`
    const es = new EventSource(url)
    eventSourceRef.current = es

    es.onopen = () => {
      setState((prev) => ({ ...prev, isConnected: true, error: null }))
      retryCountRef.current = 0
    }

    es.addEventListener('cursor.updated', (event) => {
      try {
        const data = JSON.parse(event.data)
        setState((prev) => ({
          ...prev,
          activeProject: data.activeProject ?? prev.activeProject,
          isPaused: data.isPaused ?? prev.isPaused,
        }))
      } catch {
        // Ignore malformed events
      }
    })

    es.addEventListener('cohort.window.changed', (event) => {
      try {
        const data = JSON.parse(event.data)
        setState((prev) => ({
          ...prev,
          openCohorts: data.cohorts ?? prev.openCohorts,
        }))
      } catch {
        // Ignore
      }
    })

    es.addEventListener('vote.received', () => {
      // Used for UI feedback (e.g. flash animation)
      // No state change needed
    })

    es.addEventListener('session.paused', () => {
      setState((prev) => ({ ...prev, isPaused: true }))
    })

    es.addEventListener('session.resumed', () => {
      setState((prev) => ({ ...prev, isPaused: false }))
    })

    es.addEventListener('init', (event) => {
      try {
        const data = JSON.parse(event.data)
        setState({
          isConnected: true,
          activeProject: data.activeProject ?? null,
          openCohorts: data.openCohorts ?? [],
          isPaused: data.isPaused ?? false,
          error: null,
        })
      } catch {
        // Ignore
      }
    })

    es.onerror = () => {
      es.close()
      setState((prev) => ({ ...prev, isConnected: false }))

      if (retryCountRef.current < maxRetries) {
        const delay = Math.min(1000 * Math.pow(2, retryCountRef.current), 30000)
        retryCountRef.current++
        reconnectTimeoutRef.current = setTimeout(connect, delay)
      } else {
        setState((prev) => ({
          ...prev,
          error: 'Connection lost. Please refresh the page.',
        }))
      }
    }
  }, [sessionId, enabled])

  useEffect(() => {
    connect()

    return () => {
      if (eventSourceRef.current) {
        eventSourceRef.current.close()
        eventSourceRef.current = null
      }
      if (reconnectTimeoutRef.current) {
        clearTimeout(reconnectTimeoutRef.current)
        reconnectTimeoutRef.current = null
      }
    }
  }, [connect])

  const reconnect = useCallback(() => {
    retryCountRef.current = 0
    connect()
  }, [connect])

  return { ...state, reconnect }
}
