import {
  BaseBoxShapeUtil,
  Geometry2d,
  HTMLContainer,
  Rectangle2d,
  TLBaseShape,
} from "tldraw"
import React, { useState, useRef, useEffect } from "react"
import { getRunPodVideoConfig } from "@/lib/clientConfig"
import { StandardizedToolWrapper } from "@/components/StandardizedToolWrapper"
import { usePinnedToView } from "@/hooks/usePinnedToView"
import { useMaximize } from "@/hooks/useMaximize"

// Type for RunPod job response
interface RunPodJobResponse {
  id?: string
  status?: 'IN_QUEUE' | 'IN_PROGRESS' | 'STARTING' | 'COMPLETED' | 'FAILED' | 'CANCELLED'
  output?: {
    video_url?: string
    url?: string
    [key: string]: any
  } | string
  error?: string
}

type IVideoGen = TLBaseShape<
  "VideoGen",
  {
    w: number
    h: number
    prompt: string
    imageUrl: string // Input image URL for I2V generation
    imageBase64: string // Uploaded image as base64 for I2V generation
    videoUrl: string | null
    isLoading: boolean
    error: string | null
    duration: number // seconds
    model: string
    tags: string[]
    pinnedToView: boolean
  }
>

export class VideoGenShape extends BaseBoxShapeUtil<IVideoGen> {
  static override type = "VideoGen" as const

  // Video generation theme color: Purple
  static readonly PRIMARY_COLOR = "#8B5CF6"

  getDefaultProps(): IVideoGen['props'] {
    return {
      w: 500,
      h: 540,
      prompt: "",
      imageUrl: "", // Input image URL for I2V generation
      imageBase64: "", // Uploaded image as base64
      videoUrl: null,
      isLoading: false,
      error: null,
      duration: 3,
      model: "wan2.2",
      tags: ['video', 'ai-generated'],
      pinnedToView: false
    }
  }

  getGeometry(shape: IVideoGen): Geometry2d {
    // Ensure minimum dimensions for proper hit testing
    return new Rectangle2d({
      width: Math.max(shape.props.w, 1),
      height: Math.max(shape.props.h, 1),
      isFilled: true,
    })
  }

  component(shape: IVideoGen) {
    // Capture editor reference to avoid stale 'this' during drag operations
    const editor = this.editor

    // Debug: log what's in shape props on each render
    console.log('🎬 VideoGen render - shape.props.videoUrl:', shape.props.videoUrl?.substring(0, 80) || 'null')

    const [prompt, setPrompt] = useState(shape.props.prompt)
    const [imageUrl, setImageUrl] = useState(shape.props.imageUrl)
    const [imageBase64, setImageBase64] = useState(shape.props.imageBase64)
    const [isGenerating, setIsGenerating] = useState(shape.props.isLoading)
    const [error, setError] = useState<string | null>(shape.props.error)
    const [videoUrl, setVideoUrl] = useState<string | null>(shape.props.videoUrl)
    const [isMinimized, setIsMinimized] = useState(false)
    const fileInputRef = useRef<HTMLInputElement>(null)
    const isSelected = editor.getSelectedShapeIds().includes(shape.id)

    // Determine mode based on whether an image is provided
    const hasImage = imageUrl.trim() || imageBase64
    const mode = hasImage ? 'i2v' : 't2v'

    // Sync video URL from shape props when it changes externally
    // This ensures the displayed video matches the shape's stored videoUrl
    useEffect(() => {
      if (shape.props.videoUrl !== videoUrl) {
        console.log('🎬 VideoGen: Syncing videoUrl from shape props:', shape.props.videoUrl?.substring(0, 50))
        setVideoUrl(shape.props.videoUrl)
      }
    }, [shape.props.videoUrl])

    // Pin to view functionality
    usePinnedToView(editor, shape.id, shape.props.pinnedToView)

    // Use the maximize hook for fullscreen functionality
    const { isMaximized, toggleMaximize } = useMaximize({
      editor: editor,
      shapeId: shape.id,
      currentW: shape.props.w,
      currentH: shape.props.h,
      shapeType: 'VideoGen',
    })

    const handlePinToggle = () => {
      editor.updateShape<IVideoGen>({
        id: shape.id,
        type: "VideoGen",
        props: { pinnedToView: !shape.props.pinnedToView },
      })
    }

    // Handle file upload
    const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
      const file = e.target.files?.[0]
      if (!file) return

      // Validate file type
      if (!file.type.startsWith('image/')) {
        setError('Please upload an image file (JPEG, PNG, etc.)')
        return
      }

      // Validate file size (max 10MB)
      if (file.size > 10 * 1024 * 1024) {
        setError('Image must be less than 10MB')
        return
      }

      const reader = new FileReader()
      reader.onload = (event) => {
        const base64 = event.target?.result as string
        setImageBase64(base64)
        setImageUrl('') // Clear URL if uploading
        setError(null)
      }
      reader.onerror = () => {
        setError('Failed to read image file')
      }
      reader.readAsDataURL(file)
    }

