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

const STORAGE_KEY = 'librairie-orders'

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

function saveOrders(orders) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(orders))
}

function round2(n) {
  return Math.round((Number(n) + Number.EPSILON) * 100) / 100
}

function calcSubtotal(items) {
  return round2(
    items.reduce((sum, it) => sum + Number(it.unitPrice) * Number(it.qty), 0),
  )
}

function calcDiscount({ subtotal, promotion }) {
  if (!promotion) return 0
  if (promotion.type === 'percent') {
    const pct = Number(promotion.value)
    if (!Number.isFinite(pct) || pct <= 0) return 0
    return round2((subtotal * pct) / 100)
  }
  return 0
}

const OrdersContext = createContext(null)

export function OrdersProvider({ children }) {
  const [orders, setOrders] = useState(loadOrders)

  useEffect(() => {
    saveOrders(orders)
  }, [orders])

  /**
   * Équivalent local d’un POST /api/orders.
   * orderDraft: { items: [{ bookId, title, unitPrice, qty }], promotion?: { code, type, value } }
   */
  const createOrder = useCallback((orderDraft) => {
    const items = Array.isArray(orderDraft?.items) ? orderDraft.items : []
    const cleaned = items
      .map((it) => ({
        bookId: String(it.bookId),
        title: String(it.title || ''),
        unitPrice: Number(it.unitPrice),
        qty: Math.max(0, Math.trunc(Number(it.qty) || 0)),
      }))
      .filter((it) => it.bookId && it.qty > 0 && Number.isFinite(it.unitPrice))

    if (cleaned.length === 0) {
      throw new Error('Aucun article dans la commande')
    }

    const subtotal = calcSubtotal(cleaned)
    const promotion = orderDraft?.promotion
      ? {
          code: String(orderDraft.promotion.code || ''),
          type: String(orderDraft.promotion.type || 'percent'),
          value: Number(orderDraft.promotion.value),
        }
      : null
    const discount = calcDiscount({ subtotal, promotion })
    const total = round2(Math.max(0, subtotal - discount))

    const order = {
      id: crypto.randomUUID(),
      createdAt: new Date().toISOString(),
      items: cleaned,
      promotion: promotion && promotion.code ? promotion : null,
      subtotal,
      discount,
      total,
    }

    setOrders((prev) => [order, ...prev])
    return order
  }, [])

  const value = useMemo(() => ({ orders, createOrder }), [orders, createOrder])

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

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

