import { nextTick } from 'vue' export function useAdminCustomItems({ api, toast, customItems, customItemPage, customItemLimit, customItemPageCount, customItemQuery, customItemFilter, customItemModalOpen, customItemDeleteModalOpen, customItemModalHistoryActive, modalTargetCustomItem, customItemModalDraftLabel, customItemModalLabelSaving, customItemModalTargetTemplateId, templates, selectedTemplateId, refreshCustomItems, loadTemplate, setTab, selectAdminTemplate, resetMessages, success, error, }) { function submitCustomItemSearch() { customItemPage.value = 1 refreshCustomItems() } function changeCustomItemFilter(filter) { customItemFilter.value = filter customItemPage.value = 1 refreshCustomItems() } function changeCustomItemLimit(limit) { customItemLimit.value = limit customItemPage.value = 1 refreshCustomItems() } function moveCustomItemPage(direction) { const nextPage = customItemPage.value + direction if (nextPage < 1 || nextPage > customItemPageCount.value) return customItemPage.value = nextPage refreshCustomItems() } function pushCustomItemModalHistoryState() { if (typeof window === 'undefined') return window.history.pushState({ ...(window.history.state || {}), adminCustomItemModal: true }, '', window.location.href) customItemModalHistoryActive.value = true } function openCustomItemModal(item) { modalTargetCustomItem.value = item || null customItemModalDraftLabel.value = item?.label || '' customItemModalTargetTemplateId.value = '' customItemModalOpen.value = true pushCustomItemModalHistoryState() } function closeCustomItemModal({ fromPopState = false } = {}) { customItemModalOpen.value = false customItemDeleteModalOpen.value = false modalTargetCustomItem.value = null customItemModalDraftLabel.value = '' customItemModalLabelSaving.value = false customItemModalTargetTemplateId.value = '' if (fromPopState) { customItemModalHistoryActive.value = false return } if (customItemModalHistoryActive.value && typeof window !== 'undefined') { customItemModalHistoryActive.value = false window.history.back() } } function openCustomItemDeleteModal(item) { if (!item) return if (item.sourceType === 'user' && (item.usageCount > 0 || item.linkedTemplates.length > 0)) { error.value = '사용 중이거나 템플릿에 연결된 사용자 업로드 이미지는 먼저 참조를 정리해야 삭제할 수 있어요.' return } modalTargetCustomItem.value = item customItemDeleteModalOpen.value = true } function closeCustomItemDeleteModal() { customItemDeleteModalOpen.value = false } function jumpToTemplateAdmin(templateId) { if (!templateId) return closeCustomItemModal() setTab('template-admin') nextTick(() => { selectAdminTemplate(templateId) }) } async function removeCustomItem(item = modalTargetCustomItem.value) { resetMessages() if (!item) return if (item.sourceType === 'user' && (item.usageCount > 0 || item.linkedTemplates.length > 0)) { error.value = '사용 중이거나 템플릿에 연결된 사용자 업로드 이미지는 먼저 참조를 정리해야 삭제할 수 있어요.' return } try { await api.deleteAdminCustomItem(item.id) closeCustomItemDeleteModal() closeCustomItemModal() await refreshCustomItems() success.value = item.sourceType === 'template' ? '선택한 템플릿 아이템을 제거했어요.' : item.sourceType === 'asset' ? '선택한 이미지 자산을 삭제했어요.' : '사용자 업로드 이미지를 삭제했어요.' } catch (e) { error.value = item.sourceType === 'template' ? '템플릿 아이템 제거에 실패했어요.' : item.sourceType === 'asset' ? '이미지 자산 삭제에 실패했어요.' : '사용자 업로드 이미지 삭제에 실패했어요.' } } async function removeUnusedCustomItems() { resetMessages() const ok = window.confirm('현재 검색 조건에 맞는 미사용 커스텀 이미지를 모두 삭제할까요?') if (!ok) return try { const data = await api.deleteAdminUnusedCustomItems({ q: customItemQuery.value }) await refreshCustomItems() success.value = `${data.deletedCount || 0}개의 미사용 사용자 업로드 이미지를 삭제했어요.` } catch (e) { error.value = '미사용 커스텀 이미지 일괄 삭제에 실패했어요.' } } async function saveCustomItemModalLabel() { const item = modalTargetCustomItem.value const nextLabel = customItemModalDraftLabel.value.trim().slice(0, 60) if (!item || !nextLabel || nextLabel === item.label || customItemModalLabelSaving.value) return try { customItemModalLabelSaving.value = true const data = await api.updateAdminCustomItemLabel(item.id, { label: nextLabel, sourceType: item.sourceType }) item.label = data.item?.label || nextLabel customItemModalDraftLabel.value = item.label customItems.value = customItems.value.map((entry) => (entry.id === item.id ? { ...entry, label: item.label } : entry)) toast.success('아이템 이름을 변경했어요.') } catch (e) { error.value = '아이템 이름 변경에 실패했어요.' } finally { customItemModalLabelSaving.value = false } } async function promoteCustomItem(item) { resetMessages() if (!customItemModalTargetTemplateId.value) { error.value = '추가할 템플릿을 먼저 선택해주세요.' return } try { item.isPromoting = true await api.promoteAdminTemplateItem(item.id, { topicId: customItemModalTargetTemplateId.value }) const targetTemplateName = templates.value.find((template) => template.id === customItemModalTargetTemplateId.value)?.name || customItemModalTargetTemplateId.value if (selectedTemplateId.value === customItemModalTargetTemplateId.value) await loadTemplate() closeCustomItemModal() success.value = `"${item.label}" 이미지를 ${targetTemplateName} 템플릿으로 추가했어요.` } catch (e) { error.value = '선택한 이미지를 템플릿으로 추가하지 못했어요.' } finally { item.isPromoting = false } } return { submitCustomItemSearch, changeCustomItemFilter, changeCustomItemLimit, moveCustomItemPage, pushCustomItemModalHistoryState, openCustomItemModal, closeCustomItemModal, openCustomItemDeleteModal, closeCustomItemDeleteModal, jumpToTemplateAdmin, removeCustomItem, removeUnusedCustomItems, saveCustomItemModalLabel, promoteCustomItem, } }