import { ArrowLeft, CheckCircle2, ImagePlus, Loader2, Play, Sparkles, Waves, } from 'lucide-react'; import { useMemo, useState } from 'react'; import type { BigFishAssetSlotResponse, BigFishGameDraftResponse, BigFishLevelBlueprintResponse, BigFishSessionSnapshotResponse, ExecuteBigFishActionRequest, } from '../../../packages/shared/src/contracts/bigFish'; import { ResolvedAssetImage } from '../ResolvedAssetImage'; type BigFishAssetStudioTarget = | { kind: 'level_main_image'; level: BigFishLevelBlueprintResponse; } | { kind: 'level_motion'; level: BigFishLevelBlueprintResponse; motionKey: 'idle_float' | 'move_swim'; } | { kind: 'stage_background'; }; type BigFishResultViewProps = { session: BigFishSessionSnapshotResponse; isBusy?: boolean; error?: string | null; onBack: () => void; onExecuteAction: (payload: ExecuteBigFishActionRequest) => void; onStartTestRun: () => void; }; function findAssetSlot( slots: BigFishAssetSlotResponse[], assetKind: string, level?: number, motionKey?: string, ) { return slots.find((slot) => { if (slot.assetKind !== assetKind) { return false; } if (level !== undefined && slot.level !== level) { return false; } if (motionKey !== undefined && slot.motionKey !== motionKey) { return false; } return true; }); } function assetReadyLabel(slot: BigFishAssetSlotResponse | undefined) { if (slot?.status !== 'ready') { return '待生成'; } return isBigFishPlaceholderAsset(slot) ? '占位已生成' : '已生成'; } function buildLevelAssetPreview(slot: BigFishAssetSlotResponse | undefined) { if (slot?.assetUrl) { return slot.assetUrl; } return null; } function isBigFishPlaceholderAsset(slot: BigFishAssetSlotResponse | undefined) { return Boolean(slot?.assetUrl?.includes('/generated-big-fish/')); } function buildStudioAssetPreview( slots: BigFishAssetSlotResponse[], target: BigFishAssetStudioTarget, ) { if (target.kind === 'stage_background') { return buildLevelAssetPreview(findAssetSlot(slots, 'stage_background')); } if (target.kind === 'level_main_image') { return buildLevelAssetPreview( findAssetSlot(slots, 'level_main_image', target.level.level), ); } return buildLevelAssetPreview( findAssetSlot( slots, 'level_motion', target.level.level, target.motionKey, ), ); } function BigFishAssetStudioModal({ draft, target, previewUrl, isBusy, onClose, onExecuteAction, }: { draft: BigFishGameDraftResponse; target: BigFishAssetStudioTarget; previewUrl?: string | null; isBusy: boolean; onClose: () => void; onExecuteAction: (payload: ExecuteBigFishActionRequest) => void; }) { const title = target.kind === 'stage_background' ? '场地背景工坊' : target.kind === 'level_main_image' ? `Lv.${target.level.level} 主图工坊` : `Lv.${target.level.level} 动作工坊`; const prompt = target.kind === 'stage_background' ? draft.background.backgroundPromptSeed : target.kind === 'level_main_image' ? target.level.visualPromptSeed : `${target.level.motionPromptSeed} / ${target.motionKey}`; const execute = () => { if (target.kind === 'stage_background') { onExecuteAction({ action: 'big_fish_generate_stage_background' }); return; } if (target.kind === 'level_main_image') { onExecuteAction({ action: 'big_fish_generate_level_main_image', level: target.level.level, }); return; } onExecuteAction({ action: 'big_fish_generate_level_motion', level: target.level.level, motionKey: target.motionKey, }); }; return (