import type { Match3DAgentSessionSnapshot } from '../../../packages/shared/src/contracts/match3dAgent'; import type { Match3DRunSnapshot } from '../../../packages/shared/src/contracts/match3dRuntime'; import type { Match3DGeneratedBackgroundAsset, Match3DGeneratedItemAsset, Match3DWorkProfile, Match3DWorkSummary, } from '../../../packages/shared/src/contracts/match3dWorks'; import { hasMatch3DGeneratedImageAsset, mergeMatch3DGeneratedItemAssetsForRuntime, normalizeMatch3DGeneratedItemAssetsForRuntime, } from '../../services/match3dGeneratedModelCache'; import { isMatch3DGalleryEntry, mapMatch3DWorkToPlatformGalleryCard, type PlatformPublicGalleryCard, } from '../rpg-entry/rpgEntryWorldPresentation'; export function mapMatch3DWorkToPublicWorkDetail( item: Match3DWorkSummary, ): PlatformPublicGalleryCard { return mapMatch3DWorkToPlatformGalleryCard( normalizeMatch3DWorkForRuntimeUi(item), ); } export function mapPublicWorkDetailToMatch3DWork( entry: PlatformPublicGalleryCard, ): Match3DWorkSummary | null { if (!isMatch3DGalleryEntry(entry)) { return null; } return promoteMatch3DGeneratedBackgroundAsset({ workId: entry.workId, profileId: entry.profileId, ownerUserId: entry.ownerUserId, sourceSessionId: 'sourceSessionId' in entry && typeof entry.sourceSessionId === 'string' ? entry.sourceSessionId : null, gameName: entry.worldName, themeText: entry.themeTags[0] ?? '经典消除', summary: entry.summaryText, tags: entry.themeTags, coverImageSrc: entry.coverImageSrc, referenceImageSrc: null, clearCount: 12, difficulty: 4, publicationStatus: 'published', playCount: entry.playCount ?? 0, updatedAt: entry.updatedAt, publishedAt: entry.publishedAt, publishReady: true, backgroundPrompt: entry.backgroundPrompt ?? null, backgroundImageSrc: entry.backgroundImageSrc ?? null, backgroundImageObjectKey: entry.backgroundImageObjectKey ?? null, generatedBackgroundAsset: entry.generatedBackgroundAsset ?? findMatch3DGeneratedBackgroundAsset(entry.generatedItemAssets) ?? null, generatedItemAssets: normalizeMatch3DGeneratedItemAssetsForRuntime( entry.generatedItemAssets ?? [], ), }); } export function findMatch3DGeneratedBackgroundAsset( generatedItemAssets: readonly Match3DGeneratedItemAsset[] | null | undefined, ): Match3DGeneratedBackgroundAsset | null { return ( generatedItemAssets ?.map((asset) => asset.backgroundAsset ?? null) .find(Boolean) ?? null ); } export function promoteMatch3DGeneratedBackgroundAsset< T extends Pick< Match3DWorkSummary, | 'backgroundPrompt' | 'backgroundImageSrc' | 'backgroundImageObjectKey' | 'generatedBackgroundAsset' | 'generatedItemAssets' >, >(profile: T): T { const backgroundAsset = profile.generatedBackgroundAsset ?? findMatch3DGeneratedBackgroundAsset(profile.generatedItemAssets); if (!backgroundAsset) { return profile; } return { ...profile, backgroundPrompt: profile.backgroundPrompt ?? backgroundAsset.prompt ?? null, backgroundImageSrc: profile.backgroundImageSrc ?? backgroundAsset.imageSrc ?? backgroundAsset.imageObjectKey ?? null, backgroundImageObjectKey: profile.backgroundImageObjectKey ?? backgroundAsset.imageObjectKey ?? backgroundAsset.imageSrc ?? null, generatedBackgroundAsset: profile.generatedBackgroundAsset ?? backgroundAsset, }; } export function normalizeMatch3DWorkForRuntimeUi( profile: T, ): T { return promoteMatch3DGeneratedBackgroundAsset({ ...profile, generatedItemAssets: normalizeMatch3DGeneratedItemAssetsForRuntime( profile.generatedItemAssets, ), }); } export function mapMatch3DWorksForRuntimeUi( profiles: readonly T[], ): T[] { return profiles.map(normalizeMatch3DWorkForRuntimeUi); } export function buildMatch3DProfileFromSession( session: Match3DAgentSessionSnapshot | null, ): Match3DWorkProfile | null { const draft = session?.draft; if (!session || !draft?.profileId) { return null; } const now = session.updatedAt || new Date().toISOString(); const generatedItemAssets = normalizeMatch3DGeneratedItemAssetsForRuntime( draft.generatedItemAssets, ); return promoteMatch3DGeneratedBackgroundAsset({ workId: draft.profileId, profileId: draft.profileId, ownerUserId: 'current-user', sourceSessionId: session.sessionId, gameName: draft.gameName, themeText: draft.themeText, summary: draft.summary ?? draft.summaryText ?? '', tags: draft.tags, coverImageSrc: draft.coverImageSrc ?? draft.referenceImageSrc ?? null, referenceImageSrc: draft.referenceImageSrc ?? null, clearCount: draft.clearCount, difficulty: draft.difficulty, publicationStatus: 'draft', playCount: 0, updatedAt: now, publishedAt: null, publishReady: Boolean(draft.publishReady), backgroundPrompt: draft.backgroundPrompt ?? null, backgroundImageSrc: draft.backgroundImageSrc ?? null, backgroundImageObjectKey: draft.backgroundImageObjectKey ?? null, generatedBackgroundAsset: draft.generatedBackgroundAsset ?? null, generatedItemAssets, }); } export function hasMatch3DRuntimeAsset( assets: readonly Match3DGeneratedItemAsset[] | null | undefined, ) { return hasMatch3DGeneratedImageAsset(assets); } export function hasMatch3DRuntimeBackgroundAsset( profile: Pick< Match3DWorkSummary, | 'backgroundImageSrc' | 'backgroundImageObjectKey' | 'generatedBackgroundAsset' | 'generatedItemAssets' >, ) { return Boolean( profile.backgroundImageSrc?.trim() || profile.backgroundImageObjectKey?.trim() || profile.generatedBackgroundAsset?.imageSrc?.trim() || profile.generatedBackgroundAsset?.imageObjectKey?.trim() || profile.generatedBackgroundAsset?.containerImageSrc?.trim() || profile.generatedBackgroundAsset?.containerImageObjectKey?.trim() || profile.generatedItemAssets?.some( (asset) => asset.backgroundAsset?.imageSrc?.trim() || asset.backgroundAsset?.imageObjectKey?.trim() || asset.backgroundAsset?.containerImageSrc?.trim() || asset.backgroundAsset?.containerImageObjectKey?.trim(), ), ); } export function resolveMatch3DRuntimeGeneratedItemAssets( run: Match3DRunSnapshot | null, profile: Match3DWorkProfile | null, publicWorkDetail: PlatformPublicGalleryCard | null, ) { const runProfileId = run?.profileId?.trim() ?? ''; const profileAssets = profile?.generatedItemAssets ?? []; const publicDetailAssets = publicWorkDetail && isMatch3DGalleryEntry(publicWorkDetail) ? (publicWorkDetail.generatedItemAssets ?? []) : []; if (runProfileId && profile?.profileId === runProfileId) { if (hasMatch3DRuntimeAsset(profileAssets)) { return normalizeMatch3DGeneratedItemAssetsForRuntime(profileAssets); } if ( publicWorkDetail && isMatch3DGalleryEntry(publicWorkDetail) && publicWorkDetail.profileId === runProfileId ) { return hasMatch3DRuntimeAsset(publicDetailAssets) ? mergeMatch3DGeneratedItemAssetsForRuntime( publicDetailAssets, profileAssets, ) : normalizeMatch3DGeneratedItemAssetsForRuntime(profileAssets); } return normalizeMatch3DGeneratedItemAssetsForRuntime(profileAssets); } if ( runProfileId && publicWorkDetail && isMatch3DGalleryEntry(publicWorkDetail) && publicWorkDetail.profileId === runProfileId ) { return normalizeMatch3DGeneratedItemAssetsForRuntime(publicDetailAssets); } if (hasMatch3DRuntimeAsset(profileAssets)) { return normalizeMatch3DGeneratedItemAssetsForRuntime(profileAssets); } return publicDetailAssets.length > 0 ? normalizeMatch3DGeneratedItemAssetsForRuntime(publicDetailAssets) : normalizeMatch3DGeneratedItemAssetsForRuntime(profileAssets); } export function resolveMatch3DRuntimeGeneratedBackgroundAsset( run: Match3DRunSnapshot | null, profile: Match3DWorkProfile | null, publicWorkDetail: PlatformPublicGalleryCard | null, ) { const runProfileId = run?.profileId?.trim() ?? ''; const profileBackground = profile ? (promoteMatch3DGeneratedBackgroundAsset(profile) .generatedBackgroundAsset ?? null) : null; const publicBackground = publicWorkDetail && isMatch3DGalleryEntry(publicWorkDetail) ? (promoteMatch3DGeneratedBackgroundAsset(publicWorkDetail) .generatedBackgroundAsset ?? null) : null; if (runProfileId && profile?.profileId === runProfileId) { return profileBackground ?? publicBackground; } if ( runProfileId && publicWorkDetail && isMatch3DGalleryEntry(publicWorkDetail) && publicWorkDetail.profileId === runProfileId ) { return publicBackground ?? profileBackground; } return profileBackground ?? publicBackground; } export function resolveActiveMatch3DRuntimeProfile( run: Match3DRunSnapshot | null, runtimeProfile: Match3DWorkProfile | null, profile: Match3DWorkProfile | null, ) { const runProfileId = run?.profileId?.trim() ?? ''; if (runProfileId && runtimeProfile?.profileId === runProfileId) { return runtimeProfile; } if (runProfileId && profile?.profileId === runProfileId) { return profile; } return runtimeProfile ?? profile; } export function resolveMatch3DRuntimeBackgroundImageSrc( run: Match3DRunSnapshot | null, profile: Match3DWorkProfile | null, publicWorkDetail: PlatformPublicGalleryCard | null, ) { const runProfileId = run?.profileId?.trim() ?? ''; const resolvedProfile = profile ? promoteMatch3DGeneratedBackgroundAsset(profile) : null; const resolvedPublicWork = publicWorkDetail && isMatch3DGalleryEntry(publicWorkDetail) ? promoteMatch3DGeneratedBackgroundAsset(publicWorkDetail) : null; const profileBackground = resolvedProfile?.backgroundImageSrc?.trim() || resolvedProfile?.generatedBackgroundAsset?.imageSrc?.trim() || resolvedProfile?.backgroundImageObjectKey?.trim() || resolvedProfile?.generatedBackgroundAsset?.imageObjectKey?.trim() || ''; const publicBackground = resolvedPublicWork?.backgroundImageSrc?.trim() || resolvedPublicWork?.generatedBackgroundAsset?.imageSrc?.trim() || resolvedPublicWork?.backgroundImageObjectKey?.trim() || resolvedPublicWork?.generatedBackgroundAsset?.imageObjectKey?.trim() || ''; if (runProfileId && profile?.profileId === runProfileId) { return profileBackground || publicBackground || null; } if ( runProfileId && publicWorkDetail && isMatch3DGalleryEntry(publicWorkDetail) && publicWorkDetail.profileId === runProfileId ) { return publicBackground || profileBackground || null; } return profileBackground || publicBackground || null; }