'use client'

import { useState, useRef, useCallback, ChangeEvent, useEffect } from 'react'
import Image from 'next/image'
import ReactCrop, { Crop, PixelCrop, centerCrop, makeAspectCrop } from 'react-image-crop'
import { archetypes } from '@/data/archetypes'
import { PRIME_AURA_COLORS } from '@/lib/primePrompt'
import styles from './Forge.module.css'

function centerAspectCrop(mediaWidth: number, mediaHeight: number, aspect: number) {
  // Ensure minimum crop size to prevent handle overlap
  const minWidth = Math.max(50, mediaWidth * 0.3); // At least 50px or 30% of width
  const minHeight = Math.max(50, mediaHeight * 0.3); // At least 50px or 30% of height
  
  return centerCrop(
    makeAspectCrop({ 
      unit: '%', 
      width: Math.min(90, (minWidth / mediaWidth) * 100),
      height: Math.min(90, (minHeight / mediaHeight) * 100)
    }, aspect, mediaWidth, mediaHeight),
    mediaWidth,
    mediaHeight
  )
}

export default function Forge() {
  const [uploadedImage, setUploadedImage] = useState<string | null>(null)
  const [croppedImage, setCroppedImage] = useState<string | null>(null)
  const [finalImageForApi, setFinalImageForApi] = useState<string | null>(null)
  const [generatedImage, setGeneratedImage] = useState<string | null>(null)
  const [generatedBlob, setGeneratedBlob] = useState<Blob | null>(null)
  
  // Advanced Controls State
  const [selectedArchetype, setSelectedArchetype] = useState<string>('forged')
  const [selectedTier, setSelectedTier] = useState<'subtle' | 'core' | 'apex'>('core')
  const [selectedGrain, setSelectedGrain] = useState<'clean' | 'gritty' | 'filthy'>('gritty')
  const [selectedRain, setSelectedRain] = useState<'none' | 'light' | 'storm'>('light')
  const [selectedAuraColor, setSelectedAuraColor] = useState<string>('void-silver')
  const [selectedAspect, setSelectedAspect] = useState<'full' | 'square' | 'portrait'>('full')

  const [isLoading, setIsLoading] = useState(false)
  const [loadingStatus, setLoadingStatus] = useState<'queued' | 'processing' | 'finalizing'>('queued')
  const [loadingProgress, setLoadingProgress] = useState(0)
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [isSharing, setIsSharing] = useState(false)
  const [submitted, setSubmitted] = useState(false)
  const [galleryUrl, setGalleryUrl] = useState<string | null>(null)
  const [shareUrl, setShareUrl] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [crop, setCrop] = useState<Crop>()
  const [completedCrop, setCompletedCrop] = useState<PixelCrop>()
  const fileInputRef = useRef<HTMLInputElement>(null)
  const cameraInputRef = useRef<HTMLInputElement>(null)
  const imgRef = useRef<HTMLImageElement>(null)

  // Cleanup object URLs on component unmount
  useEffect(() => {
    return () => {
      // Cleanup object URLs on component unmount
      if (generatedImage) {
        URL.revokeObjectURL(generatedImage);
      }
    };
  }, [generatedImage]);

  const CONTRACT_ADDRESS = 'D8WDarzRHYpW5VkbwiRTuWCLzerAdwFw5PNkivkYpump'
  const MAX_FILE_SIZE = 20 * 1024 * 1024 // 20MB - increased for higher resolution
  const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/gif']

  const PRIME_TAGLINES = [
    'We already know the truth.',
    'Understanding is irreversible.',
    "What's seen cannot be unseen.",
    'Pressure revealed the structure.',
    'The mask burned. This remained.',
    'No going back. Only forward.',
    'Forged, not manufactured.',
    'Clarity has no undo button.',
    'The real was always underneath.',
    'Some transformations are permanent.',
    "Truth doesn't negotiate.",
    'Built different. Proven same.',
    'The noise stopped. This stayed.',
    'Earned, not given.',
    "What survives is what's real.",
  ]

  const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file) return

    if (!ALLOWED_TYPES.includes(file.type)) {
      setError('Please upload a valid image (JPEG, PNG, WebP, or GIF)')
      return
    }

    if (file.size > MAX_FILE_SIZE) {
      setError('Image too large. Please upload an image under 20MB.')
      return
    }

    const reader = new FileReader()
    reader.onloadend = () => {
      setUploadedImage(reader.result as string)
      setCroppedImage(null)
      setGeneratedImage(null)
      setShareUrl(null)
      setError(null)
    }
    reader.readAsDataURL(file)
  }

  const aspectRatio = selectedAspect === 'full' ? undefined : (selectedAspect === 'square' ? 1 : 3 / 4)

  const onImageLoad = useCallback((e: React.SyntheticEvent<HTMLImageElement>) => {
    const { width, height } = e.currentTarget

    if (selectedAspect === 'full') {
      // Full image - select everything
      setCrop({ unit: '%', x: 0, y: 0, width: 100, height: 100 })
    } else {
      const ratio = selectedAspect === 'square' ? 1 : 3 / 4
      const initialCrop = centerAspectCrop(width, height, ratio)
      setCrop(initialCrop)
    }
  }, [selectedAspect])

  // Update crop when aspect ratio changes
  const handleAspectChange = useCallback((newAspect: 'full' | 'square' | 'portrait') => {
    setSelectedAspect(newAspect)
    if (imgRef.current) {
      const { width, height } = imgRef.current

      if (newAspect === 'full') {
        setCrop({ unit: '%', x: 0, y: 0, width: 100, height: 100 })
      } else {
        const ratio = newAspect === 'square' ? 1 : 3 / 4
        const newCrop = centerAspectCrop(width, height, ratio)
        setCrop(newCrop)
      }
    }
  }, [])

  // Helper to get Base64 PNG directly (Synchronous, Reliable)
  const getCroppedImagePreview = useCallback(async (): Promise<string> => {
    if (!imgRef.current || !crop) {
      return uploadedImage || ''
    }

    const image = imgRef.current
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    if (!ctx) {
      return uploadedImage || ''
    }

    const scaleX = image.naturalWidth / image.width
    const scaleY = image.naturalHeight / image.height

    const cropWidth = (crop.width / 100) * image.width * scaleX
    const cropHeight = (crop.height / 100) * image.height * scaleY
    const cropX = (crop.x / 100) * image.width * scaleX
    const cropY = (crop.y / 100) * image.height * scaleY

    const maxSize = 1024  // Match API expectations

    if (selectedAspect === 'full') {
      // Full mode: always output 1024x1024, maintaining aspect ratio with letterboxing
      const aspectRatioVal = cropWidth / cropHeight
      
      canvas.width = maxSize
      canvas.height = maxSize
      
      if (aspectRatioVal > 1) {
        // Wider than tall - fit width, center vertically
        const scaledHeight = maxSize / aspectRatioVal
        const yOffset = (maxSize - scaledHeight) / 2
        ctx.drawImage(
          image,
          cropX,
          cropY,
          cropWidth,
          cropHeight,
          0,
          yOffset,
          maxSize,
          scaledHeight
        )
      } else {
        // Taller than wide - fit height, center horizontally
        const scaledWidth = maxSize * aspectRatioVal
        const xOffset = (maxSize - scaledWidth) / 2
        ctx.drawImage(
          image,
          cropX,
          cropY,
          cropWidth,
          cropHeight,
          xOffset,
          0,
          scaledWidth,
          maxSize
        )
      }
    } else {
      // Square/Portrait: use the actual crop dimensions without forcing square
      canvas.width = maxSize
      canvas.height = maxSize

      // For square/portrait, center the crop within a square canvas
      const targetSize = Math.min(cropWidth, cropHeight)
      const sourceX = cropX + (cropWidth - targetSize) / 2
      const sourceY = cropY + (cropHeight - targetSize) / 2

      ctx.drawImage(
        image,
        sourceX,
        sourceY,
        targetSize,
        targetSize,
        0,
        0,
        maxSize,
        maxSize
      )
    }

    return canvas.toDataURL('image/jpeg', 0.95)
  }, [crop, uploadedImage, selectedAspect])

  const getCroppedImageBase64 = useCallback(async (): Promise<string> => {
    return new Promise((resolve) => {
      if (!imgRef.current || !crop) {
        resolve(uploadedImage || '')
        return
      }

      const image = imgRef.current
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      if (!ctx) {
        resolve(uploadedImage || '')
        return
      }

      // Calculate actual pixel values from percentages
      const scaleX = image.naturalWidth / image.width
      const scaleY = image.naturalHeight / image.height
      
      const cropX = (crop.x / 100) * image.width * scaleX
      const cropY = (crop.y / 100) * image.height * scaleY
      const cropWidth = (crop.width / 100) * image.width * scaleX
      const cropHeight = (crop.height / 100) * image.height * scaleY
      
      canvas.width = cropWidth
      canvas.height = cropHeight
      
      ctx.drawImage(
        image,
        cropX,
        cropY,
        cropWidth,
        cropHeight,
        0,
        0,
        canvas.width,
        canvas.height
      )
      resolve(canvas.toDataURL('image/jpeg', 0.95))
    })
  }, [crop, uploadedImage])

  const handleCropConfirm = async () => {
    const preview = await getCroppedImagePreview()
    const apiPng = await getCroppedImageBase64()
    
    setCroppedImage(preview)
    setFinalImageForApi(apiPng)
  }

  const fetchWithRetry = async (url: string, options: RequestInit, retries = 2): Promise<Response> => {
    try {
      const response = await fetch(url, options)

      if (response.status === 504 && retries > 0) {
        const delay = Math.pow(2, 3 - retries) * 1000
        console.warn(`504 Timeout. Retrying in ${delay}ms...`)
        await new Promise(resolve => setTimeout(resolve, delay))
        return fetchWithRetry(url, options, retries - 1)
      }

      return response
    } catch (error) {
      if (retries > 0) {
        const delay = Math.pow(2, 3 - retries) * 1000
        await new Promise(resolve => setTimeout(resolve, delay))
        return fetchWithRetry(url, options, retries - 1)
      }
      throw error
    }
  }

  const handleTransform = async () => {
    // Use stored PNG from state
    if (!finalImageForApi) return

    setIsLoading(true)
    setLoadingStatus('queued')
    setLoadingProgress(0)
    setError(null)

    try {
      const payload = {
        image: finalImageForApi,
        tier: selectedTier,
        archetype: selectedArchetype,
        aura_color: selectedAuraColor,
        grain: selectedGrain,
        rain: selectedRain
      }

      // Start Replicate prediction
      const res = await fetch('/api/prime', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      })

      const data = await res.json()
      if (!res.ok) {
        throw new Error(data.error || 'Failed to start transformation')
      }

      const predictionId = data.id
      if (!predictionId) {
        throw new Error('No prediction ID returned')
      }

      // Poll for completion with timeout protection
      let progress = 10
      setLoadingProgress(progress)
      const maxPolls = 60 // ~120 seconds timeout
      let pollCount = 0

      while (pollCount < maxPolls) {
        pollCount++
        await new Promise(resolve => setTimeout(resolve, 2000))

        const pollRes = await fetch(`/api/prime?id=${predictionId}`)
        const pollData = await pollRes.json()
        
        console.log('Poll response:', pollData)

        if (!pollRes.ok) {
          throw new Error(pollData.error || 'Failed to check status')
        }

        // Update progress based on status
        if (pollData.status === 'starting') {
          progress = Math.min(progress + 2, 30)
        } else if (pollData.status === 'processing') {
          setLoadingStatus('processing')
          progress = Math.min(progress + 5, 85)
        }
        setLoadingProgress(progress)

        if (pollData.status === 'succeeded') {
          console.log('SUCCESS: Processing succeeded response:', pollData)
          setLoadingStatus('finalizing')
          setLoadingProgress(95)

          const outputUrl = Array.isArray(pollData.output)
            ? pollData.output[0]
            : pollData.output
          if (!outputUrl) {
            throw new Error('No image returned')
          }

          // Fetch and convert to blob
          const imgRes = await fetch(outputUrl)
          const resultBlob = await imgRes.blob()
          const imageUrl = URL.createObjectURL(resultBlob)

          setLoadingProgress(100)
          setGeneratedImage(imageUrl)
          setGeneratedBlob(resultBlob)
          setShareUrl(null)
          console.log('SUCCESS: Image processed and set')
          return // Return instead of break to avoid timeout
        }

        if (pollData.status === 'failed') {
          console.error('Replicate prediction failed:', pollData.error)
          throw new Error(pollData.error || 'Transformation failed')
        }

        // Log status for debugging
        if (pollCount % 10 === 0) {
          console.log(`Poll ${pollCount}: status=${pollData.status}`)
        }
      }

      throw new Error('Transformation timed out. Please try again.')

    } catch (err) {
      setError(err instanceof Error ? err.message : 'Something went wrong')
    } finally {
      setIsLoading(false)
      setLoadingProgress(0)
    }
  }

  const downloadWatermarkedImage = async () => {
    if (!generatedImage || !generatedBlob) return

    await document.fonts.ready

    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    if (!ctx) return

    const img = new window.Image()
    img.crossOrigin = 'anonymous'
    await new Promise((resolve) => {
        img.onload = resolve
        img.src = generatedImage
    })

    canvas.width = img.width
    canvas.height = img.height

    ctx.drawImage(img, 0, 0)

    ctx.textAlign = 'right'
    ctx.font = '700 24px "Space Mono"'
    ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'
    ctx.fillText('$PRIME', canvas.width - 20, canvas.height - 20)

    const link = document.createElement('a')
    link.download = `my-prime-${Date.now()}.png`
    link.href = canvas.toDataURL('image/png')
    link.click()
  }

  const generateTradingCard = async () => {
    if (!generatedImage || !generatedBlob) return

    await document.fonts.ready

    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    if (!ctx) return

    const width = 1000
    const height = 1500
    canvas.width = width
    canvas.height = height

    const gradient = ctx.createLinearGradient(0, 0, 0, height)
    gradient.addColorStop(0, '#0a0a0a')
    gradient.addColorStop(1, '#000000')
    ctx.fillStyle = gradient
    ctx.fillRect(0, 0, width, height)

    for (let i = 0; i < 50000; i++) {
        ctx.fillStyle = `rgba(255, 255, 255, ${Math.random() * 0.03})`
        ctx.fillRect(Math.random() * width, Math.random() * height, 2, 2)
    }

    const img = new window.Image()
    img.crossOrigin = 'anonymous'
    await new Promise((resolve) => {
        img.onload = resolve
        img.src = generatedImage
    })

    const imgSize = 860
    const imgX = (width - imgSize) / 2
    const imgY = 120 
    
    ctx.shadowColor = '#4a9eff'
    ctx.shadowBlur = 40
    ctx.fillStyle = '#000'
    ctx.fillRect(imgX - 5, imgY - 5, imgSize + 10, imgSize + 10)
    ctx.shadowBlur = 0

    ctx.drawImage(img, imgX, imgY, imgSize, imgSize)

    ctx.textAlign = 'center'

    const arch = archetypes.find(a => a.id === selectedArchetype)
    const title = arch ? arch.title : 'PRIME'
    const tagline = PRIME_TAGLINES[Math.floor(Math.random() * PRIME_TAGLINES.length)]

    ctx.font = '700 80px Rajdhani'
    ctx.fillStyle = '#fff'
    ctx.shadowColor = 'rgba(255, 255, 255, 0.5)'
    ctx.shadowBlur = 20
    ctx.fillText(title, width / 2, 1070)
    ctx.shadowBlur = 0

    // Tagline
    ctx.font = 'italic 28px Rajdhani'
    ctx.fillStyle = '#888'
    ctx.fillText(`"${tagline}"`, width / 2, 1120)

    const rollStat = (bonus: number) => Math.floor(50 + Math.random() * 30 + (Math.random() * bonus))

    const stats = arch ? arch.stats : { presence: 0, will: 0, force: 0, focus: 0 }
    const presence = rollStat(stats.presence)
    const will = rollStat(stats.will)
    const force = rollStat(stats.force)
    const focus = rollStat(stats.focus)

    const startY = 1200
    const labels = ['PRESENCE', 'WILL', 'FORCE', 'FOCUS']
    const values = [presence, will, force, focus]

    const statWidth = 160
    const startX = (width - (statWidth * 4)) / 2 + (statWidth / 2)

    labels.forEach((label, i) => {
        const x = startX + (i * statWidth)
        
        ctx.font = '700 24px "Space Mono"'
        ctx.fillStyle = '#666'
        ctx.fillText(label, x, startY)

        ctx.font = '700 48px "Space Mono"'
        ctx.fillStyle = values[i] > 90 ? '#d4a574' : '#fff'
        ctx.fillText(values[i].toString(), x, startY + 50)
    })

    ctx.strokeStyle = '#333'
    ctx.lineWidth = 2
    ctx.beginPath()
    ctx.moveTo(200, 1340)
    ctx.lineTo(800, 1340)
    ctx.stroke()

    ctx.font = '700 40px "Space Mono"'
    ctx.fillStyle = '#4a9eff'
    ctx.fillText('$PRIME', width / 2, 1410)

    ctx.font = '500 30px Rajdhani'
    ctx.fillStyle = '#555'
    ctx.fillText('primeonsol.com', width / 2, 1465)

    const link = document.createElement('a')
    link.download = `prime-card-${Date.now()}.png`
    link.href = canvas.toDataURL('image/png')
    link.click()
  }

  const handleShare = async () => {
    if (!generatedImage) return

    setIsSharing(true)
    try {
      let publicUrl = shareUrl
      if (!publicUrl) {
        const blob = generatedBlob || await (await fetch(generatedImage)).blob()
        const formData = new FormData()
        formData.append('image', blob, 'prime-share.png')

        const response = await fetch('/api/share', {
          method: 'POST',
          body: formData
        })

        if (!response.ok) {
          const errorData = await response.json();
          throw new Error(errorData.error || 'Failed to upload image for sharing');
        }

        const data = await response.json()
        if (data.imageUrl) {
          publicUrl = data.imageUrl
          setShareUrl(publicUrl)
        }
      }
      const text = encodeURIComponent(`I revealed my PRIME.\n\n$PRIME\n${CONTRACT_ADDRESS}`)
      const url = encodeURIComponent(publicUrl || window.location.href)
      window.open(`https://twitter.com/intent/tweet?text=${text}&url=${url}`, '_blank')
    } catch (error) {
      setError(error instanceof Error ? error.message : 'Failed to share image');
    } finally {
      setIsSharing(false)
    }
  }

  const handleSubmitToGallery = async () => {
    if (!generatedImage || isSubmitting || submitted) return

    setIsSubmitting(true)
    try {
      const blob = generatedBlob || await (await fetch(generatedImage)).blob()
      const formData = new FormData()
      formData.append('image', blob, 'prime-gallery.png')

      const response = await fetch('/api/gallery', {
        method: 'POST',
        body: formData
      })

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.error || 'Failed to submit to gallery');
      }

      const data = await response.json()
      if (data.image?.image_url) {
        setGalleryUrl(data.image.image_url)
      }
      setSubmitted(true)
    } catch (error) {
      setError(error instanceof Error ? error.message : 'Failed to submit to gallery');
    } finally {
      setIsSubmitting(false)
    }
  }

  const handleReset = () => {
    // Revoke object URLs to prevent memory leaks
    if (generatedImage) {
      URL.revokeObjectURL(generatedImage);
    }

    setGeneratedImage(null)
    setUploadedImage(null)
    setCroppedImage(null)
    setFinalImageForApi(null)
    setSubmitted(false)
    setGalleryUrl(null)
    setShareUrl(null)
    setCrop(undefined)
    setCompletedCrop(undefined)
  }

  const getInfoText = () => {
    let tierText = ''
    switch(selectedTier) {
      case 'subtle': tierText = 'Minimal aura, close to the skin.'; break;
      case 'core': tierText = 'Standard intensity, balanced glow.'; break;
      case 'apex': tierText = 'Maximum power, jagged energy spikes.'; break;
    }

    let rainText = ''
    switch(selectedRain) {
      case 'none': rainText = 'Clear visibility.'; break;
      case 'light': rainText = 'Light rain streaks.'; break;
      case 'storm': rainText = 'Heavy storm atmosphere.'; break;
    }

    const arch = archetypes.find(a => a.id === selectedArchetype)
    return (
      <>
        <span className={styles.infoHighlight}>{arch?.name}</span>: {arch?.traits.join(', ')}. <br/>
        <span className={styles.infoHighlight}>{selectedTier.toUpperCase()}</span>: {tierText} <span className={styles.infoHighlight}>{selectedRain.toUpperCase()}</span>: {rainText}
      </>
    )
  }

  return (
    <section className={styles.forge}>
      <div className={styles.grain}></div>
      <div className={styles.lightning}></div>

      {/* Hidden elements to force font loading */}
      <div style={{ visibility: 'hidden', height: 0, position: 'absolute', fontFamily: 'Rajdhani', fontWeight: 700 }}>PRIME</div>
      <div style={{ visibility: 'hidden', height: 0, position: 'absolute', fontFamily: 'Space Mono', fontWeight: 700 }}>PRIME</div>

      <div className={styles.container}>
        <div className={styles.header}>
          <h2 className={styles.title}>Reveal your PRIME.</h2>
          <p className={styles.sub}>What survived is what remains.</p>
        </div>

        <div className={styles.content}>
          <div className={styles.frame}>
            {isLoading ? (
              <div className={styles.loading}>
                <div className={styles.loadingImage}>
                  {(croppedImage || uploadedImage) && (
                    <Image
                      src={croppedImage || uploadedImage!}
                      alt="Processing"
                      fill
                      className={styles.image}
                      unoptimized
                    />
                  )}
                  <div className={styles.loadingOverlay}>
                    <div className={styles.scanLine}></div>
                  </div>
                </div>
                <div className={styles.loadingInfo}>
                  <p className={styles.loadingText}>
                    {loadingStatus === 'queued' && 'Queuing transformation...'}
                    {loadingStatus === 'processing' && 'AI is forging your PRIME...'}
                    {loadingStatus === 'finalizing' && 'Finalizing...'}
                  </p>
                  <div aria-live="polite" className="sr-only">
                    {loadingStatus === 'queued' && 'Queuing transformation...'}
                    {loadingStatus === 'processing' && 'AI is forging your PRIME...'}
                    {loadingStatus === 'finalizing' && 'Finalizing...'}
                  </div>
                  <div className={styles.progressBar}>
                    <div
                      className={styles.progressFill}
                      style={{ width: `${loadingProgress}%` }}
                    />
                  </div>
                  <p className={styles.loadingHint}>This takes 30-60 seconds</p>
                </div>
              </div>
            ) : generatedImage ? (
              <div className={styles.resultImage}>
                <Image
                  src={generatedImage}
                  alt="Your PRIME"
                  fill
                  className={styles.image}
                  unoptimized
                />
              </div>
            ) : croppedImage ? (
              <div className={styles.previewImage}>
                <Image
                  src={croppedImage}
                  alt="Your photo"
                  fill
                  className={styles.image}
                  unoptimized
                />
              </div>
            ) : uploadedImage ? (
              <div className={styles.cropContainer}>
                <div className={styles.cropWrapper}>
                  <div className={styles.simpleCropContainer}>
                    <img
                      ref={imgRef}
                      src={uploadedImage}
                      alt="Crop preview"
                      onLoad={onImageLoad}
                      className={styles.cropImage}
                    />
                    <div className={styles.cropOverlay} style={{
                      top: `${crop?.y || 0}%`,
                      left: `${crop?.x || 0}%`,
                      width: `${crop?.width || 100}%`,
                      height: `${crop?.height || 100}%`
                    }}>
                      <div className={styles.cropHandle} data-handle="nw" />
                      <div className={styles.cropHandle} data-handle="ne" />
                      <div className={styles.cropHandle} data-handle="se" />
                      <div className={styles.cropHandle} data-handle="sw" />
                    </div>
                  </div>
                </div>
              </div>
            ) : (
              <div
                className={styles.upload}
                onClick={() => fileInputRef.current?.click()}
              >
                <label htmlFor="file-upload" style={{ display: 'none' }}>Upload Photo</label>
                <input
                  id="file-upload"
                  name="image"
                  ref={fileInputRef}
                  type="file"
                  accept="image/*"
                  onChange={handleFileChange}
                  className={styles.fileInput}
                />
                <label htmlFor="camera-capture" style={{ display: 'none' }}>Capture from Camera</label>
                <input
                  id="camera-capture"
                  name="camera"
                  ref={cameraInputRef}
                  type="file"
                  accept="image/*"
                  capture="user"
                  onChange={handleFileChange}
                  className={styles.fileInput}
                />
                <div className={styles.uploadIcon}>
                  <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
                    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
                    <polyline points="17 8 12 3 7 8" />
                    <line x1="12" y1="3" x2="12" y2="15" />
                  </svg>
                </div>
                <p>Drop your photo</p>
              </div>
            )}
          </div>

          <div className={styles.interface}>
            {isLoading ? (
              <p className={styles.loadingText}>Revealing your PRIME...</p>
            ) : generatedImage ? (
              <div className={styles.interfaceContent}>
                <div className={styles.resultActions}>
                  <button
                    onClick={downloadWatermarkedImage}
                    className={styles.actionBtn}
                    aria-label="Download watermarked image"
                  >
                    Image
                  </button>
                  <button
                    onClick={generateTradingCard}
                    className={styles.actionBtn}
                    aria-label="Generate trading card"
                  >
                    Card
                  </button>
                  <button
                    onClick={handleShare}
                    className={styles.actionBtn}
                    disabled={isSharing}
                    aria-label={isSharing ? 'Sharing in progress' : 'Share on social media'}
                  >
                    {isSharing ? 'Sharing...' : 'Share'}
                  </button>
                  <button
                    onClick={handleSubmitToGallery}
                    className={`${styles.actionBtn} ${submitted ? styles.submitted : ''}`}
                    disabled={isSubmitting || submitted}
                    aria-label={isSubmitting ? 'Submission in progress' : submitted ? 'Already added to gallery' : 'Add to gallery'}
                  >
                    {isSubmitting ? '...' : submitted ? 'Added' : 'Gallery'}
                  </button>
                </div>
                <button onClick={handleReset} className={styles.resetBtn} aria-label="Start over with a new image">
                  Start Over
                </button>
              </div>
            ) : croppedImage ? (
              <div className={styles.interfaceContent}>
                <div className={styles.advancedControls}>
                  <div className={styles.controlRow}>
                    <div className={styles.controlGroup}>
                      <label htmlFor="archetype-select">Archetype</label>
                      <div className={styles.selectWrapper}>
                        <select
                          id="archetype-select"
                          name="archetype"
                          value={selectedArchetype}
                          onChange={(e) => setSelectedArchetype(e.target.value)}
                          className={styles.select}
                          aria-label="Select archetype"
                        >
                          {archetypes.map(a => (
                            <option key={a.id} value={a.id}>{a.name}</option>
                          ))}
                        </select>
                      </div>
                    </div>
                    <div className={styles.controlGroup}>
                      <label htmlFor="aura-select">Aura</label>
                      <div className={styles.selectWrapper}>
                        <select
                          id="aura-select"
                          name="aura"
                          value={selectedAuraColor}
                          onChange={(e) => setSelectedAuraColor(e.target.value)}
                          className={styles.select}
                          aria-label="Select aura color"
                        >
                          {PRIME_AURA_COLORS.map(color => (
                            <option key={color} value={color}>
                              {color.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')}
                            </option>
                          ))}
                        </select>
                      </div>
                    </div>
                  </div>
                  <div className={styles.controlRow}>
                    <div className={styles.controlGroup}>
                      <span className={styles.controlLabel}>Intensity</span>
                      <div className={styles.toggleGroup}>
                        <button
                          className={`${styles.toggleBtn} ${selectedTier === 'subtle' ? styles.active : ''}`}
                          onClick={() => setSelectedTier('subtle')}
                          aria-pressed={selectedTier === 'subtle'}
                        >Subtle</button>
                        <button
                          className={`${styles.toggleBtn} ${selectedTier === 'core' ? styles.active : ''}`}
                          onClick={() => setSelectedTier('core')}
                          aria-pressed={selectedTier === 'core'}
                        >Core</button>
                        <button
                          className={`${styles.toggleBtn} ${selectedTier === 'apex' ? styles.active : ''}`}
                          onClick={() => setSelectedTier('apex')}
                          aria-pressed={selectedTier === 'apex'}
                        >Apex</button>
                      </div>
                    </div>
                    <div className={styles.controlGroup}>
                      <span className={styles.controlLabel}>Weather</span>
                      <div className={styles.toggleGroup}>
                        <button
                          className={`${styles.toggleBtn} ${selectedRain === 'none' ? styles.active : ''}`}
                          onClick={() => setSelectedRain('none')}
                          aria-pressed={selectedRain === 'none'}
                        >Clear</button>
                        <button
                          className={`${styles.toggleBtn} ${selectedRain === 'light' ? styles.active : ''}`}
                          onClick={() => setSelectedRain('light')}
                          aria-pressed={selectedRain === 'light'}
                        >Rain</button>
                        <button
                          className={`${styles.toggleBtn} ${selectedRain === 'storm' ? styles.active : ''}`}
                          onClick={() => setSelectedRain('storm')}
                          aria-pressed={selectedRain === 'storm'}
                        >Storm</button>
                      </div>
                    </div>
                  </div>
                </div>

                <div className={styles.infoSection}>
                  <p className={styles.infoText}>
                    {getInfoText()}
                  </p>
                </div>

                <div className={styles.previewActions}>
                  <button onClick={() => setCroppedImage(null)} className={styles.adjustBtn} aria-label="Reframe image">
                    Reframe
                  </button>
                  <button onClick={handleTransform} className={styles.forgeBtn} aria-label="Reveal PRIME transformation">
                    Reveal PRIME
                  </button>
                </div>
              </div>
            ) : uploadedImage ? (
              <div className={styles.interfaceContent}>
                <p className={styles.interfaceTitle}>Frame the truth</p>
                <div className={styles.controlGroup}>
                  <span className={styles.controlLabel}>Aspect</span>
                  <div className={styles.toggleGroup}>
                    <button
                      className={`${styles.toggleBtn} ${selectedAspect === 'full' ? styles.active : ''}`}
                      onClick={() => handleAspectChange('full')}
                      aria-pressed={selectedAspect === 'full'}
                    >Full</button>
                    <button
                      className={`${styles.toggleBtn} ${selectedAspect === 'square' ? styles.active : ''}`}
                      onClick={() => handleAspectChange('square')}
                      aria-pressed={selectedAspect === 'square'}
                    >Square</button>
                    <button
                      className={`${styles.toggleBtn} ${selectedAspect === 'portrait' ? styles.active : ''}`}
                      onClick={() => handleAspectChange('portrait')}
                      aria-pressed={selectedAspect === 'portrait'}
                    >Portrait</button>
                  </div>
                </div>
                <div className={styles.cropActions}>
                  <button onClick={handleReset} className={styles.backBtn} aria-label="Reset and start over">
                    Reset
                  </button>
                  <button onClick={handleCropConfirm} className={styles.forgeBtn} aria-label="Lock the frame selection">
                    Lock Frame
                  </button>
                </div>
              </div>
            ) : null}
          </div>

          {error && <p className={styles.error}>{error}</p>}
        </div>
      </div>
    </section>
  )
}
