import { ref } from 'vue'
import { useToast } from './useToast'
import { useApi } from './useApi'
import { uniqueConstructeurIds } from '~/shared/constructeurUtils'
import { useConstructeurs, type Constructeur } from './useConstructeurs'
import { extractRelationId, normalizeRelationIds } from '~/shared/apiRelations'
import { extractCollection, extractTotal } from '~/shared/utils/apiHelpers'

export interface Piece {
  id: string
  name: string
  reference?: string | null
  referenceAuto?: string | null
  description?: string | null
  typePieceId?: string | null
  typePiece?: { id: string; name?: string } | null
  productId?: string | null
  productIds?: string[]
  product?: { id: string; name?: string } | null
  constructeurs?: Constructeur[]
  constructeurIds?: string[]
  documents?: unknown[]
  createdAt?: string | null
  updatedAt?: string | null
  [key: string]: unknown
}

interface PieceListResult {
  success: boolean
  data?: { items: Piece[]; total: number; page: number; itemsPerPage: number }
  error?: string
}

interface PieceSingleResult {
  success: boolean
  data?: Piece
  error?: string
}

interface LoadPiecesOptions {
  search?: string
  page?: number
  itemsPerPage?: number
  orderBy?: string
  orderDir?: 'asc' | 'desc'
  typeName?: string
  typePieceId?: string
  force?: boolean
}

const pieces = ref<Piece[]>([])
const total = ref(0)
const loading = ref(false)
const loaded = ref(false)

