← back to Letsbegin

components/PRDGeneratorStep.tsx

1284 lines

'use client'

import { useState } from 'react'
import CollapsibleSection from './CollapsibleSection'
import SimplifiedQuestionnaire from './SimplifiedQuestionnaire'

interface PRDData {
  projectName: string
  featureTitle: string
  problemStatement: string
  targetUser: string
  scope: string
  priority: string
  keyFeatures: string
  nonGoals: string
  successMetrics: string
  components: string[]
  integrations: string
  techStack: string
  additionalAnswers: string
  competitorUrls: string[]
  appStoreUrls: string[]
  uploadedFiles: string[]
  researchOptions: {
    searchGithub: boolean
    searchPublicDBs: boolean
    searchSkills: boolean
    searchAgents: boolean
    searchAppStore: boolean
    searchPlayStore: boolean
  }
}

interface Project {
  name: string
  path: string
  hasClaudeMd: boolean
}

interface GitInfo {
  isRepo: boolean
  branch: string | null
  remoteUrl: string | null
  lastCommit: string | null
  lastCommitDate: string | null
  uncommittedChanges: number
  hasGitignore: boolean
}

interface SecurityFeatures {
  hasAuth: boolean
  hasEnvExample: boolean
  hasEnvLocal: boolean
  hasSecrets: boolean
  authType: string | null
  hasHttps: boolean
  hasCors: boolean
  hasRateLimiting: boolean
  hasInputValidation: boolean
  hasCSRF: boolean
}

interface DetectedAPI {
  name: string
  type: 'ai' | 'payment' | 'storage' | 'auth' | 'email' | 'analytics' | 'other'
  detected: boolean
  envVar?: string
}

interface ProjectScanResult {
  name: string
  path: string
  description: string
  techStack: string[]
  dependencies: string[]
  components: string[]
  existingPRDs: string[]
  hasReadme: boolean
  hasClaudeMd: boolean
  hasPackageJson: boolean
  git: GitInfo
  security: SecurityFeatures
  detectedAPIs: DetectedAPI[]
  recentFiles: string[]
  suggestedFeatures: string[]
}

interface Props {
  prdData: PRDData
  setPrdData: (data: PRDData) => void
  selectedProject: Project | null
  onGenerate: (prd: string) => void
  generatedPRD: string
}

const targetUserOptions = [
  { value: 'A', label: 'New users', description: 'First-time visitors to the application' },
  { value: 'B', label: 'Existing users', description: 'Users already familiar with the app' },
  { value: 'C', label: 'Admin users', description: 'Administrators and power users' },
  { value: 'D', label: 'All users', description: 'Everyone who uses the application' },
]

const scopeOptions = [
  { value: 'A', label: 'Minimal viable', description: 'Core functionality only' },
  { value: 'B', label: 'Full-featured', description: 'Complete implementation' },
  { value: 'C', label: 'Backend only', description: 'API and database changes' },
  { value: 'D', label: 'Frontend only', description: 'UI and UX changes' },
]

const priorityOptions = [
  { value: 'A', label: 'Critical/ASAP', description: 'Needs immediate attention' },
  { value: 'B', label: 'High', description: 'Important for upcoming release' },
  { value: 'C', label: 'Medium', description: 'Should be done when possible' },
  { value: 'D', label: 'Low/Nice-to-have', description: 'Can wait for future releases' },
]

const techStackOptions = [
  'Next.js 16 + React 19',
  'React 19 (Standalone)',
  'Node.js + Express',
  'Python + FastAPI',
  'Other',
]

// Clarifying question from the PRD skill
interface ClarifyingQuestion {
  id: string
  question: string
  options: { key: string; label: string }[]
  answer?: string
}

