import {
  BaseBoxShapeUtil,
  Geometry2d,
  HTMLContainer,
  Rectangle2d,
  TLBaseShape,
  TLShapeId,
  createShapeId,
} from "tldraw"
import React, { useState, useRef, useEffect } from "react"
import { StandardizedToolWrapper } from "@/components/StandardizedToolWrapper"
import { usePinnedToView } from "@/hooks/usePinnedToView"
import { useMaximize } from "@/hooks/useMaximize"
// Note: Image generation now uses zine.jeffemmett.com API which proxies through RunPod

// ============================================================================
// Types
// ============================================================================

type ZinePhase = 'ideation' | 'drafts' | 'feedback' | 'finalizing' | 'complete'

type ZineStyle = 'punk-zine' | 'minimal' | 'collage' | 'retro' | 'academic'
type ZineTone = 'rebellious' | 'playful' | 'informative' | 'poetic'

interface ChatMessage {
  id: string
  role: 'user' | 'assistant'
  content: string
  timestamp: number
}

interface ZinePageOutline {
  pageNumber: number // 1-8
  type: 'cover' | 'content' | 'cta'
  title: string
  subtitle?: string
  keyPoints: string[]
  hashtags: string[]
  imagePrompt: string
}

interface GeneratedZinePage {
  pageNumber: number
  imageUrl: string
  shapeId?: string // Canvas shape ID if spawned
  outline: ZinePageOutline
  generationPrompt: string
  timestamp: number
  version: number // 1=draft, 2+=refined
}

interface PageFeedback {
  pageNumber: number
  feedbackText: string
  requestedChanges: string[]
  approved: boolean
}

interface ZineTemplate {
  id: string
  name: string
  topic: string
  style: ZineStyle
  tone: ZineTone
  pages: GeneratedZinePage[]
  createdAt: number
}

type IMycroZineGenerator = TLBaseShape<
  "MycroZineGenerator",
  {
    w: number
    h: number

    // Zine Identity
    zineId: string
    title: string
    topic: string
    style: ZineStyle
    tone: ZineTone

    // Phase State
    phase: ZinePhase

    // Ideation Phase
    ideationMessages: ChatMessage[]
    contentOutline: ZinePageOutline[] | null

    // Drafts Phase
    draftPages: GeneratedZinePage[]
    spawnedShapeIds: string[]
    currentGeneratingPage: number // 0 = not generating, 1-8 = generating that page

    // Feedback Phase
    pageFeedback: PageFeedback[]

    // Final Phase
    finalPages: GeneratedZinePage[]
    printLayoutUrl: string | null

    // UI State
    isLoading: boolean
    error: string | null
    tags: string[]
    pinnedToView: boolean
  }
>

// ============================================================================
// Constants
// ============================================================================

const STYLES: Record<ZineStyle, string> = {
  'punk-zine': 'Xerox texture, high contrast B&W, DIY collage, hand-drawn typography',
  'minimal': 'Clean lines, white space, modern sans-serif, subtle gradients',
  'collage': 'Layered imagery, mixed media textures, vintage photographs',
  'retro': '1970s aesthetic, earth tones, groovy typography, halftone patterns',
  'academic': 'Diagram-heavy, annotated illustrations, infographic elements',
}

const TONES: Record<ZineTone, string> = {
  'rebellious': 'Defiant, anti-establishment, punk energy',
  'playful': 'Fun, whimsical, approachable',
  'informative': 'Educational, clear, accessible',
  'poetic': 'Lyrical, metaphorical, evocative',
}

const PAGE_TEMPLATES = [
  { type: 'cover', description: 'Bold title, subtitle, visual hook' },
  { type: 'content', description: 'Key concepts with visual explanations' },
  { type: 'content', description: 'Deep dive on main topic' },
  { type: 'content', description: 'Supporting information' },
  { type: 'content', description: 'Practical applications' },
  { type: 'content', description: 'Community or movement aspect' },
  { type: 'content', description: 'Philosophy or manifesto' },
  { type: 'cta', description: 'Call-to-action with QR codes' },
]

// ============================================================================
// Shape Util
// ============================================================================

export class MycroZineGeneratorShape extends BaseBoxShapeUtil<IMycroZineGenerator> {
  static override type = "MycroZineGenerator" as const

  // Mycro-zine theme color: Punk green
  static readonly PRIMARY_COLOR = "#00ff00"
  static readonly SECONDARY_COLOR = "#1a1a1a"

