import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from 'react'

import { getMySites, type MeSiteRow } from '../api/backend'

export const SITE_STORAGE_KEY = 'ems.selected_site_id'

export type SiteSelectionContextValue = {
  sites: MeSiteRow[]
  selectedSiteId: number | null
  setSelectedSiteId: (id: number) => void
  ready: boolean
  error: string | null
}

const SiteSelectionContext = createContext<SiteSelectionContextValue | null>(null)

export function SiteSelectionProvider({ children }: { children: ReactNode }) {
  const [sites, setSites] = useState<MeSiteRow[]>([])
  const [selectedSiteId, setSelectedSiteIdState] = useState<number | null>(null)
  const [ready, setReady] = useState(false)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      try {
        const list = await getMySites()
        if (cancelled) return
        setSites(list)
        if (list.length === 0) {
          setError('Žádná aktivní lokalita')
          setSelectedSiteIdState(null)
        } else {
          setError(null)
          const raw = localStorage.getItem(SITE_STORAGE_KEY)
          const parsed = raw != null ? Number.parseInt(raw, 10) : Number.NaN
          const valid = Number.isFinite(parsed) && list.some((s) => s.id === parsed)
          setSelectedSiteIdState(valid ? parsed : list[0]!.id)
        }
      } catch {
        if (!cancelled) {
          setSites([])
          setSelectedSiteIdState(null)
          setError('Lokality se nepodařilo načíst')
        }
      } finally {
        if (!cancelled) setReady(true)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [])

  const setSelectedSiteId = useCallback((id: number) => {
    setSelectedSiteIdState(id)
    localStorage.setItem(SITE_STORAGE_KEY, String(id))
  }, [])

  const value = useMemo(
    (): SiteSelectionContextValue => ({
      sites,
      selectedSiteId,
      setSelectedSiteId,
      ready,
      error,
    }),
    [sites, selectedSiteId, setSelectedSiteId, ready, error],
  )

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

export function useSiteSelection(): SiteSelectionContextValue {
  const ctx = useContext(SiteSelectionContext)
  if (ctx == null) {
    throw new Error('useSiteSelection must be used within SiteSelectionProvider')
  }
  return ctx
}
