import { ref } from 'vue' import { useApi } from './useApi' import { useToast } from './useToast' import { extractCollection } from '~/shared/utils/apiHelpers' export interface CommentDocument { id: string name: string filename: string mimeType: string size: number type: string fileUrl: string downloadUrl: string createdAt: string } export interface Comment { id: string content: string entityType: string entityId: string entityName?: string | null authorId: string authorName: string status: 'open' | 'resolved' resolvedById?: string | null resolvedByName?: string | null resolvedAt?: string | null createdAt: string updatedAt: string documents?: CommentDocument[] } interface CommentResult { success: boolean data?: Comment | Comment[] error?: string } interface CommentListResult { success: boolean data?: Comment[] total?: number error?: string } export function useComments() { const { get, post, patch, postFormData, delete: del } = useApi() const { showSuccess, showError } = useToast() const loading = ref(false) const fetchComments = async ( entityType: string, entityId: string, status: string = 'open', ): Promise => { loading.value = true try { const result = await get(`/comments/by-entity/${entityType}/${entityId}?status=${status}`) if (result.success) { const items = (result.data ?? []) as Comment[] return { success: true, data: items } } return { success: false, error: result.error } } catch (error) { const err = error as Error return { success: false, error: err.message } } finally { loading.value = false } } const fetchAllComments = async (options: { status?: string entityType?: string entityName?: string page?: number itemsPerPage?: number orderBy?: string orderDir?: string } = {}): Promise => { loading.value = true try { const params = new URLSearchParams() if (options.status) params.set('status', options.status) if (options.entityType) params.set('entityType', options.entityType) if (options.entityName) params.set('entityName', options.entityName) params.set('sort', options.orderBy || 'createdAt') params.set('direction', options.orderDir || 'desc') params.set('itemsPerPage', String(options.itemsPerPage || 30)) params.set('page', String(options.page || 1)) const result = await get<{ items: Comment[]; total: number }>(`/comments/search/list?${params.toString()}`) if (result.success && result.data) { const data = result.data as { items: Comment[]; total: number } return { success: true, data: data.items, total: data.total } } return { success: false, error: result.error } } catch (error) { const err = error as Error return { success: false, error: err.message } } finally { loading.value = false } } const createComment = async ( entityType: string, entityId: string, content: string, entityName?: string, files?: File[], ): Promise => { loading.value = true try { let result if (files && files.length > 0) { const formData = new FormData() formData.append('content', content) formData.append('entityType', entityType) formData.append('entityId', entityId) if (entityName) formData.append('entityName', entityName) for (const file of files) { formData.append('files[]', file) } result = await postFormData('/comments', formData) } else { const payload: Record = { entityType, entityId, content } if (entityName) payload.entityName = entityName result = await post('/comments', payload) } if (result.success) { showSuccess('Commentaire ajouté') return { success: true, data: result.data as Comment } } if (result.error) showError(result.error) return { success: false, error: result.error } } catch (error) { const err = error as Error showError('Impossible d\'ajouter le commentaire') return { success: false, error: err.message } } finally { loading.value = false } } const resolveComment = async (commentId: string): Promise => { loading.value = true try { const result = await patch(`/comments/${commentId}/resolve`) if (result.success) { showSuccess('Commentaire résolu') return { success: true, data: result.data as Comment } } if (result.error) showError(result.error) return { success: false, error: result.error } } catch (error) { const err = error as Error showError('Impossible de résoudre le commentaire') return { success: false, error: err.message } } finally { loading.value = false } } const deleteComment = async (commentId: string): Promise => { loading.value = true try { const result = await del(`/comments/${commentId}`) if (result.success) { showSuccess('Commentaire supprimé') return { success: true } } if (result.error) showError(result.error) return { success: false, error: result.error } } catch (error) { const err = error as Error showError('Impossible de supprimer le commentaire') return { success: false, error: err.message } } finally { loading.value = false } } const fetchUnresolvedCount = async (): Promise => { try { const result = await get<{ count: number }>('/comments/stats/unresolved-count') if (result.success && result.data) { return result.data.count } return 0 } catch { return 0 } } return { loading, fetchComments, fetchAllComments, createComment, resolveComment, deleteComment, fetchUnresolvedCount, } }