"use client"

import { useCallback, useState } from "react"
import { api } from "@/lib/api"
import { ENDPOINTS } from "@/constants/endpoints"
import type {
  PaginatedResponse,
  SupplierShipment,
  SupplierShipmentCreatePayload,
  SupplierShipmentFilters,
  SupplierShipmentUpdatePayload,
} from "@/types"

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

export function useSupplierShipments() {
  const [items, setItems] = useState<SupplierShipment[]>([])
  const [selected, setSelected] = useState<SupplierShipment | 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: SupplierShipmentFilters = {}) => {
    setIsLoading(true)
    setError(null)
    try {
      const res = unwrap<PaginatedResponse<SupplierShipment>>(await api.get(ENDPOINTS.SUPPLIER_SHIPMENTS.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 || "Failed to load shipments")
      return null
    } finally {
      setIsLoading(false)
    }
  }, [])

  const get = useCallback(async (id: string) => {
    setIsLoading(true)
    setError(null)
    try {
      const shipment = unwrap<SupplierShipment>(await api.get(ENDPOINTS.SUPPLIER_SHIPMENTS.GET_BY_ID(id)))
      setSelected(shipment)
      return shipment
    } catch (err: any) {
      setError(err?.response?.data?.detail || err?.message || "Failed to load shipment")
      return null
    } finally {
      setIsLoading(false)
    }
  }, [])

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

  const update = useCallback(async (id: string, payload: SupplierShipmentUpdatePayload) => {
    setIsSubmitting(true)
    try {
      return unwrap<SupplierShipment>(await api.patch(ENDPOINTS.SUPPLIER_SHIPMENTS.UPDATE(id), payload))
    } finally {
      setIsSubmitting(false)
    }
  }, [])

  const act = useCallback(async (id: string, action: string, note?: string) => {
    const e = ENDPOINTS.SUPPLIER_SHIPMENTS
    const endpointMap: Record<string, string> = {
      confirm_dispatch: e.CONFIRM_DISPATCH(id),
      mark_arrived: e.MARK_ARRIVED(id),
      cancel: e.CANCEL(id),
      close: e.CLOSE(id),
      link_to_receiving: e.LINK_TO_RECEIVING(id),
    }
    const body = { note: note || null }
    setIsSubmitting(true)
    try {
      return unwrap<SupplierShipment>(await api.post(endpointMap[action], body))
    } finally {
      setIsSubmitting(false)
    }
  }, [])

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