export default function PRDGeneratorStep({ prdData, setPrdData, selectedProject, onGenerate, generatedPRD }: Props) {
  const [isGenerating, setIsGenerating] = useState(false)
  const [isScanning, setIsScanning] = useState(false)
  const [scanResult, setScanResult] = useState<ProjectScanResult | null>(null)
  const [showPreview, setShowPreview] = useState(false)
  const [useSimplifiedMode, setUseSimplifiedMode] = useState(false)
  const [competitorSuggestion, setCompetitorSuggestion] = useState<string | null>(null)
  const [appStoreSuggestion, setAppStoreSuggestion] = useState<string | null>(null)
  const [isLoadingCompetitorSuggestion, setIsLoadingCompetitorSuggestion] = useState(false)
  const [isLoadingAppStoreSuggestion, setIsLoadingAppStoreSuggestion] = useState(false)

  // New state for skill-based clarifying questions flow
  const [skillStep, setSkillStep] = useState<'questionnaire' | 'clarifying' | 'generating' | 'preview'>('questionnaire')
  const [clarifyingQuestions, setClarifyingQuestions] = useState<ClarifyingQuestion[]>([])
  const [isLoadingQuestions, setIsLoadingQuestions] = useState(false)

  const [expandedSections, setExpandedSections] = useState({
    foundation: false,
    targetScope: false,
    requirements: false,
    technical: false,
    inspiration: false,
    additional: false,
  })

  // Handle simplified questionnaire completion
  const handleSimplifiedComplete = async () => {
    setUseSimplifiedMode(false)
    // Submit to skill flow instead of directly generating
    if (prdData.featureTitle && prdData.problemStatement) {
      submitToSkill()
    }
  }

  // Show simplified questionnaire if enabled
  if (useSimplifiedMode) {
    return (
      <SimplifiedQuestionnaire
        prdData={prdData}
        setPrdData={setPrdData as React.Dispatch<React.SetStateAction<PRDData>>}
        selectedProject={selectedProject}
        onComplete={handleSimplifiedComplete}
        onCancel={() => setUseSimplifiedMode(false)}
      />
    )
  }

  // Fetch Claude suggestions for competitor URLs
  async function fetchCompetitorSuggestions() {
    setIsLoadingCompetitorSuggestion(true)
    setCompetitorSuggestion(null)
    try {
      const res = await fetch('/api/claude/suggest', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          projectName: prdData.projectName || selectedProject?.name,
          currentField: 'competitorUrls',
          currentQuestion: 'Competitor or Inspiration Apps',
          existingData: prdData
        })
      })
      if (res.ok) {
        const data = await res.json()
        setCompetitorSuggestion(data.suggestion)
      }
    } catch (err) {
      console.error('Suggestion error:', err)
      setCompetitorSuggestion('Unable to get suggestions. Please try again.')
    } finally {
      setIsLoadingCompetitorSuggestion(false)
    }
  }

  // Fetch Claude suggestions for App Store URLs
  async function fetchAppStoreSuggestions() {
    setIsLoadingAppStoreSuggestion(true)
    setAppStoreSuggestion(null)
    try {
      const res = await fetch('/api/claude/suggest', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          projectName: prdData.projectName || selectedProject?.name,
          currentField: 'appStoreUrls',
          currentQuestion: 'Similar Apps on App Store / Play Store',
          existingData: prdData
        })
      })
      if (res.ok) {
        const data = await res.json()
        setAppStoreSuggestion(data.suggestion)
      }
    } catch (err) {
      console.error('Suggestion error:', err)
      setAppStoreSuggestion('Unable to get suggestions. Please try again.')
    } finally {
      setIsLoadingAppStoreSuggestion(false)
    }
  }

  // Submit to PRD skill - gets clarifying questions
  async function submitToSkill() {
    if (!prdData.featureTitle || !prdData.problemStatement) {
      alert('Please fill in Feature Title and Problem Statement')
      return
    }

    setIsLoadingQuestions(true)
    try {
      const res = await fetch('/api/prd/clarify', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          ...prdData,
          projectPath: selectedProject?.path
        })
      })

      if (!res.ok) {
        throw new Error('Failed to get clarifying questions')
      }

      const data = await res.json()
      if (data.questions && data.questions.length > 0) {
        setClarifyingQuestions(data.questions)
        setSkillStep('clarifying')
      } else {
        // No questions needed, go straight to generation
        setSkillStep('generating')
        await generatePRDWithAnswers([])
      }
    } catch (err) {
      console.error('Failed to get clarifying questions:', err)
      alert('Failed to submit to PRD skill. Please try again.')
    } finally {
      setIsLoadingQuestions(false)
    }
  }

  // Handle answering a clarifying question
  function handleClarifyingAnswer(questionId: string, answer: string) {
    setClarifyingQuestions(prev =>
      prev.map(q => q.id === questionId ? { ...q, answer } : q)
    )
  }

  // Generate PRD with clarifying question answers
  async function generatePRDWithAnswers(answers: ClarifyingQuestion[]) {
    setSkillStep('generating')
    setIsGenerating(true)
    try {
      // Format answers as "1A, 2C, 3B" style
      const formattedAnswers = answers
        .filter(q => q.answer)
        .map((q, i) => `${i + 1}${q.answer}: ${q.question} → ${q.options.find(o => o.key === q.answer)?.label || q.answer}`)
        .join('\n')

      const res = await fetch('/api/prd/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          ...prdData,
          additionalAnswers: prdData.additionalAnswers
            ? `${prdData.additionalAnswers}\n\nClarifying Questions:\n${formattedAnswers}`
            : `Clarifying Questions:\n${formattedAnswers}`,
          projectPath: selectedProject?.path
        })
      })

      const data = await res.json()
      if (data.prd) {
        onGenerate(data.prd)
        setSkillStep('preview')
        setShowPreview(true)
      } else {
        throw new Error(data.error || 'Failed to generate PRD')
      }
    } catch (err) {
      console.error('Failed to generate PRD:', err)
      alert('Failed to generate PRD')
      setSkillStep('clarifying')
    } finally {
      setIsGenerating(false)
    }
  }

  // Submit clarifying answers and generate PRD
  function submitClarifyingAnswers() {
    const unanswered = clarifyingQuestions.filter(q => !q.answer)
    if (unanswered.length > 0) {
      alert(`Please answer all questions. ${unanswered.length} remaining.`)
      return
    }
    generatePRDWithAnswers(clarifyingQuestions)
  }

  // Scan project and auto-fill form fields
  async function handleScanProject() {
    if (!selectedProject?.path) {
      alert('Please select a project first')
      return
    }

    setIsScanning(true)
    try {
      const res = await fetch(`/api/projects/scan?path=${encodeURIComponent(selectedProject.path)}`)

      if (!res.ok) {
        const err = await res.json()
        throw new Error(err.error || 'Failed to scan project')
      }

      const data: ProjectScanResult = await res.json()
      setScanResult(data)

      // Auto-fill form fields from scan result
      const techStackStr = data.techStack.length > 0
        ? (data.techStack.some(t => t.includes('Next.js')) ? 'Next.js 16 + React 19'
          : data.techStack.some(t => t.includes('React')) ? 'React 19 (Standalone)'
          : data.techStack.some(t => t.includes('Express')) ? 'Node.js + Express'
          : 'Other')
        : prdData.techStack

      // Build suggested features as key features
      const suggestedKeyFeatures = data.suggestedFeatures.length > 0
        ? data.suggestedFeatures.map(f => `• ${f}`).join('\n')
        : prdData.keyFeatures

      // Build integrations from dependencies
      const integrations = data.dependencies
        .filter(d => ['@anthropic-ai/sdk', 'axios', 'prisma', 'next-auth', 'stripe'].some(i => d.includes(i)))
        .join(', ') || prdData.integrations

      // Generate feature title if not set
      const featureTitle = prdData.featureTitle || `New Feature for ${data.name}`

      updatePrdData({
        projectName: data.name,
        featureTitle: featureTitle,
        problemStatement: data.description || prdData.problemStatement,
        techStack: techStackStr,
        keyFeatures: suggestedKeyFeatures,
        integrations: integrations,
        components: data.components.map(c => c.replace('.tsx', '').replace('.jsx', ''))
      })

      // Open technical and inspiration sections to show filled data and Search Claude buttons
      setExpandedSections(prev => ({ ...prev, technical: true, inspiration: true }))
    } catch (err) {
      console.error('Failed to scan project:', err)
      alert(err instanceof Error ? err.message : 'Failed to scan project')
    } finally {
      setIsScanning(false)
    }
  }

  function updatePrdData(updates: Partial<PRDData>) {
    setPrdData({ ...prdData, ...updates })
  }

  function toggleSection(section: keyof typeof expandedSections) {
    setExpandedSections(prev => ({ ...prev, [section]: !prev[section] }))
  }

  async function handleGenerate() {
    if (!prdData.featureTitle || !prdData.problemStatement) {
      alert('Please fill in Feature Title and Problem Statement')
      return
    }

    setIsGenerating(true)
    try {
      const res = await fetch('/api/prd/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          ...prdData,
          projectPath: selectedProject?.path
        })
      })
      const data = await res.json()
      if (data.prd) {
        onGenerate(data.prd)
        setShowPreview(true)
      }
    } catch (err) {
      console.error('Failed to generate PRD:', err)
      alert('Failed to generate PRD')
    } finally {
      setIsGenerating(false)
    }
  }

  return (
    <div className="space-y-6">
      {/* Mode Toggle */}
      <div className="flex items-center justify-between p-4 rounded-xl bg-gradient-to-r from-[var(--primary)]/10 to-[var(--secondary)]/10 border border-[var(--border)]">
        <div className="flex items-center gap-4">
          <div>
            <div className="font-medium">Questionnaire Mode</div>
            <div className="text-sm text-[var(--foreground-secondary)]">
              {useSimplifiedMode ? 'One question at a time, large fonts' : 'All questions on one page'}
            </div>
          </div>
        </div>
        <div className="flex items-center gap-3">
          <span className={`text-sm ${!useSimplifiedMode ? 'text-[var(--primary)] font-medium' : 'text-[var(--foreground-secondary)]'}`}>
            Full Form
          </span>
          <button
            onClick={() => setUseSimplifiedMode(!useSimplifiedMode)}
            className={`relative w-14 h-7 rounded-full transition-colors ${
              useSimplifiedMode ? 'bg-[var(--primary)]' : 'bg-[var(--surface-alt)]'
            }`}
          >
            <span
              className={`absolute top-1 w-5 h-5 rounded-full bg-white shadow transition-transform ${
                useSimplifiedMode ? 'translate-x-8' : 'translate-x-1'
              }`}
            />
          </button>
          <span className={`text-sm ${useSimplifiedMode ? 'text-[var(--primary)] font-medium' : 'text-[var(--foreground-secondary)]'}`}>
            Step-by-Step
          </span>
        </div>
      </div>

      {/* Section A: Project Foundation */}
      <CollapsibleSection
        title="Section A: Project Foundation"
        icon="🏗️"
        isExpanded={expandedSections.foundation}
        onToggle={() => toggleSection('foundation')}
      >
        <div className="space-y-4">
          {/* Scan Project Button */}
          {selectedProject && (
            <div className="flex items-center justify-between p-3 rounded-lg bg-[var(--surface-alt)] border border-[var(--border)]">
              <div className="flex items-center gap-3">
                <span className="text-lg">📂</span>
                <div>
                  <div className="font-medium">{selectedProject.name}</div>
                  <div className="text-xs text-[var(--foreground-tertiary)]">{selectedProject.path}</div>
                </div>
              </div>
              <button
                onClick={handleScanProject}
                disabled={isScanning}
                className="btn-primary text-sm px-4 py-2"
              >
                {isScanning ? (
                  <>
                    <svg className="w-4 h-4 animate-spin mr-2 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
                    </svg>
                    Scanning...
                  </>
                ) : (
                  <>🔍 Scan & Fill Fields</>
                )}
              </button>
            </div>
          )}

          {/* Scan Result Summary */}
          {scanResult && (
            <div className="space-y-3">
              {/* Basic Info */}
              <div className="p-3 rounded-lg bg-[var(--success)]/10 border border-[var(--success)]/30">
                <div className="flex items-center gap-2 mb-2">
                  <span className="text-[var(--success)]">✓</span>
                  <span className="font-medium text-[var(--success)]">Project Scanned Successfully</span>
                </div>
                <div className="grid grid-cols-2 md:grid-cols-4 gap-2 text-xs">
                  <div className="flex items-center gap-1">
                    <span>{scanResult.hasPackageJson ? '✓' : '✗'}</span>
                    <span>package.json</span>
                  </div>
                  <div className="flex items-center gap-1">
                    <span>{scanResult.hasReadme ? '✓' : '✗'}</span>
                    <span>README.md</span>
                  </div>
                  <div className="flex items-center gap-1">
                    <span>{scanResult.hasClaudeMd ? '✓' : '✗'}</span>
                    <span>CLAUDE.md</span>
                  </div>
                  <div className="flex items-center gap-1">
                    <span>{scanResult.git.isRepo ? '✓' : '✗'}</span>
                    <span>Git</span>
                  </div>
                </div>
                {scanResult.techStack.length > 0 && (
                  <div className="mt-2 flex flex-wrap gap-1">
                    {scanResult.techStack.map((tech, i) => (
                      <span key={i} className="px-2 py-0.5 text-xs rounded bg-[var(--primary)]/20 text-[var(--primary)]">
                        {tech}
                      </span>
                    ))}
                  </div>
                )}
              </div>

              {/* Git Info */}
              {scanResult.git.isRepo && (
                <div className="p-3 rounded-lg bg-[var(--surface-alt)] border border-[var(--border)]">
                  <div className="flex items-center gap-2 mb-2">
                    <span>📦</span>
                    <span className="font-medium text-sm">Git Repository</span>
                  </div>
                  <div className="grid grid-cols-2 gap-2 text-xs">
                    <div>
                      <span className="text-[var(--foreground-tertiary)]">Branch:</span>{' '}
                      <span className="text-[var(--primary)]">{scanResult.git.branch}</span>
                    </div>
                    {scanResult.git.remoteUrl && (
                      <div className="truncate">
                        <span className="text-[var(--foreground-tertiary)]">Remote:</span>{' '}
                        <span>{scanResult.git.remoteUrl.replace('https://github.com/', '').replace('.git', '')}</span>
                      </div>
                    )}
                    {scanResult.git.lastCommit && (
                      <div className="col-span-2 truncate">
                        <span className="text-[var(--foreground-tertiary)]">Last Commit:</span>{' '}
                        <span>{scanResult.git.lastCommit}</span>
                      </div>
                    )}
                    {scanResult.git.uncommittedChanges > 0 && (
                      <div>
                        <span className="text-[var(--warning)]">⚠ {scanResult.git.uncommittedChanges} uncommitted changes</span>
                      </div>
                    )}
                  </div>
                </div>
              )}

              {/* Security Features */}
              <div className="p-3 rounded-lg bg-[var(--surface-alt)] border border-[var(--border)]">
                <div className="flex items-center gap-2 mb-2">
                  <span>🔐</span>
                  <span className="font-medium text-sm">Security Features</span>
                </div>
                <div className="grid grid-cols-2 md:grid-cols-3 gap-2 text-xs">
                  <label className="flex items-center gap-2 cursor-default">
                    <input type="checkbox" checked={scanResult.security.hasAuth} readOnly className="accent-[var(--success)]" />
                    <span>Authentication {scanResult.security.authType && `(${scanResult.security.authType})`}</span>
                  </label>
                  <label className="flex items-center gap-2 cursor-default">
                    <input type="checkbox" checked={scanResult.security.hasEnvLocal} readOnly className="accent-[var(--success)]" />
                    <span>Env Variables</span>
                  </label>
                  <label className="flex items-center gap-2 cursor-default">
                    <input type="checkbox" checked={scanResult.security.hasEnvExample} readOnly className="accent-[var(--success)]" />
                    <span>.env.example</span>
                  </label>
                  <label className="flex items-center gap-2 cursor-default">
                    <input type="checkbox" checked={scanResult.security.hasCors} readOnly className="accent-[var(--success)]" />
                    <span>CORS Protection</span>
                  </label>
                  <label className="flex items-center gap-2 cursor-default">
                    <input type="checkbox" checked={scanResult.security.hasRateLimiting} readOnly className="accent-[var(--success)]" />
                    <span>Rate Limiting</span>
                  </label>
                  <label className="flex items-center gap-2 cursor-default">
                    <input type="checkbox" checked={scanResult.security.hasInputValidation} readOnly className="accent-[var(--success)]" />
                    <span>Input Validation</span>
                  </label>
                  <label className="flex items-center gap-2 cursor-default">
                    <input type="checkbox" checked={scanResult.security.hasCSRF} readOnly className="accent-[var(--success)]" />
                    <span>CSRF Protection</span>
                  </label>
                  <label className="flex items-center gap-2 cursor-default">
                    <input type="checkbox" checked={scanResult.git.hasGitignore} readOnly className="accent-[var(--success)]" />
                    <span>.gitignore</span>
                  </label>
                </div>
                {scanResult.security.hasSecrets && (
                  <div className="mt-2 text-xs text-[var(--warning)]">
                    ⚠ Potential hardcoded secrets detected in source files
                  </div>
                )}
              </div>

              {/* Detected APIs */}
              {scanResult.detectedAPIs.length > 0 && (
                <div className="p-3 rounded-lg bg-[var(--surface-alt)] border border-[var(--border)]">
                  <div className="flex items-center gap-2 mb-2">
                    <span>🔌</span>
                    <span className="font-medium text-sm">Detected APIs ({scanResult.detectedAPIs.length})</span>
                  </div>
                  <div className="grid grid-cols-2 md:grid-cols-3 gap-2">
                    {scanResult.detectedAPIs.map((api, i) => (
                      <div key={i} className="flex items-center gap-2 text-xs p-2 rounded bg-[var(--surface)] border border-[var(--border)]">
                        <span className={`w-2 h-2 rounded-full ${
                          api.type === 'ai' ? 'bg-purple-500' :
                          api.type === 'payment' ? 'bg-green-500' :
                          api.type === 'storage' ? 'bg-blue-500' :
                          api.type === 'auth' ? 'bg-yellow-500' :
                          api.type === 'email' ? 'bg-pink-500' :
                          api.type === 'analytics' ? 'bg-cyan-500' : 'bg-gray-500'
                        }`} />
                        <div>
                          <div className="font-medium">{api.name}</div>
                          <div className="text-[var(--foreground-tertiary)] text-[10px]">{api.envVar}</div>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {scanResult.existingPRDs.length > 0 && (
                <div className="text-xs text-[var(--foreground-secondary)]">
                  Existing PRDs: {scanResult.existingPRDs.join(', ')}
                </div>
              )}
            </div>
          )}

          <div>
            <label className="block text-sm font-medium mb-2">Project Name</label>
            <input
              type="text"
              className="input"
              value={prdData.projectName}
              onChange={(e) => updatePrdData({ projectName: e.target.value })}
              placeholder={selectedProject?.name || 'Enter project name'}
            />
          </div>

          <div>
            <label className="block text-sm font-medium mb-2">Feature Title *</label>
            <input
              type="text"
              className="input"
              value={prdData.featureTitle}
              onChange={(e) => updatePrdData({ featureTitle: e.target.value })}
              placeholder="e.g., Voice Auto-Start Enhancement"
            />
          </div>

          <div>
            <label className="block text-sm font-medium mb-2">Problem Statement *</label>
            <textarea
              className="textarea"
              value={prdData.problemStatement}
              onChange={(e) => updatePrdData({ problemStatement: e.target.value })}
              placeholder="What problem does this feature solve? Why is it needed?"
              rows={3}
            />
          </div>
        </div>
      </CollapsibleSection>

      {/* Section B: Target & Scope */}
      <CollapsibleSection
        title="Section B: Target & Scope"
        icon="🎯"
        isExpanded={expandedSections.targetScope}
        onToggle={() => toggleSection('targetScope')}
      >
        <div className="space-y-6">
          {/* Q1: Target User */}
          <div>
            <label className="block text-sm font-medium mb-3">
              Q1: Who is the primary user?
            </label>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
              {targetUserOptions.map((opt) => (
                <div
                  key={opt.value}
                  className={`radio-option ${prdData.targetUser === opt.value ? 'selected' : ''}`}
                  onClick={() => updatePrdData({ targetUser: opt.value })}
                >
                  <div className={`radio-dot ${prdData.targetUser === opt.value ? 'selected' : ''}`} />
                  <div>
                    <div className="font-medium">{opt.value}) {opt.label}</div>
                    <div className="text-xs text-[var(--foreground-tertiary)]">{opt.description}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>

          {/* Q2: Scope */}
          <div>
            <label className="block text-sm font-medium mb-3">
              Q2: What is the scope?
            </label>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
              {scopeOptions.map((opt) => (
                <div
                  key={opt.value}
                  className={`radio-option ${prdData.scope === opt.value ? 'selected' : ''}`}
                  onClick={() => updatePrdData({ scope: opt.value })}
                >
                  <div className={`radio-dot ${prdData.scope === opt.value ? 'selected' : ''}`} />
                  <div>
                    <div className="font-medium">{opt.value}) {opt.label}</div>
                    <div className="text-xs text-[var(--foreground-tertiary)]">{opt.description}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>

          {/* Q3: Priority */}
          <div>
            <label className="block text-sm font-medium mb-3">
              Q3: Priority level?
            </label>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
              {priorityOptions.map((opt) => (
                <div
                  key={opt.value}
                  className={`radio-option ${prdData.priority === opt.value ? 'selected' : ''}`}
                  onClick={() => updatePrdData({ priority: opt.value })}
                >
                  <div className={`radio-dot ${prdData.priority === opt.value ? 'selected' : ''}`} />
                  <div>
                    <div className="font-medium">{opt.value}) {opt.label}</div>
                    <div className="text-xs text-[var(--foreground-tertiary)]">{opt.description}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </CollapsibleSection>

      {/* Section C: Core Requirements */}
      <CollapsibleSection
        title="Section C: Core Requirements"
        icon="📋"
        isExpanded={expandedSections.requirements}
        onToggle={() => toggleSection('requirements')}
      >
        <div className="space-y-4">
          <div>
            <label className="block text-sm font-medium mb-2">Key Features (bullet points)</label>
            <textarea
              className="textarea"
              value={prdData.keyFeatures}
              onChange={(e) => updatePrdData({ keyFeatures: e.target.value })}
              placeholder="• Feature 1&#10;• Feature 2&#10;• Feature 3"
              rows={4}
            />
          </div>

          <div>
            <label className="block text-sm font-medium mb-2">Non-Goals (what this should NOT do)</label>
            <textarea
              className="textarea"
              value={prdData.nonGoals}
              onChange={(e) => updatePrdData({ nonGoals: e.target.value })}
              placeholder="• Should not affect existing functionality&#10;• Not handling edge case X"
              rows={3}
            />
          </div>

          <div>
            <label className="block text-sm font-medium mb-2">Success Metrics</label>
            <textarea
              className="textarea"
              value={prdData.successMetrics}
              onChange={(e) => updatePrdData({ successMetrics: e.target.value })}
              placeholder="• Response time under 2 seconds&#10;• 90% user satisfaction"
              rows={3}
            />
          </div>
        </div>
      </CollapsibleSection>

      {/* Section D: Technical Context */}
      <CollapsibleSection
        title="Section D: Technical Context"
        icon="⚙️"
        isExpanded={expandedSections.technical}
        onToggle={() => toggleSection('technical')}
      >
        <div className="space-y-4">
          {/* Scanned Components */}
          {scanResult && scanResult.components.length > 0 && (
            <div>
              <label className="block text-sm font-medium mb-2">
                Existing Components to Reuse ({scanResult.components.length} found)
              </label>
              <div className="grid grid-cols-2 md:grid-cols-3 gap-2 p-3 rounded-lg bg-[var(--surface-alt)] border border-[var(--border)]">
                {scanResult.components.map((comp, i) => {
                  const compName = comp.replace('.tsx', '').replace('.jsx', '')
                  const isSelected = prdData.components.includes(compName)
                  return (
                    <label
                      key={i}
                      className={`flex items-center gap-2 p-2 rounded cursor-pointer transition-colors ${
                        isSelected ? 'bg-[var(--primary)]/20' : 'hover:bg-[var(--surface)]'
                      }`}
                    >
                      <input
                        type="checkbox"
                        checked={isSelected}
                        onChange={(e) => {
                          if (e.target.checked) {
                            updatePrdData({ components: [...prdData.components, compName] })
                          } else {
                            updatePrdData({ components: prdData.components.filter(c => c !== compName) })
                          }
                        }}
                        className="accent-[var(--primary)]"
                      />
                      <span className="text-sm">{comp}</span>
                    </label>
                  )
                })}
              </div>
            </div>
          )}

          {/* Recent Files */}
          {scanResult && scanResult.recentFiles.length > 0 && (
            <div>
              <label className="block text-sm font-medium mb-2">Recently Modified Files</label>
              <div className="p-3 rounded-lg bg-[var(--surface-alt)] border border-[var(--border)] text-xs font-mono max-h-32 overflow-y-auto">
                {scanResult.recentFiles.map((file, i) => (
                  <div key={i} className="text-[var(--foreground-secondary)] py-0.5">{file}</div>
                ))}
              </div>
            </div>
          )}

          {/* Dependencies */}
          {scanResult && scanResult.dependencies.length > 0 && (
            <div>
              <label className="block text-sm font-medium mb-2">Dependencies ({scanResult.dependencies.length})</label>
              <div className="flex flex-wrap gap-1">
                {scanResult.dependencies.map((dep, i) => (
                  <span key={i} className="px-2 py-0.5 text-xs rounded bg-[var(--surface-alt)] border border-[var(--border)]">
                    {dep}
                  </span>
                ))}
              </div>
            </div>
          )}

          <div>
            <label className="block text-sm font-medium mb-2">Integration Points</label>
            <input
              type="text"
              className="input"
              value={prdData.integrations}
              onChange={(e) => updatePrdData({ integrations: e.target.value })}
              placeholder="e.g., ElevenLabs API, Browser Web Audio API"
            />
          </div>

          <div>
            <label className="block text-sm font-medium mb-2">Tech Stack</label>
            <select
              className="input"
              value={prdData.techStack}
              onChange={(e) => updatePrdData({ techStack: e.target.value })}
            >
              {techStackOptions.map((opt) => (
                <option key={opt} value={opt}>{opt}</option>
              ))}
            </select>
          </div>
        </div>
      </CollapsibleSection>

      {/* Section E: Inspiration & Research */}
      <CollapsibleSection
        title="Section E: Inspiration & Research"
        icon="🔍"
        isExpanded={expandedSections.inspiration || false}
        onToggle={() => toggleSection('inspiration')}
      >
        <div className="space-y-6">
          {/* Competitor/Inspiration URLs */}
          <div>
            <label className="block text-sm font-medium mb-2">
              Competitor or Inspiration Apps (URLs)
            </label>
            <p className="text-xs text-[var(--foreground-tertiary)] mb-3">
              Add links to similar apps or websites for reference
            </p>
            <div className="space-y-2">
              {(prdData.competitorUrls || ['']).map((url, index) => (
                <div key={index} className="flex gap-2">
                  <input
                    type="url"
                    className="input flex-1"
                    value={url}
                    onChange={(e) => {
                      const newUrls = [...(prdData.competitorUrls || [''])]
                      newUrls[index] = e.target.value
                      updatePrdData({ competitorUrls: newUrls })
                    }}
                    placeholder="https://example.com"
                  />
                  {index === (prdData.competitorUrls || ['']).length - 1 ? (
                    <button
                      onClick={() => updatePrdData({ competitorUrls: [...(prdData.competitorUrls || ['']), ''] })}
                      className="px-3 py-2 rounded-lg bg-[var(--primary)]/20 text-[var(--primary)] hover:bg-[var(--primary)]/30 transition-colors"
                    >
                      + Add
                    </button>
                  ) : (
                    <button
                      onClick={() => {
                        const newUrls = (prdData.competitorUrls || ['']).filter((_, i) => i !== index)
                        updatePrdData({ competitorUrls: newUrls.length ? newUrls : [''] })
                      }}
                      className="px-3 py-2 rounded-lg bg-red-500/20 text-red-400 hover:bg-red-500/30 transition-colors"
                    >
                      Remove
                    </button>
                  )}
                </div>
              ))}
            </div>

            {/* Search Claude Button */}
            <button
              onClick={fetchCompetitorSuggestions}
              disabled={isLoadingCompetitorSuggestion}
              className="mt-3 w-full flex items-center justify-center gap-2 px-4 py-3 rounded-lg bg-gradient-to-r from-purple-500/20 to-blue-500/20 border border-purple-500/30 text-purple-300 hover:from-purple-500/30 hover:to-blue-500/30 transition-all disabled:opacity-50"
            >
              {isLoadingCompetitorSuggestion ? (
                <>
                  <svg className="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
                    <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                    <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
                  </svg>
                  <span>Searching...</span>
                </>
              ) : (
                <>
                  <span>🔍</span>
                  <span>Search Claude for Suggestions</span>
                </>
              )}
            </button>

            {/* Suggestion Display */}
            {competitorSuggestion && (
              <div className="mt-3 p-4 rounded-lg bg-blue-500/10 border border-blue-500/30">
                <div className="flex items-start gap-2">
                  <span className="text-lg">💡</span>
                  <div className="flex-1">
                    <p className="text-sm text-blue-300 whitespace-pre-wrap">{competitorSuggestion}</p>
                    <button
                      onClick={() => setCompetitorSuggestion(null)}
                      className="mt-2 text-xs text-blue-400 hover:underline"
                    >
                      Dismiss
                    </button>
                  </div>
                </div>
              </div>
            )}
          </div>

          {/* App Store URLs */}
          <div>
            <label className="block text-sm font-medium mb-2">
              Similar Apps on App Store / Play Store
            </label>
            <p className="text-xs text-[var(--foreground-tertiary)] mb-3">
              Links to mobile apps for inspiration
            </p>
            <div className="space-y-2">
              {(prdData.appStoreUrls || ['']).map((url, index) => (
                <div key={index} className="flex gap-2">
                  <input
                    type="url"
                    className="input flex-1"
                    value={url}
                    onChange={(e) => {
                      const newUrls = [...(prdData.appStoreUrls || [''])]
                      newUrls[index] = e.target.value
                      updatePrdData({ appStoreUrls: newUrls })
                    }}
                    placeholder="https://apps.apple.com/... or https://play.google.com/..."
                  />
                  {index === (prdData.appStoreUrls || ['']).length - 1 ? (
                    <button
                      onClick={() => updatePrdData({ appStoreUrls: [...(prdData.appStoreUrls || ['']), ''] })}
                      className="px-3 py-2 rounded-lg bg-[var(--primary)]/20 text-[var(--primary)] hover:bg-[var(--primary)]/30 transition-colors"
                    >
                      + Add
                    </button>
                  ) : (
                    <button
                      onClick={() => {
                        const newUrls = (prdData.appStoreUrls || ['']).filter((_, i) => i !== index)
                        updatePrdData({ appStoreUrls: newUrls.length ? newUrls : [''] })
                      }}
                      className="px-3 py-2 rounded-lg bg-red-500/20 text-red-400 hover:bg-red-500/30 transition-colors"
                    >
                      Remove
                    </button>
                  )}
                </div>
              ))}
            </div>

            {/* Search Claude Button for App Store */}
            <button
              onClick={fetchAppStoreSuggestions}
              disabled={isLoadingAppStoreSuggestion}
              className="mt-3 w-full flex items-center justify-center gap-2 px-4 py-3 rounded-lg bg-gradient-to-r from-purple-500/20 to-blue-500/20 border border-purple-500/30 text-purple-300 hover:from-purple-500/30 hover:to-blue-500/30 transition-all disabled:opacity-50"
            >
              {isLoadingAppStoreSuggestion ? (
                <>
                  <svg className="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
                    <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                    <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
                  </svg>
                  <span>Searching...</span>
                </>
              ) : (
                <>
                  <span>🔍</span>
                  <span>Search Claude for App Suggestions</span>
                </>
              )}
            </button>

            {/* App Store Suggestion Display */}
            {appStoreSuggestion && (
              <div className="mt-3 p-4 rounded-lg bg-blue-500/10 border border-blue-500/30">
                <div className="flex items-start gap-2">
                  <span className="text-lg">💡</span>
                  <div className="flex-1">
                    <p className="text-sm text-blue-300 whitespace-pre-wrap">{appStoreSuggestion}</p>
                    <button
                      onClick={() => setAppStoreSuggestion(null)}
                      className="mt-2 text-xs text-blue-400 hover:underline"
                    >
                      Dismiss
                    </button>
                  </div>
                </div>
              </div>
            )}
          </div>

          {/* Research Options */}
          <div>
            <label className="block text-sm font-medium mb-2">
              Research Options
            </label>
            <p className="text-xs text-[var(--foreground-tertiary)] mb-3">
              Select what Claude should research while generating the PRD
            </p>
            <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
              {[
                { key: 'searchGithub', label: 'Search GitHub', icon: '📦', desc: 'Similar projects & code' },
                { key: 'searchPublicDBs', label: 'Public Databases', icon: '🗄️', desc: 'APIs & datasets' },
                { key: 'searchSkills', label: 'Skills Registry', icon: '🎯', desc: 'Existing skills to reuse' },
                { key: 'searchAgents', label: 'Agent Library', icon: '🤖', desc: 'Pre-built agents' },
                { key: 'searchAppStore', label: 'App Store', icon: '🍎', desc: 'iOS app inspiration' },
                { key: 'searchPlayStore', label: 'Play Store', icon: '🤖', desc: 'Android app inspiration' },
              ].map(({ key, label, icon, desc }) => (
                <label
                  key={key}
                  className={`flex items-start gap-3 p-3 rounded-lg cursor-pointer transition-colors border ${
                    prdData.researchOptions?.[key as keyof typeof prdData.researchOptions]
                      ? 'bg-[var(--primary)]/10 border-[var(--primary)]/50'
                      : 'bg-[var(--surface-alt)] border-[var(--border)] hover:border-[var(--primary)]/30'
                  }`}
                >
                  <input
                    type="checkbox"
                    checked={prdData.researchOptions?.[key as keyof typeof prdData.researchOptions] || false}
                    onChange={(e) => {
                      updatePrdData({
                        researchOptions: {
                          ...prdData.researchOptions,
                          [key]: e.target.checked
                        }
                      })
                    }}
                    className="mt-1 accent-[var(--primary)]"
                  />
                  <div>
                    <div className="flex items-center gap-1.5 font-medium text-sm">
                      <span>{icon}</span>
                      <span>{label}</span>
                    </div>
                    <div className="text-xs text-[var(--foreground-tertiary)]">{desc}</div>
                  </div>
                </label>
              ))}
            </div>
          </div>
        </div>
      </CollapsibleSection>

      {/* Section F: Additional Questions */}
      <CollapsibleSection
        title="Section F: Additional Questions"
        icon="❓"
        isExpanded={expandedSections.additional}
        onToggle={() => toggleSection('additional')}
      >
        <div>
          <label className="block text-sm font-medium mb-2">
            Additional Notes or Questions (Optional)
          </label>
          <textarea
            className="textarea"
            value={prdData.additionalAnswers}
            onChange={(e) => updatePrdData({ additionalAnswers: e.target.value })}
            placeholder="Any additional context, constraints, or questions..."
            rows={4}
          />
        </div>
      </CollapsibleSection>

      {/* Actions - Only show in questionnaire step */}
      {skillStep === 'questionnaire' && (
        <div className="flex items-center justify-between p-4 card">
          <div className="text-sm text-[var(--foreground-secondary)]">
            Answers: 1{prdData.targetUser}, 2{prdData.scope}, 3{prdData.priority}
          </div>
          <div className="flex items-center gap-3">
            <button
              onClick={submitToSkill}
              className="btn-primary"
              disabled={isLoadingQuestions}
            >
              {isLoadingQuestions ? (
                <>
                  <svg className="w-4 h-4 animate-spin mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
                  </svg>
                  Submitting...
                </>
              ) : (
                <>📄 Submit to PRD Generator</>
              )}
            </button>
          </div>
        </div>
      )}

      {/* Clarifying Questions Step */}
      {skillStep === 'clarifying' && (
        <div className="card p-6">
          <div className="mb-6">
            <h3 className="text-xl font-semibold flex items-center gap-2 mb-2">
              <span>🤔</span>
              Clarifying Questions
            </h3>
            <p className="text-[var(--foreground-secondary)] text-sm">
              Based on your input, please answer these questions to help generate a better PRD.
              Select the best option for each (A, B, C, or D).
            </p>
          </div>

          <div className="space-y-8">
            {clarifyingQuestions.map((q, index) => (
              <div key={q.id} className="border-b border-[var(--border)] pb-6 last:border-b-0 last:pb-0">
                <div className="font-bold text-lg mb-4">
                  Q{index + 1}: {q.question}
                </div>
                <div className="space-y-2 pl-4">
                  {q.options.map((opt) => (
                    <button
                      key={opt.key}
                      onClick={() => handleClarifyingAnswer(q.id, opt.key)}
                      className={`w-full p-3 rounded-lg border text-left transition-all flex items-start gap-3 ${
                        q.answer === opt.key
                          ? 'bg-[var(--primary)]/20 border-[var(--primary)]'
                          : 'bg-[var(--surface)] border-[var(--border)] hover:border-[var(--primary)]/50'
                      }`}
                    >
                      <span className={`font-bold min-w-[24px] ${q.answer === opt.key ? 'text-[var(--primary)]' : ''}`}>
                        {opt.key})
                      </span>
                      <span className="text-[var(--foreground-secondary)]">{opt.label}</span>
                    </button>
                  ))}
                </div>
              </div>
            ))}
          </div>

          <div className="flex items-center justify-between mt-6 pt-4 border-t border-[var(--border)]">
            <button
              onClick={() => setSkillStep('questionnaire')}
              className="btn-secondary"
            >
              ← Back to Questionnaire
            </button>
            <div className="flex items-center gap-2 text-sm text-[var(--foreground-secondary)]">
              <span>
                {clarifyingQuestions.filter(q => q.answer).length}/{clarifyingQuestions.length} answered
              </span>
            </div>
            <button
              onClick={submitClarifyingAnswers}
              className="btn-primary"
              disabled={clarifyingQuestions.some(q => !q.answer)}
            >
              Generate PRD →
            </button>
          </div>
        </div>
      )}

      {/* Generating Step */}
      {skillStep === 'generating' && (
        <div className="card p-8 text-center">
          <div className="flex flex-col items-center gap-4">
            <svg className="w-12 h-12 animate-spin text-[var(--primary)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
            </svg>
            <div className="text-xl font-medium">Generating PRD...</div>
            <p className="text-[var(--foreground-secondary)]">
              Claude is creating your Product Requirements Document based on your inputs.
            </p>
          </div>
        </div>
      )}

      {/* Preview - Only show after PRD is generated */}
      {skillStep === 'preview' && generatedPRD && (
        <div className="card p-4">
          <div className="flex items-center justify-between mb-4">
            <h3 className="font-medium flex items-center gap-2">
              <span>📄</span>
              Live Preview
            </h3>
            <button
              onClick={() => navigator.clipboard.writeText(generatedPRD)}
              className="text-sm text-[var(--primary)] hover:underline"
            >
              Copy to Clipboard
            </button>
          </div>
          <div className="code-block max-h-96 overflow-y-auto text-sm">
            <pre>{generatedPRD}</pre>
          </div>
        </div>
      )}
    </div>
  )
}