'use client' import { useState } from 'react' import { useTranslations } from 'next-intl' import { AppIcon } from '@/components/ui/icons' import { shouldShowError } from '@/lib/error-utils' import TaskStatusInline from '@/components/task/TaskStatusInline' import { resolveTaskPresentationState } from '@/lib/task/presentation' import { useAiModifyProjectPropDescription, useAiModifyPropDescription, useAssetActions, } from '@/lib/query/hooks' import { AiModifyDescriptionField } from './AiModifyDescriptionField' export interface PropEditModalProps { mode: 'asset-hub' | 'project' propId: string propName: string summary: string description: string variantId?: string projectId?: string onClose: () => void onRefresh?: () => void } export function PropEditModal({ mode, propId, propName, summary, description, variantId, projectId, onClose, onRefresh, }: PropEditModalProps) { const t = useTranslations('assets') const actions = useAssetActions({ scope: mode === 'asset-hub' ? 'global' : 'project', projectId, kind: 'prop', }) const [editingName, setEditingName] = useState(propName) const [editingSummary, setEditingSummary] = useState(summary) const [editingDescription, setEditingDescription] = useState(description) const [aiModifyInstruction, setAiModifyInstruction] = useState('') const [isAiModifying, setIsAiModifying] = useState(false) const [isSaving, setIsSaving] = useState(false) const aiModifyingState = isAiModifying ? resolveTaskPresentationState({ phase: 'processing', intent: 'modify', resource: 'image', hasOutput: true, }) : null const savingState = isSaving ? resolveTaskPresentationState({ phase: 'processing', intent: 'process', resource: 'text', hasOutput: false, }) : null const aiModifyAssetHub = useAiModifyPropDescription() const aiModifyProject = useAiModifyProjectPropDescription(projectId ?? '') const getErrorMessage = (error: unknown, fallback: string) => { if (error instanceof Error && error.message) return error.message return fallback } const persist = async () => { await actions.update(propId, { name: editingName.trim(), summary: editingSummary.trim(), }) if (variantId) { await actions.updateVariant(propId, variantId, { description: editingDescription.trim(), }) } onRefresh?.() } const handleAiModify = async () => { if (!aiModifyInstruction.trim()) return false try { setIsAiModifying(true) const data = mode === 'asset-hub' ? await aiModifyAssetHub.mutateAsync({ propId, variantId, currentDescription: editingDescription, modifyInstruction: aiModifyInstruction, }) : await aiModifyProject.mutateAsync({ propId, variantId, currentDescription: editingDescription, modifyInstruction: aiModifyInstruction, }) if (data?.modifiedDescription) { setEditingDescription(data.modifiedDescription) setAiModifyInstruction('') return true } return false } catch (error: unknown) { if (shouldShowError(error)) { alert(`${t('modal.modifyFailed')}: ${getErrorMessage(error, t('errors.failed'))}`) } return false } finally { setIsAiModifying(false) } } const handleSaveOnly = async () => { if (!editingName.trim() || !editingSummary.trim() || !editingDescription.trim()) return try { setIsSaving(true) await persist() onClose() } finally { setIsSaving(false) } } const handleSaveAndGenerate = async () => { if (!editingName.trim() || !editingSummary.trim() || !editingDescription.trim()) return try { setIsSaving(true) await persist() await actions.generate({ id: propId }) onClose() } finally { setIsSaving(false) } } return (