"use client"

import { useCallback, useState } from "react"
import { api } from "@/lib/api"
import { ENDPOINTS } from "@/constants/endpoints"
import type { PaginatedResponse, OutboundOrder, PurchaseReturn, PlatformAllocation } from "@/types"

function unwrap<T>(value: any): T {
  return value && typeof value === "object" && "data" in value ? value.data : (value as T)
}

export function useOutboundOrders() {
  const [items, setItems] = useState<OutboundOrder[]>([])
  const [selected, setSelected] = useState<OutboundOrder | null>(null)
  const [total, setTotal] = useState(0)
  const [pages, setPages] = useState(1)
  const [isLoading, setIsLoading] = useState(false)
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const list = useCallback(async (filters: any = {}) => {
    setIsLoading(true); setError(null)
    try {
      const res = unwrap<PaginatedResponse<OutboundOrder>>(await api.get(ENDPOINTS.OUTBOUND_ORDERS.LIST, { params: filters }))
      setItems(res.items ?? []); setTotal(res.total ?? 0); setPages(res.pages ?? 1)
      return res
    } catch (err: any) { setError(err?.response?.data?.detail || err?.message); return null }
    finally { setIsLoading(false) }
  }, [])

  const get = useCallback(async (id: string) => {
    setIsLoading(true); setError(null)
    try {
      const order = unwrap<OutboundOrder>(await api.get(ENDPOINTS.OUTBOUND_ORDERS.GET_BY_ID(id)))
      setSelected(order); return order
    } catch (err: any) { setError(err?.response?.data?.detail || err?.message); return null }
    finally { setIsLoading(false) }
  }, [])

  const create = useCallback(async (payload: any) => {
    setIsSubmitting(true)
    try { return unwrap<OutboundOrder>(await api.post(ENDPOINTS.OUTBOUND_ORDERS.CREATE_FROM_SOURCE, payload)) }
    finally { setIsSubmitting(false) }
  }, [])

  const act = useCallback(async (id: string, action: string, extra?: Record<string, any>) => {
    const e = ENDPOINTS.OUTBOUND_ORDERS
    const map: Record<string, string> = { approve: e.APPROVE(id), pick: e.PICK(id), dispatch: e.DISPATCH(id), confirm_handover: e.CONFIRM_HANDOVER(id), close: e.CLOSE(id) }
    setIsSubmitting(true)
    try { return unwrap<OutboundOrder>(await api.post(map[action], extra ?? {})) }
    finally { setIsSubmitting(false) }
  }, [])

  return { items, selected, total, pages, isLoading, isSubmitting, error, list, get, create, act }
}

export function usePurchaseReturns() {
  const [items, setItems] = useState<PurchaseReturn[]>([])
  const [selected, setSelected] = useState<PurchaseReturn | null>(null)
  const [total, setTotal] = useState(0)
  const [pages, setPages] = useState(1)
  const [isLoading, setIsLoading] = useState(false)
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const list = useCallback(async (filters: any = {}) => {
    setIsLoading(true); setError(null)
    try {
      const res = unwrap<PaginatedResponse<PurchaseReturn>>(await api.get(ENDPOINTS.PURCHASE_RETURNS.LIST, { params: filters }))
      setItems(res.items ?? []); setTotal(res.total ?? 0); setPages(res.pages ?? 1)
      return res
    } catch (err: any) { setError(err?.response?.data?.detail || err?.message); return null }
    finally { setIsLoading(false) }
  }, [])

  const get = useCallback(async (id: string) => {
    setIsLoading(true); setError(null)
    try {
      const ret = unwrap<PurchaseReturn>(await api.get(ENDPOINTS.PURCHASE_RETURNS.GET_BY_ID(id)))
      setSelected(ret); return ret
    } catch (err: any) { setError(err?.response?.data?.detail || err?.message); return null }
    finally { setIsLoading(false) }
  }, [])

  const create = useCallback(async (payload: any) => {
    setIsSubmitting(true)
    try { return unwrap<PurchaseReturn>(await api.post(ENDPOINTS.PURCHASE_RETURNS.CREATE, payload)) }
    finally { setIsSubmitting(false) }
  }, [])

  const act = useCallback(async (id: string, action: string, reason?: string) => {
    const e = ENDPOINTS.PURCHASE_RETURNS
    const map: Record<string, string> = { approve: e.APPROVE(id), prepare_dispatch: e.PREPARE_DISPATCH(id), post_outbound: e.POST_OUTBOUND(id), reverse: e.REVERSE(id), close: e.CLOSE(id) }
    const body = action === "reverse" ? { reason: reason || "" } : {}
    setIsSubmitting(true)
    try { return unwrap<PurchaseReturn>(await api.post(map[action], body)) }
    finally { setIsSubmitting(false) }
  }, [])

  return { items, selected, total, pages, isLoading, isSubmitting, error, list, get, create, act }
}

export function usePlatformAllocations() {
  const [items, setItems] = useState<PlatformAllocation[]>([])
  const [selected, setSelected] = useState<PlatformAllocation | null>(null)
  const [total, setTotal] = useState(0)
  const [pages, setPages] = useState(1)
  const [isLoading, setIsLoading] = useState(false)
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const list = useCallback(async (filters: any = {}) => {
    setIsLoading(true); setError(null)
    try {
      const res = unwrap<PaginatedResponse<PlatformAllocation>>(await api.get(ENDPOINTS.PLATFORM_ALLOCATIONS.LIST, { params: filters }))
      setItems(res.items ?? []); setTotal(res.total ?? 0); setPages(res.pages ?? 1)
      return res
    } catch (err: any) { setError(err?.response?.data?.detail || err?.message); return null }
    finally { setIsLoading(false) }
  }, [])

  const get = useCallback(async (id: string) => {
    setIsLoading(true); setError(null)
    try {
      const alloc = unwrap<PlatformAllocation>(await api.get(ENDPOINTS.PLATFORM_ALLOCATIONS.GET_BY_ID(id)))
      setSelected(alloc); return alloc
    } catch (err: any) { setError(err?.response?.data?.detail || err?.message); return null }
    finally { setIsLoading(false) }
  }, [])

  const create = useCallback(async (payload: any) => {
    setIsSubmitting(true)
    try { return unwrap<PlatformAllocation>(await api.post(ENDPOINTS.PLATFORM_ALLOCATIONS.CREATE, payload)) }
    finally { setIsSubmitting(false) }
  }, [])

  const act = useCallback(async (id: string, action: string) => {
    const e = ENDPOINTS.PLATFORM_ALLOCATIONS
    const map: Record<string, string> = { approve: e.APPROVE(id), post: e.POST(id), withdraw: e.WITHDRAW(id), close: e.CLOSE(id) }
    setIsSubmitting(true)
    try { return unwrap<PlatformAllocation>(await api.post(map[action], {})) }
    finally { setIsSubmitting(false) }
  }, [])

  return { items, selected, total, pages, isLoading, isSubmitting, error, list, get, create, act }
}