import { useEffect, useState } from 'react' import { Link, useParams } from 'react-router-dom' import { Helmet } from 'react-helmet-async' import type { AiHairSimulationDetail } from '../../../services/api/contracts' import { getSimulationById } from '../../../services/api/simulations' import { usePageContext } from '../../../shared/pageContext' import { DEFAULT_USER_AVATAR_URL, LOADING_ANIMATION_URL } from '../../../shared/uiAssets' import { demoSimulationResults, resolveLocalizedTemplateName } from '../../../shared/demoContent' import { ImageLightbox } from '../../../components/common/ImageLightbox' import { DashboardLayout } from '../../../layouts/DashboardLayout' function formatDisplayDate(input: string) { const date = new Date(input) if (Number.isNaN(date.getTime())) return input return `${date.getFullYear()}/${String(date.getMonth() + 1).padStart(2, '0')}/${String(date.getDate()).padStart(2, '0')}` } const demoDetail: AiHairSimulationDetail = { id: '10', createdAt: '2026-07-03T23:52:00', customer: { id: '1', name: '山田', avatar: DEFAULT_USER_AVATAR_URL, phone: '', expectContact: 'NONE' }, originImage: '/images/mvp-simulation-result-10/source-photo.jpg', simulateRemark: null, totalTaskCount: 3, processingTaskCount: 0, successTaskCount: 3, failedTaskCount: 0, overallStatus: 'SUCCESSES', tasks: demoSimulationResults.map((item, index) => ({ id: item.id, templateId: item.id, templateName: item.title, templateCoverUrl: item.image, templateCategory: 'MEDIUM', templateSource: 'SYSTEM', taskId: `demo-${index}`, taskStatus: 'SUCCESSES', resultImages: [item.image], errorMsg: null, taskStartTime: '2026-07-03T23:52:00', taskFinishTime: '2026-07-03T23:52:10', })), } export function SimulationResultPage() { const { simulationId = '' } = useParams() const { locale, path, copy } = usePageContext() const pageCopy = copy.simulationResultPage const [detail, setDetail] = useState(simulationId === '10' ? demoDetail : null) const [loading, setLoading] = useState(simulationId !== '10') const [error, setError] = useState('') const [preview, setPreview] = useState<{ image: string; alt: string } | null>(null) useEffect(() => { if (simulationId === '10') { setDetail(demoDetail) setLoading(false) return undefined } let cancelled = false let timer: number | undefined const load = async () => { try { const data = await getSimulationById(simulationId) if (cancelled) return setDetail(data) setError('') setLoading(false) if (data.overallStatus === 'PROCESSING') timer = window.setTimeout(() => void load(), 5000) } catch (loadError) { if (cancelled) return setError(loadError instanceof Error ? loadError.message : pageCopy.loadFailed) setLoading(false) } } void load() return () => { cancelled = true if (timer) window.clearTimeout(timer) } }, [pageCopy.loadFailed, simulationId]) const backTarget = detail?.customer ? path(`/customers/${detail.customer.id}`) : path('/simulation') const customerName = simulationId === '10' ? pageCopy.demoCustomerName || detail?.customer?.name : detail?.customer?.name return ( {`Aitori Stylist | ${pageCopy.title}`}
{pageCopy.back}
{error ?

{error}

: null} {loading ?
{pageCopy.card.processing}

{pageCopy.loading}

: null} {detail ?

{pageCopy.results.title}

{pageCopy.results.count.replace('{{count}}', String(detail.totalTaskCount))}
{detail.tasks.map((task) => { const image = task.resultImages[0] || task.templateCoverUrl || '/images/aitori-simulation-result.png' const templateName = task.templateSource === 'SYSTEM' ? resolveLocalizedTemplateName(task.templateName, task.templateNameI18n, locale, copy.systemTemplateNames) : resolveLocalizedTemplateName(task.templateName, task.templateNameI18n, locale) return

{templateName}

{task.templateSource === 'SYSTEM' ? pageCopy.source.system : pageCopy.source.stylist}{task.taskStatus === 'PROCESSING' ? {pageCopy.card.loadingAlt : null}

{task.taskStatus === 'FAILED' ? task.errorMsg || pageCopy.card.failed : task.taskStatus === 'PROCESSING' ? pageCopy.card.processing : pageCopy.card.success}

})}
: null}
setPreview(null)} />
) }