{"version":3,"sources":["../../src/hooks/useWallSubmit.ts"],"names":[],"mappings":"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","file":"useWallSubmit.mjs","sourcesContent":["import { useCallback, useState } from 'react';\nimport type { RefObject } from 'react';\nimport type { SceneBackground } from '../types/wall';\n\nexport interface WallSubmitInput {\n  name: string;\n  email: string;\n  message: string;\n  photoUrl: string;\n}\n\nexport interface UseWallSubmitOptions {\n  /** Reference to the in-memory wall token from `useWallToken`. */\n  tokenRef: RefObject<string | null>;\n  /** True when the URL carried a token; only then will the AI scene step run. */\n  aiEnabled: boolean;\n  /** Backgrounds list — one is picked at random for each generation. */\n  backgrounds: SceneBackground[];\n  /** Defaults: '/api/wall', '/api/generate-wall-scene', '/api/wall-scenes'. */\n  postEndpoint?: string;\n  generateEndpoint?: string;\n  scenesEndpoint?: string;\n  /** Called after a successful post (use this to refresh the post list). */\n  onPostCreated?: () => void;\n  /** Called after a successful AI scene generation (use to refresh scenes). */\n  onSceneCreated?: () => void;\n}\n\nexport interface UseWallSubmitResult {\n  submit: (post: WallSubmitInput) => Promise<void>;\n  submitting: boolean;\n  /** True for ~3s after a successful post — useful for a transient \"Posted!\" badge. */\n  submitted: boolean;\n  generating: boolean;\n  generationStatus: string;\n  creditsExhausted: boolean;\n}\n\nconst SUBMITTED_FLASH_MS = 3000;\n\n/**\n * Wraps the standard wall posting flow:\n *   1. POST /api/wall to persist the message + photo.\n *   2. Optionally POST /api/generate-wall-scene (only when `aiEnabled`) to\n *      kick off the credit-metered AI scene generation, passing the in-memory\n *      token from `useWallToken`.\n *   3. POST /api/wall-scenes to persist the generated scene.\n *\n * The hook handles the credits-exhausted signal (`NO_CREDITS` in the response\n * body), the transient submitted/generating UI flags, and the optional\n * onPostCreated / onSceneCreated callbacks for the consumer to refresh state.\n */\nexport function useWallSubmit(opts: UseWallSubmitOptions): UseWallSubmitResult {\n  const postEndpoint = opts.postEndpoint ?? '/api/wall';\n  const generateEndpoint = opts.generateEndpoint ?? '/api/generate-wall-scene';\n  const scenesEndpoint = opts.scenesEndpoint ?? '/api/wall-scenes';\n\n  const [submitting, setSubmitting] = useState(false);\n  const [submitted, setSubmitted] = useState(false);\n  const [generating, setGenerating] = useState(false);\n  const [generationStatus, setGenerationStatus] = useState('');\n  const [creditsExhausted, setCreditsExhausted] = useState(false);\n\n  const submit = useCallback(\n    async (post: WallSubmitInput) => {\n      const { name, email, message, photoUrl } = post;\n      if (!name.trim() || !email.trim() || !message.trim() || !photoUrl) {\n        return;\n      }\n\n      setSubmitting(true);\n      try {\n        const posterName = name.trim();\n        const posterEmail = email.trim();\n        const posterMessage = message.trim();\n        const posterPhotoUrl = photoUrl;\n\n        const res = await fetch(postEndpoint, {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json' },\n          body: JSON.stringify({\n            name: posterName,\n            email: posterEmail,\n            message: posterMessage,\n            photoUrl: posterPhotoUrl,\n          }),\n        });\n        if (!res.ok) throw new Error('Failed');\n\n        opts.onPostCreated?.();\n        setSubmitted(true);\n        setTimeout(() => setSubmitted(false), SUBMITTED_FLASH_MS);\n        setSubmitting(false);\n\n        // AI scene generation runs only when token was captured from URL.\n        if (opts.aiEnabled && !creditsExhausted && opts.backgrounds.length > 0) {\n          setGenerating(true);\n          setGenerationStatus('Creating your AI scene...');\n          try {\n            const bg = opts.backgrounds[Math.floor(Math.random() * opts.backgrounds.length)];\n            const origin = window.location.origin;\n            const fullPhotoUrl = posterPhotoUrl.startsWith('http')\n              ? posterPhotoUrl\n              : origin + posterPhotoUrl;\n            const fullBgUrl = bg.image_url.startsWith('http')\n              ? bg.image_url\n              : origin + bg.image_url;\n\n            const genRes = await fetch(generateEndpoint, {\n              method: 'POST',\n              headers: { 'Content-Type': 'application/json' },\n              body: JSON.stringify({\n                posterName,\n                userEmail: posterEmail,\n                message: posterMessage,\n                photoUrl: fullPhotoUrl,\n                backgroundUrl: fullBgUrl,\n                backgroundDescription: bg.description,\n                token: opts.tokenRef.current || '',\n              }),\n            });\n\n            if (!genRes.ok) {\n              const errText = await genRes.text();\n              if (errText.includes('NO_CREDITS')) {\n                setCreditsExhausted(true);\n              }\n              throw new Error('Generation failed');\n            }\n\n            const genData: {\n              success?: boolean;\n              image_url?: string;\n              credits_remaining?: number;\n            } = await genRes.json();\n\n            if (genData.success && genData.image_url) {\n              setGenerationStatus('Saving scene...');\n              await fetch(scenesEndpoint, {\n                method: 'POST',\n                headers: { 'Content-Type': 'application/json' },\n                body: JSON.stringify({\n                  scene_name: bg.name,\n                  image_url: genData.image_url,\n                  poster_name: posterName,\n                }),\n              });\n\n              if (\n                genData.credits_remaining !== undefined &&\n                genData.credits_remaining <= 0\n              ) {\n                setCreditsExhausted(true);\n              }\n\n              opts.onSceneCreated?.();\n            }\n          } catch {\n            // Scene generation failed — wall post was already saved.\n          } finally {\n            setGenerating(false);\n            setGenerationStatus('');\n          }\n        }\n      } catch {\n        setSubmitting(false);\n      }\n    },\n    [\n      postEndpoint,\n      generateEndpoint,\n      scenesEndpoint,\n      creditsExhausted,\n      opts.aiEnabled,\n      opts.tokenRef,\n      opts.backgrounds,\n      opts.onPostCreated,\n      opts.onSceneCreated,\n    ],\n  );\n\n  return {\n    submit,\n    submitting,\n    submitted,\n    generating,\n    generationStatus,\n    creditsExhausted,\n  };\n}\n"]}