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

const STORAGE_KEY = 'librairie-promotions'

function loadPromotions() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY)
    if (raw === null) return []
    const parsed = JSON.parse(raw)
    return Array.isArray(parsed) ? parsed : []
  } catch {
    return []
  }
}

function savePromotions(promotions) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(promotions))
}

function normalizeCode(code) {
  return String(code || '')
    .trim()
    .toUpperCase()
    .replace(/\s+/g, '')
}

const PromotionsContext = createContext(null)

export function PromotionsProvider({ children }) {
  const [promotions, setPromotions] = useState(loadPromotions)

  useEffect(() => {
    savePromotions(promotions)
  }, [promotions])

  const createPromotion = useCallback((promo) => {
    const code = normalizeCode(promo.code)
    const value = Number(promo.value)
    if (!code) throw new Error('Code promo invalide')
    if (!Number.isFinite(value) || value <= 0) {
      throw new Error('Valeur de promo invalide')
    }

    setPromotions((prev) => {
      if (prev.some((p) => p.code === code)) {
        throw new Error('Ce code promo existe déjà')
      }
      const next = [
        ...prev,
        {
          id: crypto.randomUUID(),
          code,
          type: 'percent',
          value,
          active: true,
          createdAt: new Date().toISOString(),
        },
      ]
      return next
    })
  }, [])

  const setPromotionActive = useCallback((code, active) => {
    const normalized = normalizeCode(code)
    setPromotions((prev) =>
      prev.map((p) => (p.code === normalized ? { ...p, active } : p)),
    )
  }, [])

  const removePromotion = useCallback((code) => {
    const normalized = normalizeCode(code)
    setPromotions((prev) => prev.filter((p) => p.code !== normalized))
  }, [])

  const getActivePromotionByCode = useCallback(
    (code) => {
      const normalized = normalizeCode(code)
      return promotions.find((p) => p.code === normalized && p.active) || null
    },
    [promotions],
  )

  const value = useMemo(
    () => ({
      promotions,
      createPromotion,
      removePromotion,
      setPromotionActive,
      getActivePromotionByCode,
      normalizeCode,
    }),
    [
      promotions,
      createPromotion,
      removePromotion,
      setPromotionActive,
      getActivePromotionByCode,
    ],
  )

  return (
    <PromotionsContext.Provider value={value}>
      {children}
    </PromotionsContext.Provider>
  )
}

// eslint-disable-next-line react-refresh/only-export-components
export function usePromotions() {
  const ctx = useContext(PromotionsContext)
  if (!ctx) {
    throw new Error('usePromotions doit être utilisé dans un PromotionsProvider')
  }
  return ctx
}