export function usePieces() {
  const { showSuccess } = useToast()
  const { get, post, patch, delete: del } = useApi()
  const { ensureConstructeurs } = useConstructeurs()

  const withResolvedConstructeurs = async (piece: Piece): Promise<Piece> => {
    if (!piece || typeof piece !== 'object') {
      return piece
    }
    if (!piece.typePieceId) {
      const typePieceId = extractRelationId(piece.typePiece)
      if (typePieceId) {
        piece.typePieceId = typePieceId
      }
    }
    if (!piece.productId) {
      const productId = extractRelationId(piece.product)
      if (productId) {
        piece.productId = productId
      }
    }
    const productIds = Array.isArray(piece.productIds) ? piece.productIds.filter(Boolean) : []
    if (productIds.length === 0 && piece.productId) {
      piece.productIds = [piece.productId]
    } else if (productIds.length > 0) {
      piece.productIds = productIds.map((id) => String(id))
      if (!piece.productId) {
        piece.productId = piece.productIds[0] || null
      }
    }
    const ids = uniqueConstructeurIds(
      piece.constructeurIds,
      piece.constructeurs,
    )
    const hasResolvedConstructeurs =
      Array.isArray(piece.constructeurs) &&
      piece.constructeurs.length > 0 &&
      piece.constructeurs.every((item) => item && typeof item === 'object')

    if (ids.length && !hasResolvedConstructeurs) {
      const resolved = await ensureConstructeurs(ids)
      if (resolved.length) {
        piece.constructeurs = resolved
        piece.constructeurIds = ids
      }
    }
    return piece
  }

  const loadPieces = async (options: LoadPiecesOptions = {}): Promise<PieceListResult> => {
    const {
      search = '',
      page = 1,
      itemsPerPage = 30,
      orderBy = 'name',
      orderDir = 'asc',
      typeName,
      typePieceId,
      force = false,
    } = options

    // Only use cache for unfiltered full-catalog loads
    if (!force && loaded.value && !search && !typeName && !typePieceId && page === 1) {
      return {
        success: true,
        data: { items: pieces.value, total: total.value, page, itemsPerPage },
      }
    }

    // For filtered queries, don't block on global loading state
    if (!typePieceId && loading.value) {
      return {
        success: true,
        data: { items: pieces.value, total: total.value, page, itemsPerPage },
      }
    }

    loading.value = true
    try {
      const params = new URLSearchParams()
      params.set('itemsPerPage', String(itemsPerPage))
      params.set('page', String(page))

      if (search && search.trim()) {
        params.set('search', search.trim())
      }

      if (typeName && typeName.trim()) {
        params.set('typePiece.name', typeName.trim())
      }

      if (typePieceId) {
        params.set('typePiece', typePieceId)
      }

      params.set(`order[${orderBy}]`, orderDir)

      const result = await get(`/pieces?${params.toString()}`)
      if (result.success) {
        const items = extractCollection(result.data)
        const enrichedItems = await Promise.all(items.map((item) => withResolvedConstructeurs(item)))
        const resultTotal = extractTotal(result.data, items.length)

        // Only update global cache for unfiltered queries
        if (!typePieceId) {
          pieces.value = enrichedItems
          total.value = resultTotal
          loaded.value = true
        }

        return {
          success: true,
          data: {
            items: enrichedItems,
            total: resultTotal,
            page,
            itemsPerPage,
          },
        }
      }
      return result as PieceListResult
    } catch (error) {
      console.error('Erreur lors du chargement des pièces:', error)
      return { success: false, error: (error as Error).message }
    } finally {
      loading.value = false
    }
  }

  const createPiece = async (pieceData: Partial<Piece>): Promise<PieceSingleResult> => {
    loading.value = true
    try {
      const { constructeurIds, constructeurs, constructeurId, constructeur, ...cleanPayload } = pieceData as any
      const normalizedPayload = normalizeRelationIds(cleanPayload)
      const result = await post('/pieces', normalizedPayload)
      if (result.success && result.data) {
        const enriched = await withResolvedConstructeurs(result.data as Piece)
        pieces.value.unshift(enriched)
        total.value += 1
        const definition = (pieceData as Record<string, unknown>)?.definition as Record<string, unknown> | undefined
        const displayName =
          (result.data as Piece)?.name ||
          (definition?.name as string | undefined) ||
          pieceData?.name ||
          'Pièce'
        showSuccess(`Pièce "${displayName}" créée avec succès`)
        return { success: true, data: enriched }
      }
      return { success: false, error: result.error }
    } catch (error) {
      console.error('Erreur lors de la création de la pièce:', error)
      return { success: false, error: (error as Error).message }
    } finally {
      loading.value = false
    }
  }

  const updatePieceData = async (id: string, pieceData: Partial<Piece>): Promise<PieceSingleResult> => {
    loading.value = true
    try {
      const { constructeurIds, constructeurs, constructeurId, constructeur, ...cleanPayload } = pieceData as any
      const normalizedPayload = normalizeRelationIds(cleanPayload)
      const result = await patch(`/pieces/${id}`, normalizedPayload)
      if (result.success && result.data) {
        const updated = await withResolvedConstructeurs(result.data as Piece)
        const index = pieces.value.findIndex((piece) => piece.id === id)
        if (index !== -1) {
          pieces.value[index] = updated
        }
        showSuccess(`Pièce "${updated?.name || pieceData.name || ''}" mise à jour avec succès`)
        return { success: true, data: updated }
      }
      return { success: false, error: result.error }
    } catch (error) {
      console.error('Erreur lors de la mise à jour de la pièce:', error)
      return { success: false, error: (error as Error).message }
    } finally {
      loading.value = false
    }
  }

  const deletePiece = async (id: string): Promise<PieceSingleResult> => {
    loading.value = true
    try {
      const result = await del(`/pieces/${id}`)
      if (result.success) {
        const deletedPiece = pieces.value.find((piece) => piece.id === id)
        pieces.value = pieces.value.filter((piece) => piece.id !== id)
        total.value = Math.max(0, total.value - 1)
        showSuccess(`Pièce "${deletedPiece?.name || 'inconnu'}" supprimée avec succès`)
        return { success: true }
      }
      return { success: false, error: result.error }
    } catch (error) {
      console.error('Erreur lors de la suppression de la pièce:', error)
      return { success: false, error: (error as Error).message }
    } finally {
      loading.value = false
    }
  }

  const getPieces = () => pieces.value
  const isLoading = () => loading.value

  const clearPiecesCache = () => {
    pieces.value = []
    total.value = 0
    loaded.value = false
  }

  return {
    pieces,
    total,
    loading,
    loaded,
    loadPieces,
    createPiece,
    updatePiece: updatePieceData,
    deletePiece,
    getPieces,
    isLoading,
    clearPiecesCache,
  }
}
