import { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react'
import { useAuth } from './AuthContext'

const PermissionsContext = createContext(null)

// Intervall für automatisches Neuladen der Permissions (30 Sekunden)
const PERMISSIONS_REFRESH_INTERVAL = 30000

export const PermissionsProvider = ({ children }) => {
  const { authFetch, isAuthenticated } = useAuth()
  const [permissions, setPermissions] = useState({
    isAdmin: false,
    hasFullAccess: false,
    accessibleSpaces: [],
    canCreateSpace: false,
    canDeleteSpace: false,
    canCreateFqdn: {},
    canDeleteFqdn: {},
    canUploadCSR: {},
    canSignCSR: {},
  })
  const [loading, setLoading] = useState(true)
  const intervalRef = useRef(null)
  const isMountedRef = useRef(true)

  const fetchPermissions = useCallback(async (isInitial = false) => {
    if (!isAuthenticated) {
      setLoading(false)
      return
    }

    try {
      if (isInitial) {
        setLoading(true)
      }
      const response = await authFetch('/api/user/permissions')
      if (response.ok && isMountedRef.current) {
        try {
          const data = await response.json()
          // Nur Permissions aktualisieren, wenn Daten erfolgreich geparst wurden
          setPermissions({
            isAdmin: data.isAdmin || false,
            hasFullAccess: data.hasFullAccess || false,
            accessibleSpaces: Array.isArray(data.accessibleSpaces) ? data.accessibleSpaces : [],
            canCreateSpace: data.permissions?.canCreateSpace || false,
            canDeleteSpace: data.permissions?.canDeleteSpace || false,
            canCreateFqdn: data.permissions?.canCreateFqdn || {},
            canDeleteFqdn: data.permissions?.canDeleteFqdn || {},
            canUploadCSR: data.permissions?.canUploadCSR || {},
            canSignCSR: data.permissions?.canSignCSR || {},
          })
        } catch (parseErr) {
          console.error('Error parsing permissions response:', parseErr)
          // Bei Parse-Fehler Permissions nicht zurücksetzen, nur loggen
        }
      } else if (response.status === 401 && isMountedRef.current) {
        // Bei 401 Unauthorized werden Permissions zurückgesetzt (wird von AuthContext gehandelt)
        console.log('Unauthorized - permissions will be cleared by auth context')
      }
    } catch (err) {
      console.error('Error fetching permissions:', err)
      // Bei Netzwerkfehlern etc. Permissions nicht zurücksetzen
    } finally {
      if (isInitial && isMountedRef.current) {
        setLoading(false)
      }
    }
  }, [isAuthenticated, authFetch])

  // Initiales Laden der Permissions
  useEffect(() => {
    if (isAuthenticated) {
      fetchPermissions(true)
    } else {
      setPermissions({
        isAdmin: false,
        hasFullAccess: false,
        accessibleSpaces: [],
        canCreateSpace: false,
        canDeleteSpace: false,
        canCreateFqdn: {},
        canDeleteFqdn: {},
        canUploadCSR: {},
        canSignCSR: {},
      })
      setLoading(false)
    }
  }, [isAuthenticated, fetchPermissions])

  // Automatisches Neuladen der Permissions im Hintergrund
  useEffect(() => {
    if (!isAuthenticated) {
      return
    }

    // Starte Polling-Intervall
    const startPolling = () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current)
      }
      intervalRef.current = setInterval(() => {
        if (isMountedRef.current && document.visibilityState === 'visible') {
          fetchPermissions(false)
        }
      }, PERMISSIONS_REFRESH_INTERVAL)
    }

    // Handle visibility change - pausiere Polling wenn Tab versteckt ist
    const handleVisibilityChange = () => {
      if (document.hidden) {
        // Tab ist versteckt, stoppe Intervall
        if (intervalRef.current) {
          clearInterval(intervalRef.current)
          intervalRef.current = null
        }
      } else {
        // Tab ist sichtbar, lade Permissions sofort und starte Polling
        if (isMountedRef.current) {
          fetchPermissions(false)
          startPolling()
        }
      }
    }

    // Starte initiales Polling
    startPolling()

    // Event Listener für visibility change
    document.addEventListener('visibilitychange', handleVisibilityChange)

    // Cleanup
    return () => {
      document.removeEventListener('visibilitychange', handleVisibilityChange)
      if (intervalRef.current) {
        clearInterval(intervalRef.current)
        intervalRef.current = null
      }
    }
  }, [isAuthenticated, fetchPermissions])

  // Cleanup beim Unmount
  useEffect(() => {
    isMountedRef.current = true
    return () => {
      isMountedRef.current = false
      if (intervalRef.current) {
        clearInterval(intervalRef.current)
        intervalRef.current = null
      }
    }
  }, [])

  const canCreateSpace = () => permissions.canCreateSpace
  const canDeleteSpace = (spaceId) => permissions.canDeleteSpace
  const canCreateFqdn = (spaceId) => permissions.canCreateFqdn[spaceId] === true
  const canDeleteFqdn = (spaceId) => permissions.canDeleteFqdn[spaceId] === true
  const canUploadCSR = (spaceId) => permissions.canUploadCSR[spaceId] === true
  const canSignCSR = (spaceId) => permissions.canSignCSR[spaceId] === true
  const hasAccessToSpace = (spaceId) => permissions.accessibleSpaces.includes(spaceId)

  // refreshPermissions Funktion, die auch loading state setzt
  const refreshPermissions = useCallback(async () => {
    await fetchPermissions(true)
  }, [fetchPermissions])

  const value = {
    permissions,
    loading,
    refreshPermissions,
    isAdmin: permissions.isAdmin,
    hasFullAccess: permissions.hasFullAccess,
    accessibleSpaces: permissions.accessibleSpaces,
    canCreateSpace,
    canDeleteSpace,
    canCreateFqdn,
    canDeleteFqdn,
    canUploadCSR,
    canSignCSR,
    hasAccessToSpace,
  }

  return <PermissionsContext.Provider value={value}>{children}</PermissionsContext.Provider>
}

export const usePermissions = () => {
  const context = useContext(PermissionsContext)
  if (!context) {
    throw new Error('usePermissions muss innerhalb eines PermissionsProvider verwendet werden')
  }
  return context
}

