"use client"

import { useCallback, useState } from "react"
import { api } from "@/lib/api"
import { ENDPOINTS } from "@/constants/endpoints"
import type {
  AccountingPreview,
  AdvancePayment,
  AdvancePaymentPayload,
  PaginatedResponse,
  PurchaseOrder,
  PurchaseOrderCreatePayload,
  PurchaseOrderFilters,
  PurchaseOrderStatusHistory,
  PurchaseOrderUpdatePayload,
} from "@/types"

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

export function usePurchaseOrders() {
  const [items, setItems] = useState<PurchaseOrder[]>([])
  const [selected, setSelected] = useState<PurchaseOrder | null>(null)
  const [history, setHistory] = useState<PurchaseOrderStatusHistory[]>([])
  const [accountingPreview, setAccountingPreview] = useState<AccountingPreview | 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: PurchaseOrderFilters = {}) => {
    setIsLoading(true)
    setError(null)
    try {
      const res = unwrap<PaginatedResponse<PurchaseOrder>>(await api.get(ENDPOINTS.PURCHASE_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 || "Failed to load purchase orders")
      return null
    } finally {
      setIsLoading(false)
    }
  }, [])

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

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

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

  const act = useCallback(async (id: string, action: string, note?: string, reason?: string) => {
    const e = ENDPOINTS.PURCHASE_ORDERS
    const endpointMap: Record<string, string> = {
      submit_review: e.SUBMIT_REVIEW(id),
      submit_approval: e.SUBMIT_APPROVAL(id),
      approve: e.APPROVE(id),
      send_to_supplier: e.SEND_TO_SUPPLIER(id),
      cancel: e.CANCEL(id),
      close: e.CLOSE(id),
    }
    const body = action === "cancel" ? { reason: reason || note } : { note: note || null }
    setIsSubmitting(true)
    try {
      return unwrap<PurchaseOrder>(await api.post(endpointMap[action], body))
    } finally {
      setIsSubmitting(false)
    }
  }, [])

  const recordAdvancePayment = useCallback(async (id: string, payload: AdvancePaymentPayload) => {
    setIsSubmitting(true)
    try {
      return unwrap<AdvancePayment>(await api.post(ENDPOINTS.PURCHASE_ORDERS.RECORD_ADVANCE_PAYMENT(id), payload))
    } finally {
      setIsSubmitting(false)
    }
  }, [])

  const getAccountingPreview = useCallback(async (id: string) => {
    try {
      const preview = unwrap<AccountingPreview>(await api.get(ENDPOINTS.PURCHASE_ORDERS.ACCOUNTING_PREVIEW(id)))
      setAccountingPreview(preview)
      return preview
    } catch (err: any) {
      setError(err?.response?.data?.detail || err?.message || "Failed to load accounting preview")
      return null
    }
  }, [])

  const getStatusHistory = useCallback(async (id: string) => {
    try {
      const res = await api.get(ENDPOINTS.PURCHASE_ORDERS.STATUS_HISTORY(id))
      const data = unwrap<any[]>(res)
      setHistory(data)
      return data
    } catch {
      setHistory([])
      return []
    }
  }, [])

  return {
    items,
    selected,
    history,
    accountingPreview,
    total,
    pages,
    isLoading,
    isSubmitting,
    error,
    list,
    get,
    create,
    update,
    act,
    recordAdvancePayment,
    getAccountingPreview,
    getStatusHistory,
  }
}
