import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from 'react'
import api from '../utils/api'
import { activeClubMemberships } from '../utils/activeClub'

const OrgInboxContext = createContext(null)

export function canAccessOrgInbox(user) {
  if (!user?.id) return false
  if (user.role === 'admin' || user.role === 'superadmin') return true
  return activeClubMemberships(user.clubs).some((c) => (c.roles || []).includes('club_admin'))
}

function canSeeContentReports(user) {
  if (user?.role === 'admin' || user?.role === 'superadmin') return true
  return activeClubMemberships(user?.clubs || []).some((c) => (c.roles || []).includes('club_admin'))
}

/** Nach Annahme/Ablehnung: Posteingang-Badges & Widget aktualisieren */
export function notifyOrgInboxChanged() {
  window.dispatchEvent(new Event('shinkan:inbox-changed'))
}

export function OrgInboxProvider({ user, children }) {
  const [items, setItems] = useState([])
  const [contentReports, setContentReports] = useState([])
  const [contentReportsError, setContentReportsError] = useState(null)
  const canAccess = useMemo(() => canAccessOrgInbox(user), [user])
  const canAccessReports = useMemo(() => canSeeContentReports(user), [user])

  const refresh = useCallback(async () => {
    if (!canAccess) {
      setItems([])
    } else {
      try {
        const data = await api.getInboxJoinRequests()
        setItems(Array.isArray(data) ? data : [])
      } catch {
        setItems([])
      }
    }

    if (!canAccessReports) {
      setContentReports([])
      setContentReportsError(null)
    } else {
      try {
        const data = await api.getInboxContentReports()
        setContentReports(Array.isArray(data) ? data : [])
        setContentReportsError(null)
      } catch (err) {
        setContentReports([])
        setContentReportsError(err?.message || String(err))
      }
    }
  }, [canAccess, canAccessReports])

  useEffect(() => {
    if (!canAccess && !canAccessReports) {
      setItems([])
      setContentReports([])
      setContentReportsError(null)
      return undefined
    }
    let cancelled = false
    ;(async () => {
      if (canAccess) {
        try {
          const data = await api.getInboxJoinRequests()
          if (!cancelled) setItems(Array.isArray(data) ? data : [])
        } catch {
          if (!cancelled) setItems([])
        }
      }
      if (canAccessReports) {
        try {
          const data = await api.getInboxContentReports()
          if (!cancelled) {
            setContentReports(Array.isArray(data) ? data : [])
            setContentReportsError(null)
          }
        } catch (err) {
          if (!cancelled) {
            setContentReports([])
            setContentReportsError(err?.message || String(err))
          }
        }
      }
    })()
    return () => {
      cancelled = true
    }
  }, [canAccess, canAccessReports, user?.id])

  useEffect(() => {
    const onChange = () => { refresh() }
    window.addEventListener('shinkan:inbox-changed', onChange)
    return () => window.removeEventListener('shinkan:inbox-changed', onChange)
  }, [refresh])

  const value = useMemo(
    () => ({
      inboxJoinRequests: items,
      inboxCount: items.length,
      contentReports,
      contentReportCount: contentReports.filter((r) => r.status === 'submitted').length,
      contentReportsError,
      refreshOrgInbox: refresh,
      canAccessOrgInbox: canAccess,
      canAccessContentReports: canAccessReports,
      isSuperadmin: user?.role === 'superadmin',
      isPlatformAdmin: user?.role === 'admin' || user?.role === 'superadmin',
      isClubAdmin: activeClubMemberships(user?.clubs || []).some((c) => (c.roles || []).includes('club_admin')),
    }),
    [items, contentReports, contentReportsError, refresh, canAccess, canAccessReports, user?.role, user?.clubs]
  )

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

export function useOrgInbox() {
  const ctx = useContext(OrgInboxContext)
  if (!ctx) {
    throw new Error('useOrgInbox must be used within OrgInboxProvider')
  }
  return ctx
}