  MIN_WIDTH = 400 as const
  MIN_HEIGHT = 500 as const
  DEFAULT_WIDTH = 450 as const
  DEFAULT_HEIGHT = 600 as const

  getDefaultProps(): IMycroZineGenerator["props"] {
    return {
      w: this.DEFAULT_WIDTH,
      h: this.DEFAULT_HEIGHT,

      zineId: `zine_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      title: '',
      topic: '',
      style: 'punk-zine',
      tone: 'rebellious',

      phase: 'ideation',

      ideationMessages: [],
      contentOutline: null,

      draftPages: [],
      spawnedShapeIds: [],
      currentGeneratingPage: 0,

      pageFeedback: [],

      finalPages: [],
      printLayoutUrl: null,

      isLoading: false,
      error: null,
      tags: ['zine', 'mycrozine', 'print'],
      pinnedToView: false,
    }
  }

  getGeometry(shape: IMycroZineGenerator): Geometry2d {
    return new Rectangle2d({
      width: Math.max(shape.props.w, 1),
      height: Math.max(shape.props.h, 1),
      isFilled: true,
    })
  }

  component(shape: IMycroZineGenerator) {
    const editor = this.editor
    const isSelected = editor.getSelectedShapeIds().includes(shape.id)

    usePinnedToView(editor, shape.id, shape.props.pinnedToView)

    const { isMaximized, toggleMaximize } = useMaximize({
      editor: editor,
      shapeId: shape.id,
      currentW: shape.props.w,
      currentH: shape.props.h,
      shapeType: 'MycroZineGenerator',
    })

    const [isMinimized, setIsMinimized] = useState(false)
    const [inputValue, setInputValue] = useState('')
    const messagesEndRef = useRef<HTMLDivElement>(null)

    // Scroll to bottom of messages
    useEffect(() => {
      messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
    }, [shape.props.ideationMessages])

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

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

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

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

    // Update shape props helper
    const updateProps = (updates: Partial<IMycroZineGenerator["props"]>) => {
      editor.updateShape<IMycroZineGenerator>({
        id: shape.id,
        type: "MycroZineGenerator",
        props: updates,
      })
    }

    // Add a chat message
    const addMessage = (role: 'user' | 'assistant', content: string) => {
      const newMessage: ChatMessage = {
        id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
        role,
        content,
        timestamp: Date.now(),
      }
      updateProps({
        ideationMessages: [...shape.props.ideationMessages, newMessage],
      })
      return newMessage
    }

    // Generate content outline from ideation
    const generateOutline = async () => {
      if (!shape.props.topic) {
        updateProps({ error: 'Please enter a topic first' })
        return
      }

      updateProps({ isLoading: true, error: null })

      try {
        // Build outline based on topic and conversation
        const outline: ZinePageOutline[] = PAGE_TEMPLATES.map((template, index) => ({
          pageNumber: index + 1,
          type: template.type as 'cover' | 'content' | 'cta',
          title: index === 0 ? shape.props.topic.toUpperCase() : `Page ${index + 1}`,
          subtitle: template.description,
          keyPoints: [],
          hashtags: [],
          imagePrompt: `${STYLES[shape.props.style]}. ${TONES[shape.props.tone]}. ${template.description} for ${shape.props.topic}.`,
        }))

        // Add assistant message with outline summary
        addMessage('assistant', `Great! I've created an outline for your "${shape.props.topic}" zine:\n\n${outline.map(p => `Page ${p.pageNumber}: ${p.title}`).join('\n')}\n\nClick "Generate Drafts" when you're ready to create the pages!`)

        updateProps({
          contentOutline: outline,
          title: shape.props.topic.toUpperCase(),
          isLoading: false,
        })
      } catch (err) {
        updateProps({
          isLoading: false,
          error: `Failed to generate outline: ${err instanceof Error ? err.message : String(err)}`,
        })
      }
    }

    // Handle user message in ideation phase
    const handleSendMessage = async () => {
      const message = inputValue.trim()
      if (!message) return

      setInputValue('')
      addMessage('user', message)

      // If this is the first message and no topic set, use it as topic
      if (!shape.props.topic && shape.props.ideationMessages.length === 0) {
        updateProps({ topic: message })

        // Auto-respond
        setTimeout(() => {
          addMessage('assistant', `Let's create an 8-page zine about "${message}"!\n\nI'll use the ${shape.props.style} style with a ${shape.props.tone} tone.\n\nFeel free to:\n• Add more details about what to cover\n• Specify any key points or themes\n• Change the style/tone using the dropdowns\n\nOr click "Generate Outline" to proceed!`)
        }, 500)
      } else {
        // Continue conversation
        setTimeout(() => {
          addMessage('assistant', `Got it! I'll incorporate that into the zine. ${shape.props.contentOutline ? 'Ready to generate drafts!' : 'Click "Generate Outline" when ready.'}`)
        }, 500)
      }
    }

    // Generate draft pages using Gemini
    const generateDrafts = async () => {
      if (!shape.props.contentOutline) {
        await generateOutline()
        if (!shape.props.contentOutline) return
      }

      updateProps({
        phase: 'drafts',
        isLoading: true,
        error: null,
        currentGeneratingPage: 1,
      })

      const outline = shape.props.contentOutline!
      const generatedPages: GeneratedZinePage[] = []

      for (let i = 0; i < outline.length; i++) {
        const pageOutline = outline[i]
        updateProps({ currentGeneratingPage: i + 1 })

        try {
          // Build the image generation prompt
          const prompt = buildImagePrompt(pageOutline, shape.props.topic, shape.props.style, shape.props.tone)

          // Call Gemini MCP for image generation
          // Note: In actual implementation, this would call the MCP server
          // For now, we'll use a placeholder approach
          const imageUrl = await generatePageImage(prompt, i + 1)

          generatedPages.push({
            pageNumber: i + 1,
            imageUrl,
            outline: pageOutline,
            generationPrompt: prompt,
            timestamp: Date.now(),
            version: 1,
          })

          // Spawn image on canvas
          const spawnedId = await spawnPageOnCanvas(editor, imageUrl, i, shape)
          if (spawnedId) {
            generatedPages[generatedPages.length - 1].shapeId = spawnedId
          }

          updateProps({ draftPages: [...generatedPages] })
        } catch (err) {
          console.error(`Failed to generate page ${i + 1}:`, err)
          updateProps({
            error: `Failed to generate page ${i + 1}: ${err instanceof Error ? err.message : String(err)}`,
          })
        }
      }

      // Initialize feedback for all pages
      const initialFeedback: PageFeedback[] = outline.map((_, i) => ({
        pageNumber: i + 1,
        feedbackText: '',
        requestedChanges: [],
        approved: false,
      }))

      updateProps({
        draftPages: generatedPages,
        pageFeedback: initialFeedback,
        spawnedShapeIds: generatedPages.map(p => p.shapeId).filter(Boolean) as string[],
        isLoading: false,
        currentGeneratingPage: 0,
        phase: generatedPages.length === 8 ? 'feedback' : 'drafts',
      })
    }

    // Approve a page
    const approvePage = (pageNumber: number) => {
      const newFeedback = shape.props.pageFeedback.map(f =>
        f.pageNumber === pageNumber ? { ...f, approved: true } : f
      )
      updateProps({ pageFeedback: newFeedback })
    }

    // Add feedback to a page
    const addPageFeedback = (pageNumber: number, feedback: string) => {
      const newFeedback = shape.props.pageFeedback.map(f =>
        f.pageNumber === pageNumber
          ? { ...f, feedbackText: feedback, requestedChanges: [feedback] }
          : f
      )
      updateProps({ pageFeedback: newFeedback })
    }

    // Check if all pages are approved or have feedback
    const allPagesReviewed = shape.props.pageFeedback.every(
      f => f.approved || f.feedbackText.length > 0
    )

    // Move to finalization
    const startFinalization = async () => {
      const pagesNeedingUpdate = shape.props.pageFeedback.filter(f => !f.approved && f.feedbackText)

      if (pagesNeedingUpdate.length === 0) {
        // All approved, skip to complete
        updateProps({
          phase: 'complete',
          finalPages: shape.props.draftPages,
        })
        return
      }

      updateProps({
        phase: 'finalizing',
        isLoading: true,
        error: null,
      })

      const finalPages = [...shape.props.draftPages]

      for (const feedback of pagesNeedingUpdate) {
        updateProps({ currentGeneratingPage: feedback.pageNumber })

        try {
          const originalPage = shape.props.draftPages.find(p => p.pageNumber === feedback.pageNumber)
          if (!originalPage) continue

          // Regenerate with feedback incorporated
          const prompt = `${originalPage.generationPrompt}\n\nIMPORTANT REVISIONS: ${feedback.feedbackText}`
          const imageUrl = await generatePageImage(prompt, feedback.pageNumber)

          finalPages[feedback.pageNumber - 1] = {
            ...originalPage,
            imageUrl,
            generationPrompt: prompt,
            timestamp: Date.now(),
            version: originalPage.version + 1,
          }
        } catch (err) {
          console.error(`Failed to regenerate page ${feedback.pageNumber}:`, err)
        }
      }

      updateProps({
        finalPages,
        isLoading: false,
        currentGeneratingPage: 0,
        phase: 'complete',
      })
    }

    // Generate print layout
    const generatePrintLayout = async () => {
      updateProps({ isLoading: true, error: null })

      try {
        // In actual implementation, this would call the mycro-zine layout generator
        // For now, show a success message
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5)
        const printUrl = `/output/${shape.props.zineId}_print_${timestamp}.png`

        updateProps({
          printLayoutUrl: printUrl,
          isLoading: false,
        })

        addMessage('assistant', `Print layout generated! Your zine is ready to download and print.`)
      } catch (err) {
        updateProps({
          isLoading: false,
          error: `Failed to generate print layout: ${err instanceof Error ? err.message : String(err)}`,
        })
      }
    }

    // Save as template
    const saveAsTemplate = () => {
      const template: ZineTemplate = {
        id: shape.props.zineId,
        name: shape.props.title || shape.props.topic,
        topic: shape.props.topic,
        style: shape.props.style,
        tone: shape.props.tone,
        pages: shape.props.finalPages.length > 0 ? shape.props.finalPages : shape.props.draftPages,
        createdAt: Date.now(),
      }

      // Save to localStorage
      const templates = JSON.parse(localStorage.getItem('mycrozine_templates') || '[]')
      templates.push(template)
      localStorage.setItem('mycrozine_templates', JSON.stringify(templates))

      addMessage('assistant', `Template "${template.name}" saved! You can reprint it anytime from the template library.`)
    }

    // Render phase-specific content
    const renderPhaseContent = () => {
      switch (shape.props.phase) {
        case 'ideation':
          return renderIdeationPhase()
        case 'drafts':
          return renderDraftsPhase()
        case 'feedback':
          return renderFeedbackPhase()
        case 'finalizing':
          return renderFinalizingPhase()
        case 'complete':
          return renderCompletePhase()
        default:
          return null
      }
    }

    // ========== IDEATION PHASE ==========
    const renderIdeationPhase = () => (
      <div style={{ display: 'flex', flexDirection: 'column', height: '100%', gap: '12px' }}>
        {/* Style/Tone selectors */}
        <div style={{ display: 'flex', gap: '8px', flexShrink: 0 }}>
          <select
            value={shape.props.style}
            onChange={(e) => updateProps({ style: e.target.value as ZineStyle })}
            onPointerDown={(e) => e.stopPropagation()}
            style={selectStyle}
          >
            {Object.keys(STYLES).map(s => (
              <option key={s} value={s}>{s}</option>
            ))}
          </select>
          <select
            value={shape.props.tone}
            onChange={(e) => updateProps({ tone: e.target.value as ZineTone })}
            onPointerDown={(e) => e.stopPropagation()}
            style={selectStyle}
          >
            {Object.keys(TONES).map(t => (
              <option key={t} value={t}>{t}</option>
            ))}
          </select>
        </div>

        {/* Chat messages */}
        <div style={{
          flex: 1,
          overflow: 'auto',
          display: 'flex',
          flexDirection: 'column',
          gap: '8px',
          padding: '8px',
          backgroundColor: '#1a1a1a',
          borderRadius: '6px',
        }}>
          {shape.props.ideationMessages.length === 0 && (
            <div style={{ color: '#666', fontSize: '13px', textAlign: 'center', padding: '20px' }}>
              What topic would you like to make a zine about?
            </div>
          )}
          {shape.props.ideationMessages.map((msg) => (
            <div
              key={msg.id}
              style={{
                padding: '8px 12px',
                borderRadius: '8px',
                maxWidth: '85%',
                alignSelf: msg.role === 'user' ? 'flex-end' : 'flex-start',
                backgroundColor: msg.role === 'user' ? MycroZineGeneratorShape.PRIMARY_COLOR : '#333',
                color: msg.role === 'user' ? '#000' : '#fff',
                fontSize: '13px',
                lineHeight: '1.4',
                whiteSpace: 'pre-wrap',
              }}
            >
              {msg.content}
            </div>
          ))}
          <div ref={messagesEndRef} />
        </div>

        {/* Input area */}
        <div style={{ display: 'flex', gap: '8px', flexShrink: 0 }}>
          <input
            type="text"
            value={inputValue}
            onChange={(e) => setInputValue(e.target.value)}
            onKeyDown={(e) => {
              e.stopPropagation()
              if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault()
                handleSendMessage()
              }
            }}
            onPointerDown={(e) => e.stopPropagation()}
            placeholder={shape.props.topic ? "Add details or feedback..." : "Enter your zine topic..."}
            style={inputStyle}
          />
          <button
            onClick={handleSendMessage}
            onPointerDown={(e) => e.stopPropagation()}
            style={buttonStyle}
            disabled={!inputValue.trim()}
          >
            Send
          </button>
        </div>

        {/* Action buttons */}
        <div style={{ display: 'flex', gap: '8px', flexShrink: 0 }}>
          {!shape.props.contentOutline && shape.props.topic && (
            <button
              onClick={generateOutline}
              onPointerDown={(e) => e.stopPropagation()}
              style={{ ...buttonStyle, flex: 1, backgroundColor: '#333' }}
              disabled={shape.props.isLoading}
            >
              Generate Outline
            </button>
          )}
          {shape.props.contentOutline && (
            <button
              onClick={generateDrafts}
              onPointerDown={(e) => e.stopPropagation()}
              style={{ ...buttonStyle, flex: 1 }}
              disabled={shape.props.isLoading}
            >
              {shape.props.isLoading ? 'Generating...' : 'Generate 8 Draft Pages →'}
            </button>
          )}
        </div>
      </div>
    )

    // ========== DRAFTS PHASE ==========
    const renderDraftsPhase = () => (
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', gap: '16px' }}>
        <div style={{ fontSize: '48px' }}>🍄</div>
        <div style={{ fontSize: '18px', fontWeight: 'bold', color: '#fff' }}>Generating Drafts...</div>

        {/* Progress bar */}
        <div style={{ width: '80%', backgroundColor: '#333', borderRadius: '4px', overflow: 'hidden' }}>
          <div style={{
            width: `${(shape.props.currentGeneratingPage / 8) * 100}%`,
            height: '8px',
            backgroundColor: MycroZineGeneratorShape.PRIMARY_COLOR,
            transition: 'width 0.3s ease',
          }} />
        </div>

        <div style={{ color: '#999', fontSize: '14px' }}>
          Page {shape.props.currentGeneratingPage}/8
        </div>

        {/* Page status list */}
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', justifyContent: 'center' }}>
          {Array.from({ length: 8 }, (_, i) => i + 1).map(pageNum => {
            const isComplete = shape.props.draftPages.some(p => p.pageNumber === pageNum)
            const isGenerating = shape.props.currentGeneratingPage === pageNum
            return (
              <div
                key={pageNum}
                style={{
                  width: '32px',
                  height: '32px',
                  borderRadius: '4px',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  fontSize: '12px',
                  fontWeight: 'bold',
                  backgroundColor: isComplete ? MycroZineGeneratorShape.PRIMARY_COLOR : isGenerating ? '#555' : '#333',
                  color: isComplete ? '#000' : '#fff',
                  border: isGenerating ? `2px solid ${MycroZineGeneratorShape.PRIMARY_COLOR}` : 'none',
                }}
              >
                {isComplete ? '✓' : pageNum}
              </div>
            )
          })}
        </div>
      </div>
    )

    // ========== FEEDBACK PHASE ==========
    const renderFeedbackPhase = () => {
      const [selectedPage, setSelectedPage] = useState<number | null>(null)
      const [feedbackInput, setFeedbackInput] = useState('')

      return (
        <div style={{ display: 'flex', flexDirection: 'column', height: '100%', gap: '12px' }}>
          <div style={{ color: '#999', fontSize: '13px', textAlign: 'center' }}>
            Review your drafts. Approve pages or add feedback for revision.
          </div>

          {/* Page grid */}
          <div style={{
            flex: 1,
            display: 'grid',
            gridTemplateColumns: 'repeat(4, 1fr)',
            gap: '8px',
            overflow: 'auto',
            padding: '4px',
          }}>
            {shape.props.draftPages.map((page) => {
              const feedback = shape.props.pageFeedback.find(f => f.pageNumber === page.pageNumber)
              const isApproved = feedback?.approved
              const hasFeedback = feedback?.feedbackText

              return (
                <div
                  key={page.pageNumber}
                  onClick={() => setSelectedPage(page.pageNumber)}
                  onPointerDown={(e) => e.stopPropagation()}
                  style={{
                    position: 'relative',
                    borderRadius: '4px',
                    overflow: 'hidden',
                    cursor: 'pointer',
                    border: selectedPage === page.pageNumber
                      ? `2px solid ${MycroZineGeneratorShape.PRIMARY_COLOR}`
                      : isApproved
                        ? '2px solid #4ade80'
                        : hasFeedback
                          ? '2px solid #fbbf24'
                          : '2px solid #333',
                  }}
                >
                  <img
                    src={page.imageUrl}
                    alt={`Page ${page.pageNumber}`}
                    style={{ width: '100%', aspectRatio: '3/4', objectFit: 'cover' }}
                  />
                  <div style={{
                    position: 'absolute',
                    bottom: 0,
                    left: 0,
                    right: 0,
                    padding: '4px',
                    backgroundColor: 'rgba(0,0,0,0.7)',
                    fontSize: '10px',
                    color: '#fff',
                    textAlign: 'center',
                  }}>
                    {page.pageNumber} {isApproved ? '✓' : hasFeedback ? '✎' : ''}
                  </div>
                </div>
              )
            })}
          </div>

          {/* Selected page actions */}
          {selectedPage && (
            <div style={{
              padding: '12px',
              backgroundColor: '#1a1a1a',
              borderRadius: '6px',
              display: 'flex',
              flexDirection: 'column',
              gap: '8px',
            }}>
              <div style={{ fontSize: '13px', color: '#fff' }}>Page {selectedPage}</div>
              <div style={{ display: 'flex', gap: '8px' }}>
                <button
                  onClick={() => {
                    approvePage(selectedPage)
                    setSelectedPage(null)
                  }}
                  onPointerDown={(e) => e.stopPropagation()}
                  style={{ ...buttonStyle, flex: 1, backgroundColor: '#4ade80', color: '#000' }}
                >
                  ✓ Approve
                </button>
                <button
                  onClick={() => {
                    // Toggle feedback input
                  }}
                  onPointerDown={(e) => e.stopPropagation()}
                  style={{ ...buttonStyle, flex: 1, backgroundColor: '#fbbf24', color: '#000' }}
                >
                  ✎ Add Feedback
                </button>
              </div>
              <input
                type="text"
                value={feedbackInput}
                onChange={(e) => setFeedbackInput(e.target.value)}
                onPointerDown={(e) => e.stopPropagation()}
                placeholder="Describe changes needed..."
                style={inputStyle}
              />
              {feedbackInput && (
                <button
                  onClick={() => {
                    addPageFeedback(selectedPage, feedbackInput)
                    setFeedbackInput('')
                    setSelectedPage(null)
                  }}
                  onPointerDown={(e) => e.stopPropagation()}
                  style={buttonStyle}
                >
                  Save Feedback
                </button>
              )}
            </div>
          )}

          {/* Continue button */}
          <button
            onClick={startFinalization}
            onPointerDown={(e) => e.stopPropagation()}
            style={{
              ...buttonStyle,
              opacity: allPagesReviewed ? 1 : 0.5,
            }}
            disabled={!allPagesReviewed}
          >
            {shape.props.pageFeedback.some(f => !f.approved && f.feedbackText)
              ? 'Apply Feedback & Finalize →'
              : 'Finalize Zine →'}
          </button>
        </div>
      )
    }

    // ========== FINALIZING PHASE ==========
    const renderFinalizingPhase = () => (
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', gap: '16px' }}>
        <div style={{ fontSize: '48px' }}>🔄</div>
        <div style={{ fontSize: '18px', fontWeight: 'bold', color: '#fff' }}>Applying Feedback...</div>

        <div style={{ color: '#999', fontSize: '14px' }}>
          Regenerating {shape.props.pageFeedback.filter(f => !f.approved && f.feedbackText).length} pages
        </div>

        {shape.props.currentGeneratingPage > 0 && (
          <div style={{ color: MycroZineGeneratorShape.PRIMARY_COLOR, fontSize: '14px' }}>
            Currently updating page {shape.props.currentGeneratingPage}...
          </div>
        )}
      </div>
    )

    // ========== COMPLETE PHASE ==========
    const renderCompletePhase = () => {
      const pages = shape.props.finalPages.length > 0 ? shape.props.finalPages : shape.props.draftPages

      return (
        <div style={{ display: 'flex', flexDirection: 'column', height: '100%', gap: '12px' }}>
          <div style={{ textAlign: 'center' }}>
            <div style={{ fontSize: '24px', marginBottom: '4px' }}>🍄</div>
            <div style={{ fontSize: '16px', fontWeight: 'bold', color: MycroZineGeneratorShape.PRIMARY_COLOR }}>
              Zine Complete!
            </div>
            <div style={{ color: '#999', fontSize: '13px' }}>
              "{shape.props.title || shape.props.topic}"
            </div>
          </div>

          {/* Print preview - 2x4 grid */}
          <div style={{
            flex: 1,
            display: 'grid',
            gridTemplateColumns: 'repeat(4, 1fr)',
            gridTemplateRows: 'repeat(2, 1fr)',
            gap: '2px',
            backgroundColor: '#fff',
            padding: '4px',
            borderRadius: '4px',
          }}>
            {pages.map((page) => (
              <img
                key={page.pageNumber}
                src={page.imageUrl}
                alt={`Page ${page.pageNumber}`}
                style={{ width: '100%', height: '100%', objectFit: 'cover' }}
              />
            ))}
          </div>

          {/* Action buttons */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
            <button
              onClick={generatePrintLayout}
              onPointerDown={(e) => e.stopPropagation()}
              style={buttonStyle}
              disabled={shape.props.isLoading}
            >
              📥 Download Print-Ready PNG
            </button>
            <button
              onClick={saveAsTemplate}
              onPointerDown={(e) => e.stopPropagation()}
              style={{ ...buttonStyle, backgroundColor: '#333' }}
            >
              💾 Save as Template
            </button>
            <button
              onClick={() => updateProps({
                phase: 'ideation',
                topic: '',
                title: '',
                contentOutline: null,
                ideationMessages: [],
                draftPages: [],
                pageFeedback: [],
                finalPages: [],
                printLayoutUrl: null,
                zineId: `zine_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
              })}
              onPointerDown={(e) => e.stopPropagation()}
              style={{ ...buttonStyle, backgroundColor: '#1a1a1a', color: '#999' }}
            >
              🔄 Start New Zine
            </button>
          </div>
        </div>
      )
    }

    // Phase indicator
    const phaseLabels: Record<ZinePhase, string> = {
      ideation: '1. Ideation',
      drafts: '2. Drafts',
      feedback: '3. Feedback',
      finalizing: '4. Finalizing',
      complete: '5. Complete',
    }

    return (
      <HTMLContainer id={shape.id}>
        <StandardizedToolWrapper
          title="🍄 MycroZine Generator"
          primaryColor={MycroZineGeneratorShape.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={
            <span style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
              🍄 MycroZine
              <span style={{
                fontSize: '10px',
                backgroundColor: MycroZineGeneratorShape.SECONDARY_COLOR,
                padding: '2px 6px',
                borderRadius: '10px',
                color: MycroZineGeneratorShape.PRIMARY_COLOR,
              }}>
                {phaseLabels[shape.props.phase]}
              </span>
            </span>
          }
        >
          <div style={{
            flex: 1,
            display: 'flex',
            flexDirection: 'column',
            padding: '12px',
            backgroundColor: '#0a0a0a',
            color: '#fff',
            overflow: 'hidden',
          }}>
            {/* Error display */}
            {shape.props.error && (
              <div style={{
                padding: '8px 12px',
                backgroundColor: '#331111',
                border: '1px solid #663333',
                borderRadius: '6px',
                color: '#ff6666',
                fontSize: '12px',
                marginBottom: '12px',
                display: 'flex',
                justifyContent: 'space-between',
                alignItems: 'center',
              }}>
                <span>{shape.props.error}</span>
                <button
                  onClick={() => updateProps({ error: null })}
                  onPointerDown={(e) => e.stopPropagation()}
                  style={{ background: 'none', border: 'none', color: '#ff6666', cursor: 'pointer' }}
                >
                  ✕
                </button>
              </div>
            )}

            {renderPhaseContent()}
          </div>
        </StandardizedToolWrapper>
      </HTMLContainer>
    )
  }

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

// ============================================================================
// Helper Functions
// ============================================================================

function buildImagePrompt(
  pageOutline: ZinePageOutline,
  topic: string,
  style: ZineStyle,
  tone: ZineTone
): string {
  const styleDesc = STYLES[style]
  const toneDesc = TONES[tone]

  return `Punk zine page ${pageOutline.pageNumber}/8 for "${topic}".

${pageOutline.imagePrompt}

Title text: "${pageOutline.title}"
${pageOutline.subtitle ? `Subtitle: "${pageOutline.subtitle}"` : ''}
${pageOutline.keyPoints.length > 0 ? `Key points: ${pageOutline.keyPoints.join(', ')}` : ''}
${pageOutline.hashtags.length > 0 ? `Hashtags: ${pageOutline.hashtags.join(' ')}` : ''}

Style: ${styleDesc}
Tone: ${toneDesc}

High contrast black and white with neon green accent highlights. Xerox texture, DIY cut-and-paste collage aesthetic, rough edges, rebellious feel.`
}

interface GenerateImageResponse {
  success: boolean
  imageData?: string
  mimeType?: string
  error?: string
}

async function generatePageImage(prompt: string, pageNumber: number): Promise<string> {
  console.log(`🍄 Generating page ${pageNumber} via RunPod proxy...`)
  console.log(`📝 Prompt preview:`, prompt.substring(0, 100) + '...')

  // Use the mycro-zine API which proxies through RunPod (US-based, bypasses geo-restrictions)
  const ZINE_API_URL = 'https://zine.jeffemmett.com/api/generate-image'

  try {
    const response = await fetch(ZINE_API_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ prompt }),
    })

    if (!response.ok) {
      let errorMessage = `HTTP ${response.status}`
      try {
        const errorData = await response.json() as { error?: string }
        if (errorData.error) errorMessage = errorData.error
      } catch {
        // Ignore JSON parse errors
      }
      console.error(`❌ API error for page ${pageNumber}:`, response.status, errorMessage)
      throw new Error(errorMessage)
    }

    const data: GenerateImageResponse = await response.json()

    if (data.success && data.imageData) {
      console.log(`✅ Page ${pageNumber} generated via RunPod proxy`)
      // Convert base64 to data URL
      return `data:${data.mimeType || 'image/png'};base64,${data.imageData}`
    }

    throw new Error('No image data in response')
  } catch (error) {
    console.error(`❌ Generation failed for page ${pageNumber}:`, error)
    // Fallback to placeholder
    return `https://via.placeholder.com/825x1275/1a1a1a/00ff00?text=Page+${pageNumber}+%28Generation+Failed%29`
  }
}

// Removed direct Gemini API functions - now using zine.jeffemmett.com proxy

async function spawnPageOnCanvas(
  editor: any,
  imageUrl: string,
  index: number,
  parentShape: IMycroZineGenerator
): Promise<string | undefined> {
  try {
    // Calculate position in a 4x2 grid to the right of the generator
    const col = index % 4
    const row = Math.floor(index / 4)
    const spacing = 20
    const pageWidth = 200
    const pageHeight = 300

    const x = parentShape.props.w + 50 + col * (pageWidth + spacing)
    const y = row * (pageHeight + spacing)

    // Get parent shape position
    const parentBounds = editor.getShapePageBounds(parentShape.id)
    if (!parentBounds) return undefined

    const shapeId = createShapeId()

    // Create an image shape on the canvas
    editor.createShape({
      id: shapeId,
      type: 'image',
      x: parentBounds.x + x,
      y: parentBounds.y + y,
      props: {
        w: pageWidth,
        h: pageHeight,
        url: imageUrl,
      },
    })

    return shapeId
  } catch (err) {
    console.error('Failed to spawn page on canvas:', err)
    return undefined
  }
}

// ============================================================================
// Styles
// ============================================================================

const inputStyle: React.CSSProperties = {
  flex: 1,
  padding: '10px 12px',
  backgroundColor: '#1a1a1a',
  border: '1px solid #333',
  borderRadius: '6px',
  color: '#fff',
  fontSize: '13px',
  outline: 'none',
}

const buttonStyle: React.CSSProperties = {
  padding: '10px 16px',
  backgroundColor: '#00ff00',
  border: 'none',
  borderRadius: '6px',
  color: '#000',
  fontSize: '13px',
  fontWeight: 'bold',
  cursor: 'pointer',
  transition: 'opacity 0.15s',
}

const selectStyle: React.CSSProperties = {
  flex: 1,
  padding: '8px 12px',
  backgroundColor: '#1a1a1a',
  border: '1px solid #333',
  borderRadius: '6px',
  color: '#fff',
  fontSize: '12px',
  cursor: 'pointer',
}