    const handleGenerate = async () => {
      if (!prompt.trim()) {
        setError("Please enter a prompt describing the video")
        return
      }

      // Validate image URL if provided
      if (imageUrl.trim()) {
        try {
          new URL(imageUrl)
        } catch {
          setError("Please enter a valid image URL (must start with http:// or https://)")
          return
        }
      }

      // Check RunPod config
      const runpodConfig = getRunPodVideoConfig()
      if (!runpodConfig) {
        setError("RunPod video endpoint not configured. Please set VITE_RUNPOD_API_KEY and VITE_RUNPOD_VIDEO_ENDPOINT_ID in your .env file.")
        return
      }

      const currentMode = (imageUrl.trim() || imageBase64) ? 'i2v' : 't2v'
      console.log(`🎬 VideoGen: Starting ${currentMode.toUpperCase()} generation`)
      console.log('🎬 VideoGen: Prompt:', prompt)
      if (currentMode === 'i2v') {
        console.log('🎬 VideoGen: Image source:', imageUrl ? 'URL' : 'Uploaded')
      }

      // Clear any existing video and set loading state
      setIsGenerating(true)
      setError(null)
      setVideoUrl(null) // Clear old video immediately

      // Update shape to show loading state and clear old video
      const currentShape = editor.getShape(shape.id) as IVideoGen | undefined
      if (currentShape) {
        editor.updateShape({
          id: shape.id,
          type: shape.type,
          props: {
            ...currentShape.props,
            isLoading: true,
            error: null,
            videoUrl: null // Clear old video from shape props
          }
        })
      }

      try {
        const { apiKey, endpointId } = runpodConfig

        // Submit job to RunPod
        console.log('🎬 VideoGen: Submitting to RunPod endpoint:', endpointId)
        const runUrl = `https://api.runpod.ai/v2/${endpointId}/run`

        // Generate a random seed for reproducibility
        const seed = Math.floor(Math.random() * 2147483647)

        // Wan2.2 parameters
        // Note: Portrait orientation (480x832) works better than landscape
        // Length is in frames: 81 frames ≈ 3 seconds at ~27fps output
        const framesPerSecond = 27 // Wan2.2 output fps
        const frameLength = Math.min(Math.max(shape.props.duration * framesPerSecond, 41), 121) // 41-121 frames supported

        // Build input payload based on mode
        const inputPayload: Record<string, any> = {
          prompt: prompt,
          negative_prompt: "blurry, distorted, low quality, static, frozen",
          width: 480,           // Portrait width (Wan2.2 optimal)
          height: 832,          // Portrait height (Wan2.2 optimal)
          length: frameLength,  // Total frames (81 ≈ 3 seconds)
          steps: 10,            // Inference steps (10 is optimal for speed/quality)
          cfg: 2.0,             // CFG scale - lower works better for Wan2.2
          seed: seed,
          context_overlap: 48,  // Frame overlap for temporal consistency
        }

        // Add image for I2V mode
        if (currentMode === 'i2v') {
          if (imageUrl.trim()) {
            inputPayload.image_url = imageUrl
          } else if (imageBase64) {
            // Strip data URL prefix if present, send just the base64
            const base64Data = imageBase64.includes(',')
              ? imageBase64.split(',')[1]
              : imageBase64
            inputPayload.image = base64Data
          }
        }

        const response = await fetch(runUrl, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${apiKey}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ input: inputPayload })
        })

        if (!response.ok) {
          const errorText = await response.text()
          throw new Error(`RunPod API error: ${response.status} - ${errorText}`)
        }

        const jobData = await response.json() as RunPodJobResponse
        console.log('🎬 VideoGen: Job submitted:', jobData.id)

        if (!jobData.id) {
          throw new Error('No job ID returned from RunPod')
        }

        // Poll for completion
        // Video generation can take a long time, especially with GPU cold starts:
        // - GPU cold start: 30-120 seconds
        // - Model loading: 30-60 seconds
        // - Actual generation: 60-180 seconds depending on duration
        // Total: up to 6 minutes is reasonable
        const statusUrl = `https://api.runpod.ai/v2/${endpointId}/status/${jobData.id}`
        let attempts = 0
        const maxAttempts = 180 // 6 minutes with 2s intervals

        while (attempts < maxAttempts) {
          await new Promise(resolve => setTimeout(resolve, 2000))
          attempts++

          const statusResponse = await fetch(statusUrl, {
            headers: { 'Authorization': `Bearer ${apiKey}` }
          })

          if (!statusResponse.ok) {
            console.warn(`🎬 VideoGen: Poll error (attempt ${attempts}):`, statusResponse.status)
            continue
          }

          const statusData = await statusResponse.json() as RunPodJobResponse
          console.log(`🎬 VideoGen: Poll ${attempts}/${maxAttempts}, status:`, statusData.status)

          if (statusData.status === 'COMPLETED') {
            // Extract video from output - can be URL or base64 data
            let videoData = ''

            if (typeof statusData.output === 'string') {
              // Direct string output - could be URL or base64
              videoData = statusData.output
            } else if (statusData.output?.video) {
              // Base64 video data in output.video field
              videoData = statusData.output.video
            } else if (statusData.output?.video_url) {
              videoData = statusData.output.video_url
            } else if (statusData.output?.url) {
              videoData = statusData.output.url
            }

            if (videoData) {
              // Check if it's base64 data (doesn't start with http)
              let finalUrl = videoData
              if (!videoData.startsWith('http') && !videoData.startsWith('data:')) {
                // Convert base64 to data URL
                finalUrl = `data:video/mp4;base64,${videoData}`
                console.log('✅ VideoGen: Generation complete, converted base64 to data URL')
                console.log('✅ VideoGen: Base64 length:', videoData.length, 'chars')
              } else {
                console.log('✅ VideoGen: Generation complete, URL:', finalUrl.substring(0, 100))
              }

              // Log the data URL prefix to verify format
              console.log('✅ VideoGen: Final URL prefix:', finalUrl.substring(0, 50))

              // Update local state immediately
              setVideoUrl(finalUrl)
              setIsGenerating(false)

              // Get fresh shape data to avoid stale props
              const currentShape = editor.getShape(shape.id)
              if (currentShape) {
                editor.updateShape({
                  id: shape.id,
                  type: shape.type,
                  props: {
                    ...(currentShape as IVideoGen).props,
                    videoUrl: finalUrl,
                    isLoading: false,
                    prompt: prompt,
                    imageUrl: imageUrl,
                    imageBase64: imageBase64
                  }
                })
              }
              return
            } else {
              console.log('⚠️ VideoGen: Completed but no video in output:', JSON.stringify(statusData.output))
              throw new Error('Video generation completed but no video data returned')
            }
          } else if (statusData.status === 'FAILED') {
            throw new Error(statusData.error || 'Video generation failed')
          } else if (statusData.status === 'CANCELLED') {
            throw new Error('Video generation was cancelled')
          }
        }

        throw new Error('Video generation timed out after 6 minutes. The GPU may be busy - try again later.')
      } catch (error: any) {
        const errorMessage = error.message || 'Unknown error during video generation'
        console.error('❌ VideoGen: Generation error:', errorMessage)
        setError(errorMessage)
        setIsGenerating(false)

        editor.updateShape({
          id: shape.id,
          type: shape.type,
          props: { ...shape.props, isLoading: false, error: errorMessage }
        })
      }
    }

    const handleClose = () => {
      editor.deleteShape(shape.id)
    }

    const handleMinimize = () => {
      setIsMinimized(!isMinimized)
    }

    const handleTagsChange = (newTags: string[]) => {
      editor.updateShape({
        id: shape.id,
        type: shape.type,
        props: { ...shape.props, tags: newTags }
      })
    }

    return (
      <HTMLContainer id={shape.id}>
        <StandardizedToolWrapper
          title="🎬 Video Generator (Wan2.2)"
          primaryColor={VideoGenShape.PRIMARY_COLOR}
          isSelected={isSelected}
          width={shape.props.w}
          height={shape.props.h}
          onClose={handleClose}
          onMinimize={handleMinimize}
          isMinimized={isMinimized}
          onMaximize={toggleMaximize}
          isMaximized={isMaximized}
          editor={editor}
          shapeId={shape.id}
          tags={shape.props.tags}
          onTagsChange={handleTagsChange}
          tagsEditable={true}
          isPinnedToView={shape.props.pinnedToView}
          onPinToggle={handlePinToggle}
          headerContent={
            isGenerating ? (
              <span style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
                🎬 Video Generator
                <span style={{
                  marginLeft: 'auto',
                  fontSize: '11px',
                  color: VideoGenShape.PRIMARY_COLOR,
                  animation: 'pulse 1.5s ease-in-out infinite'
                }}>
                  Generating...
                </span>
              </span>
            ) : undefined
          }
        >
          <div style={{
            flex: 1,
            display: 'flex',
            flexDirection: 'column',
            padding: '16px',
            gap: '12px',
            overflow: 'auto',
            backgroundColor: '#fafafa'
          }}>
            {!videoUrl && (
              <>
                {/* Mode indicator */}
                <div style={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: '8px',
                  padding: '8px 12px',
                  backgroundColor: mode === 'i2v' ? '#e8f4fd' : '#f0e8fd',
                  borderRadius: '6px',
                  fontSize: '12px',
                  color: mode === 'i2v' ? '#1976d2' : '#7c3aed'
                }}>
                  <span style={{ fontWeight: '600' }}>
                    {mode === 'i2v' ? '🖼️ Image-to-Video' : '✨ Text-to-Video'}
                  </span>
                  <span style={{ opacity: 0.8 }}>
                    {mode === 'i2v' ? '(animates your image)' : '(generates from text only)'}
                  </span>
                </div>

                {/* Image Input Section */}
                <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
                  <label style={{ color: '#555', fontSize: '12px', fontWeight: '600' }}>
                    Source Image (optional)
                  </label>

                  {/* Image preview or upload area */}
                  {(imageUrl || imageBase64) ? (
                    <div style={{ position: 'relative' }}>
                      <img
                        src={imageBase64 || imageUrl}
                        alt="Preview"
                        style={{
                          width: '100%',
                          maxHeight: '100px',
                          objectFit: 'contain',
                          borderRadius: '6px',
                          backgroundColor: '#f5f5f5'
                        }}
                        onError={(e) => {
                          (e.target as HTMLImageElement).style.display = 'none'
                          setError('Failed to load image from URL')
                        }}
                      />
                      <button
                        onClick={() => {
                          setImageUrl('')
                          setImageBase64('')
                        }}
                        onPointerDown={(e) => e.stopPropagation()}
                        onTouchStart={(e) => e.stopPropagation()}
                        onTouchEnd={(e) => e.stopPropagation()}
                        disabled={isGenerating}
                        style={{
                          position: 'absolute',
                          top: '4px',
                          right: '4px',
                          width: '32px',
                          height: '32px',
                          borderRadius: '50%',
                          border: 'none',
                          backgroundColor: 'rgba(0,0,0,0.6)',
                          color: '#fff',
                          cursor: 'pointer',
                          fontSize: '14px',
                          display: 'flex',
                          alignItems: 'center',
                          justifyContent: 'center',
                          touchAction: 'manipulation',
                        }}
                      >
                        ×
                      </button>
                    </div>
                  ) : (
                    <div style={{ display: 'flex', gap: '8px' }}>
                      {/* Upload button */}
                      <button
                        onClick={() => fileInputRef.current?.click()}
                        onPointerDown={(e) => e.stopPropagation()}
                        onTouchStart={(e) => e.stopPropagation()}
                        onTouchEnd={(e) => {
                          e.stopPropagation()
                          e.preventDefault()
                          fileInputRef.current?.click()
                        }}
                        disabled={isGenerating}
                        style={{
                          flex: 1,
                          padding: '12px',
                          backgroundColor: '#f5f5f5',
                          border: '2px dashed #ccc',
                          borderRadius: '6px',
                          cursor: 'pointer',
                          fontSize: '12px',
                          color: '#666',
                          display: 'flex',
                          alignItems: 'center',
                          justifyContent: 'center',
                          gap: '6px',
                          touchAction: 'manipulation',
                          minHeight: '44px',
                        }}
                      >
                        📤 Upload Image
                      </button>
                      <input
                        ref={fileInputRef}
                        type="file"
                        accept="image/*"
                        onChange={handleFileUpload}
                        style={{ display: 'none' }}
                      />
                    </div>
                  )}

                  {/* URL input (collapsible) */}
                  {!imageBase64 && (
                    <input
                      type="url"
                      value={imageUrl}
                      onChange={(e) => {
                        setImageUrl(e.target.value)
                        setImageBase64('')
                      }}
                      placeholder="Or paste image URL..."
                      disabled={isGenerating}
                      onPointerDown={(e) => e.stopPropagation()}
                      onTouchStart={(e) => e.stopPropagation()}
                      onMouseDown={(e) => e.stopPropagation()}
                      style={{
                        width: '100%',
                        padding: '8px 10px',
                        backgroundColor: '#fff',
                        color: '#333',
                        border: '1px solid #ddd',
                        borderRadius: '6px',
                        fontSize: '12px',
                        boxSizing: 'border-box',
                        touchAction: 'manipulation',
                        minHeight: '44px',
                      }}
                    />
                  )}
                </div>

                {/* Prompt */}
                <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
                  <label style={{ color: '#555', fontSize: '12px', fontWeight: '600' }}>
                    {mode === 'i2v' ? 'Motion Prompt *' : 'Video Prompt *'}
                  </label>
                  <textarea
                    value={prompt}
                    onChange={(e) => setPrompt(e.target.value)}
                    placeholder={mode === 'i2v'
                      ? "Describe the motion (e.g., 'gentle camera pan, wind blowing')"
                      : "Describe the video scene (e.g., 'a cat walking through a forest')"
                    }
                    disabled={isGenerating}
                    onPointerDown={(e) => e.stopPropagation()}
                    onTouchStart={(e) => e.stopPropagation()}
                    onMouseDown={(e) => e.stopPropagation()}
                    style={{
                      width: '100%',
                      minHeight: '50px',
                      padding: '10px',
                      backgroundColor: '#fff',
                      color: '#333',
                      border: '1px solid #ddd',
                      borderRadius: '6px',
                      fontSize: '13px',
                      fontFamily: 'inherit',
                      resize: 'vertical',
                      boxSizing: 'border-box',
                      touchAction: 'manipulation',
                    }}
                  />
                </div>

                <div style={{ display: 'flex', gap: '12px', alignItems: 'flex-end' }}>
                  <div style={{ flex: 1 }}>
                    <label style={{ color: '#555', fontSize: '11px', display: 'block', marginBottom: '4px', fontWeight: '500' }}>
                      Duration (seconds)
                    </label>
                    <input
                      type="number"
                      min="2"
                      max="4"
                      value={shape.props.duration}
                      onChange={(e) => {
                        editor.updateShape({
                          id: shape.id,
                          type: shape.type,
                          props: { ...shape.props, duration: parseInt(e.target.value) || 3 }
                        })
                      }}
                      disabled={isGenerating}
                      onPointerDown={(e) => e.stopPropagation()}
                      onTouchStart={(e) => e.stopPropagation()}
                      onMouseDown={(e) => e.stopPropagation()}
                      style={{
                        width: '100%',
                        padding: '8px',
                        backgroundColor: '#fff',
                        color: '#333',
                        border: '1px solid #ddd',
                        borderRadius: '6px',
                        fontSize: '13px',
                        boxSizing: 'border-box',
                        touchAction: 'manipulation',
                        minHeight: '44px',
                      }}
                    />
                  </div>

                  <button
                    onClick={handleGenerate}
                    disabled={isGenerating || !prompt.trim()}
                    onPointerDown={(e) => e.stopPropagation()}
                    onTouchStart={(e) => e.stopPropagation()}
                    onTouchEnd={(e) => {
                      e.stopPropagation()
                      e.preventDefault()
                      if (!isGenerating && prompt.trim()) {
                        handleGenerate()
                      }
                    }}
                    onMouseDown={(e) => e.stopPropagation()}
                    style={{
                      padding: '8px 20px',
                      backgroundColor: isGenerating ? '#ccc' : VideoGenShape.PRIMARY_COLOR,
                      color: '#fff',
                      border: 'none',
                      borderRadius: '6px',
                      fontSize: '13px',
                      fontWeight: '600',
                      cursor: isGenerating ? 'not-allowed' : 'pointer',
                      transition: 'all 0.2s',
                      whiteSpace: 'nowrap',
                      opacity: isGenerating || !prompt.trim() ? 0.6 : 1,
                      touchAction: 'manipulation',
                      minHeight: '44px',
                    }}
                  >
                    {isGenerating ? 'Generating...' : (mode === 'i2v' ? 'Animate Image' : 'Generate Video')}
                  </button>
                </div>

                {error && (
                  <div style={{
                    padding: '12px',
                    backgroundColor: '#fee',
                    border: '1px solid #fcc',
                    color: '#c33',
                    borderRadius: '6px',
                    fontSize: '12px',
                    lineHeight: '1.4'
                  }}>
                    <strong>Error:</strong> {error}
                  </div>
                )}

                <div style={{
                  marginTop: 'auto',
                  padding: '12px',
                  backgroundColor: '#f0f0f0',
                  borderRadius: '6px',
                  fontSize: '11px',
                  color: '#666',
                  lineHeight: '1.5'
                }}>
                  <div><strong>Wan2.2 Video Generation</strong></div>
                  <div>
                    {mode === 'i2v'
                      ? 'Animates your image based on the motion prompt'
                      : 'Creates video from your text description'
                    }
                  </div>
                  <div style={{ marginTop: '4px' }}>Output: 480x832 portrait | ~3 seconds</div>
                  <div style={{ marginTop: '4px', opacity: 0.8 }}>
                    Processing: 2-6 minutes (includes GPU warm-up)
                  </div>
                </div>
              </>
            )}

            {videoUrl && (
              <>
                <video
                  key={videoUrl.substring(0, 100)} // Force reload when URL changes
                  src={videoUrl}
                  controls
                  autoPlay
                  loop
                  playsInline
                  onPointerDown={(e) => e.stopPropagation()}
                  onTouchStart={(e) => e.stopPropagation()}
                  onLoadedData={() => console.log('🎬 VideoGen: Video loaded successfully')}
                  onError={(e) => console.error('🎬 VideoGen: Video load error:', e)}
                  style={{
                    width: '100%',
                    maxHeight: '280px',
                    borderRadius: '6px',
                    backgroundColor: '#000',
                    touchAction: 'manipulation',
                  }}
                />

                <div style={{
                  padding: '10px',
                  backgroundColor: '#f0f0f0',
                  borderRadius: '6px',
                  fontSize: '11px',
                  color: '#555',
                  wordBreak: 'break-word'
                }}>
                  <strong>Prompt:</strong> {shape.props.prompt || prompt}
                </div>

                <div style={{ display: 'flex', gap: '8px' }}>
                  <button
                    onClick={() => {
                      setVideoUrl(null)
                      setPrompt("")
                      setImageUrl("")
                      setImageBase64("")
                      editor.updateShape({
                        id: shape.id,
                        type: shape.type,
                        props: { ...shape.props, videoUrl: null, prompt: "", imageUrl: "", imageBase64: "" }
                      })
                    }}
                    onPointerDown={(e) => e.stopPropagation()}
                    onTouchStart={(e) => e.stopPropagation()}
                    onTouchEnd={(e) => e.stopPropagation()}
                    onMouseDown={(e) => e.stopPropagation()}
                    style={{
                      flex: 1,
                      padding: '10px',
                      backgroundColor: '#e0e0e0',
                      color: '#333',
                      border: 'none',
                      borderRadius: '6px',
                      fontSize: '12px',
                      fontWeight: '500',
                      cursor: 'pointer',
                      touchAction: 'manipulation',
                      minHeight: '44px',
                    }}
                  >
                    New Video
                  </button>

                  <a
                    href={videoUrl}
                    download="generated-video.mp4"
                    onPointerDown={(e) => e.stopPropagation()}
                    onTouchStart={(e) => e.stopPropagation()}
                    onTouchEnd={(e) => e.stopPropagation()}
                    onMouseDown={(e) => e.stopPropagation()}
                    style={{
                      flex: 1,
                      padding: '10px',
                      backgroundColor: VideoGenShape.PRIMARY_COLOR,
                      color: '#fff',
                      border: 'none',
                      borderRadius: '6px',
                      fontSize: '12px',
                      fontWeight: '600',
                      textAlign: 'center',
                      textDecoration: 'none',
                      cursor: 'pointer',
                      touchAction: 'manipulation',
                      minHeight: '44px',
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                    }}
                  >
                    Download
                  </a>
                </div>
              </>
            )}
          </div>

          <style>{`
            @keyframes pulse {
              0%, 100% { opacity: 1; }
              50% { opacity: 0.5; }
            }
          `}</style>
        </StandardizedToolWrapper>
      </HTMLContainer>
    )
  }

  indicator(shape: IVideoGen) {
    return <rect width={shape.props.w} height={shape.props.h} rx={8} />
  }
}
