'use client'

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

export interface VoteUpdate {
  projectId: string
  totalVotes: number
  averageScore: number | null
  latestVote: { score: number; isAudienceVote: boolean; votedAt: string } | null
  timestamp: string
}

export interface AudienceVoteUpdate {
  projectId: string
  audienceVotes: number
  audienceAverage: number | null
  timestamp: string
}

export interface SessionStatusUpdate {
  status: string
  timestamp: string
}

export interface ProjectChangeUpdate {
  projectId: string | null
  projectIndex: number
  timestamp: string
}

interface SSECallbacks {
  onVoteUpdate?: (data: VoteUpdate) => void
  onAudienceVote?: (data: AudienceVoteUpdate) => void
  onSessionStatus?: (data: SessionStatusUpdate) => void
  onProjectChange?: (data: ProjectChangeUpdate) => void
  onConnected?: () => void
  onError?: (error: Event) => void
}

export function useLiveVotingSSE(
  sessionId: string | null,
  callbacks: SSECallbacks
) {
  const [isConnected, setIsConnected] = useState(false)
  const eventSourceRef = useRef<EventSource | null>(null)
  const callbacksRef = useRef(callbacks)
  callbacksRef.current = callbacks

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

    // Close any existing connection
    if (eventSourceRef.current) {
      eventSourceRef.current.close()
    }

    const baseUrl = typeof window !== 'undefined' ? window.location.origin : ''
    const url = `${baseUrl}/api/live-voting/stream?sessionId=${sessionId}`
    const es = new EventSource(url)
    eventSourceRef.current = es

    es.addEventListener('connected', () => {
      setIsConnected(true)
      callbacksRef.current.onConnected?.()
    })

    es.addEventListener('vote_update', (event) => {
      try {
        const data = JSON.parse(event.data) as VoteUpdate
        callbacksRef.current.onVoteUpdate?.(data)
      } catch {
        // Ignore parse errors
      }
    })

    es.addEventListener('audience_vote', (event) => {
      try {
        const data = JSON.parse(event.data) as AudienceVoteUpdate
        callbacksRef.current.onAudienceVote?.(data)
      } catch {
        // Ignore parse errors
      }
    })

    es.addEventListener('session_status', (event) => {
      try {
        const data = JSON.parse(event.data) as SessionStatusUpdate
        callbacksRef.current.onSessionStatus?.(data)
      } catch {
        // Ignore parse errors
      }
    })

    es.addEventListener('project_change', (event) => {
      try {
        const data = JSON.parse(event.data) as ProjectChangeUpdate
        callbacksRef.current.onProjectChange?.(data)
      } catch {
        // Ignore parse errors
      }
    })

    es.onerror = (event) => {
      setIsConnected(false)
      callbacksRef.current.onError?.(event)

      // Auto-reconnect after 3 seconds
      setTimeout(() => {
        if (eventSourceRef.current === es) {
          connect()
        }
      }, 3000)
    }
  }, [sessionId])

  const disconnect = useCallback(() => {
    if (eventSourceRef.current) {
      eventSourceRef.current.close()
      eventSourceRef.current = null
      setIsConnected(false)
    }
  }, [])

  useEffect(() => {
    connect()
    return () => disconnect()
  }, [connect, disconnect])

  return { isConnected, reconnect: connect, disconnect }
}
