import { useState, useCallback, useRef, useEffect } from 'react'
import { useSearchParams, useNavigate } from 'react-router-dom'
import { BrandLogo } from '@/components/common/BrandLogo'
import { PageMeta } from '@/components/common/PageMeta'

// ── Survey Data Types ──

type QuestionType = 'mc' | 'mc-multi' | 'range' | 'text' | 'rank'

interface SurveyQuestion {
  id: string
  type: QuestionType
  num: string
  text: string
  hint?: string
  options?: string[]
  items?: string[]
  min?: number
  max?: number
  step?: number
  suffix?: string
  low_label?: string
  high_label?: string
}

interface SurveySlideData {
  id: string
  questions: SurveyQuestion[]
  scenario?: {
    title: string
    symptom: string
    details: string
  }
}

// ── Survey Questions (from reference HTML) ──

const SLIDES: SurveySlideData[] = [
  {
    id: 'prework',
    questions: [
      { id: 'prereqs', type: 'mc-multi', num: '1', text: 'Before you start troubleshooting, what info do you need? (Select all that apply)', hint: 'What do you gather or verify before you even start diagnosing?',
        options: ["Who's affected (one user, group, everyone)", "What changed recently (patches, config, new software)", "Is there an existing/related ticket", "Client environment details (domain, VPN, on-prem vs. cloud)", "How long the issue has been happening", "User's exact error message or screenshot", "Whether the user has already tried anything", "RMM/monitoring status for the device or service"] },
      { id: 'verify_fix', type: 'mc', num: '2', text: 'After you apply a fix, how do you verify it actually worked?',
        options: ["Have the user confirm it's working", "Test it myself from their machine or account", "Run the same diagnostic command that showed the failure", "Check monitoring/logs to confirm the service is healthy", "All of the above in sequence", "Fix it and move on — if they don't call back, it worked"] },
      { id: 'steps_at_a_time', type: 'range', num: '3', text: 'When following a troubleshooting guide, how many steps do you prefer to see at once?', hint: '1 = show me one step at a time, 10 = give me the full picture upfront.',
        min: 1, max: 10, step: 1, suffix: ' steps', low_label: 'One at a time', high_label: 'Show me everything' },
    ]
  },
  {
    id: 'philosophy',
    questions: [
      { id: 'first_step', type: 'mc', num: '4', text: 'A vague ticket comes in: "Internet is down." What\'s your FIRST move?', hint: 'Before any technical check — what\'s the first mental step?',
        options: ["Check if it's one user or many (scope it)", "Look at monitoring / RMM dashboard", "Check for recent changes or maintenance", "Ask the user clarifying questions", "Ping / basic connectivity test", "Check if other tickets are related"] },
      { id: 'junior_mistake', type: 'mc', num: '5', text: 'What\'s the most common mistake you see junior engineers make?',
        options: ["Jumping to a fix before understanding the problem", "Not checking scope (one user vs. many)", "Ignoring recent changes as a cause", "Googling the error instead of reading it", "Restarting things without checking logs first", "Not documenting what they tried"] },
      { id: 'pivot', type: 'mc', num: '6', text: 'How do you decide when to stop pursuing one theory and pivot?',
        options: ["After 2–3 checks that don't support the theory", "Time-based — if I've spent 15+ min with no progress", "When I find evidence that contradicts the theory", "Gut feeling / experience", "When I run out of ideas on that path"] },
    ]
  },
  {
    id: 'scenario',
    scenario: {
      title: 'Incoming Ticket',
      symptom: 'Multiple users can\'t access \\\\fileserver\\shared',
      details: 'Started ~9 AM. Some users still can. No known recent changes. Server appears online.'
    },
    questions: [
      { id: 'scenario_approach', type: 'text', num: '7', text: 'Walk through your first 3 diagnostic steps for this ticket.', hint: 'Include specific commands/tools, what you expect to see, and what a bad result tells you.' },
      { id: 'scenario_deeper', type: 'text', num: '8', text: 'Server pings fine, you can RDP in. What do you check next on the server itself?', hint: 'Services, shares, permissions, event logs — what\'s your sequence?' },
    ]
  },
  {
    id: 'commands',
    questions: [
      { id: 'doc_pct', type: 'range', num: '9', text: 'Be honest: what percentage of your troubleshooting steps do you actually document in the ticket?', min: 0, max: 100, step: 10, suffix: '%', low_label: 'Almost none', high_label: 'Everything' },
      { id: 'go_to_commands', type: 'text', num: '10', text: 'What are your top 3 go-to PowerShell commands or one-liners? Include exact syntax.', hint: "The ones you type from muscle memory — we're building FlowPilot's command library from real usage." },
      { id: 'secret_weapon', type: 'text', num: '11', text: "Name a command, tool, or technique that junior engineers don't know about but saves you significant time.", hint: 'The secret weapon stuff. This is gold.' },
    ]
  },
  {
    id: 'tribal',
    questions: [
      { id: 'gotcha', type: 'text', num: '12', text: 'Describe an issue where the obvious diagnosis was WRONG. What did everyone assume, and what was it actually?', hint: "These 'gotcha' patterns help FlowPilot warn engineers before they go down the wrong path." },
      { id: 'hard_rules', type: 'mc-multi', num: '13', text: 'Which of these "rules" do you follow? (Select all that apply)',
        options: [
          "Always check recent changes before deep-diving",
          "Screenshot/document current state before making changes",
          "Never restart a service without checking logs first",
          "Verify the user's report before troubleshooting",
          "Check if it's a known issue / existing ticket first",
          "Test the fix, don't assume it worked",
          "Always have a rollback plan"
        ]},
    ]
  },
  {
    id: 'ranking',
    questions: [
      { id: 'prioritization', type: 'rank', num: '14', text: 'Rank these factors by how much they influence your diagnostic order.', hint: 'What drives which theory you investigate first? Drag to reorder — most influential at the top.',
        items: [
          "Likelihood of being the root cause",
          "How fast I can test or rule it out",
          "Blast radius — impact if it's the problem",
          "How recently something changed",
          "Tool / access availability right now",
          "Past experience with similar symptoms"
        ]},
    ]
  },
  {
    id: 'flowpilot',
    questions: [
      { id: 'detail_level', type: 'mc', num: '15', text: 'When an AI suggests a diagnostic step, how specific should it be?',
        options: [
          'High-level only ("Check DNS resolution")',
          'Moderate ("Run nslookup against the domain controller")',
          'Exact syntax ("nslookup hostname dc01.domain.local — verify IP matches expected")',
          'Exact syntax + explanation of WHY and what to look for'
        ]},
      { id: 'ai_personality', type: 'mc', num: '16', text: 'What would make an AI troubleshooting assistant feel like a useful colleague instead of a chatbot?',
        options: [
          "Suggests things I haven't thought of yet",
          "Knows the right diagnostic order (not just alphabetical)",
          "Challenges my assumptions constructively",
          "Includes real commands with exact syntax",
          "Explains WHY we check things in a certain order",
          "Doesn't waste my time with obvious stuff"
        ]},
    ]
  },
]

const TOTAL_QUESTIONS = SLIDES.reduce((n, s) => n + s.questions.length, 0)

// ── Component ──

export default function SurveyPage() {
  const [currentSlide, setCurrentSlide] = useState(0)
  const [answers, setAnswers] = useState<Record<string, string | string[]>>(() => {
    // Initialize rank answers with default order
    const init: Record<string, string[]> = {}
    SLIDES.forEach(s => s.questions.forEach(q => {
      if (q.type === 'rank' && q.items) init[q.id] = [...q.items]
    }))
    return init
  })
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [isComplete, setIsComplete] = useState(false)
  const [submitError, setSubmitError] = useState('')
  const [emailInput, setEmailInput] = useState('')
  const [emailSending, setEmailSending] = useState(false)
  const [emailSent, setEmailSent] = useState(false)
  const [emailError, setEmailError] = useState('')
  const [responseId, setResponseId] = useState<string | null>(null)
  const navigate = useNavigate()

  const [searchParams] = useSearchParams()
  const token = searchParams.get('t')
  const [inviteName, setInviteName] = useState<string | null>(null)
  const [alreadyCompleted, setAlreadyCompleted] = useState(false)
  const [tokenLoading, setTokenLoading] = useState(!!token)

  useEffect(() => {
    if (!token) return
    const apiUrl = import.meta.env.VITE_API_URL || 'http://localhost:8000'
    fetch(`${apiUrl}/api/v1/survey/invite/${token}`)
      .then(r => r.ok ? r.json() : null)
      .then(data => {
        if (data?.status === 'completed') setAlreadyCompleted(true)
        if (data?.name) setInviteName(data.name)
      })
      .catch(() => {})
      .finally(() => setTokenLoading(false))
  }, [token])

  const setAnswer = useCallback((qid: string, value: string | string[]) => {
    setAnswers(prev => ({ ...prev, [qid]: value }))
  }, [])

  const answeredCount = SLIDES.reduce((count, slide) => {
    return count + slide.questions.filter(q => {
      const a = answers[q.id]
      return a !== undefined && a !== '' && (!Array.isArray(a) || a.length > 0)
    }).length
  }, 0)
  const progressPct = Math.round((answeredCount / TOTAL_QUESTIONS) * 100)

  const topRef = useRef<HTMLDivElement>(null)

  const goSlide = (idx: number) => {
    setCurrentSlide(idx)
  }

  // Scroll to top whenever the active slide changes — mobile browsers
  // (especially iOS Safari) ignore window.scrollTo, so we use
  // scrollIntoView on a ref at the top of the page as primary method
  const isFirstRender = useRef(true)
  useEffect(() => {
    if (isFirstRender.current) {
      isFirstRender.current = false
      return
    }
    if (topRef.current) {
      topRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })
    } else {
      window.scrollTo({ top: 0, behavior: 'smooth' })
    }
  }, [currentSlide])

  const handleSubmit = async () => {
    setIsSubmitting(true)
    setSubmitError('')
    try {
      const apiUrl = import.meta.env.VITE_API_URL || 'http://localhost:8000'
      const res = await fetch(`${apiUrl}/api/v1/survey/submit`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ respondent_name: inviteName || undefined, responses: answers, token: token || undefined }),
      })
      if (!res.ok) {
        if (res.status === 409) {
          setAlreadyCompleted(true)
          window.scrollTo({ top: 0, behavior: 'smooth' })
          return
        }
        const errData = await res.json().catch(() => null)
        throw new Error(errData?.detail || `Submission failed (${res.status})`)
      }
      const data = await res.json()
      setResponseId(data.id)
      setIsComplete(true)
      window.scrollTo({ top: 0, behavior: 'smooth' })
    } catch (err) {
      setSubmitError(err instanceof Error ? err.message : 'Submission failed. Try copying your responses instead.')
    } finally {
      setIsSubmitting(false)
    }
  }

  const buildOutput = () => {
    let out = 'FLOWPILOT SURVEY RESPONSE\n========================\n\n'
    SLIDES.forEach(slide => {
      slide.questions.forEach(q => {
        out += `Q${q.num}. ${q.text}\n`
        const a = answers[q.id]
        if (Array.isArray(a)) out += a.map((v, i) => `  ${i + 1}. ${v}`).join('\n') + '\n'
        else if (a) out += `  ${a}\n`
        else out += '  (no answer)\n'
        out += '\n'
      })
    })
    return out
  }

  const copyAll = async () => {
    try {
      await navigator.clipboard.writeText(buildOutput())
      alert('Copied! Paste into an email and send.')
    } catch {
      alert('Copy failed — try selecting the text manually.')
    }
  }

  if (tokenLoading) {
    return (
      <div className="min-h-screen bg-background flex items-center justify-center">
        <div className="text-muted-foreground text-sm">Loading...</div>
      </div>
    )
  }

  if (alreadyCompleted) {
    return (
      <div className="min-h-screen bg-background text-foreground">
        <div className="pointer-events-none fixed inset-0 overflow-hidden" aria-hidden="true">
          <div className="absolute -top-32 right-0 h-[500px] w-[500px] rounded-full opacity-[0.03]" style={{ background: 'radial-gradient(circle, var(--color-primary), transparent 70%)' }} />
          <div className="absolute -bottom-32 left-0 h-[400px] w-[400px] rounded-full opacity-[0.02]" style={{ background: 'radial-gradient(circle, var(--color-accent), transparent 70%)' }} />
        </div>
        <div className="relative z-10 mx-auto max-w-[680px] px-4 sm:px-5">
          <div className="text-center pt-20 sm:pt-32 animate-fade-in-up">
            <div className="w-16 h-16 mx-auto mb-5 rounded-full flex items-center justify-center" style={{ background: 'rgba(96, 165, 250, 0.10)' }}>
              <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="var(--color-primary)" strokeWidth="2.5"><path d="M20 6L9 17l-5-5"/></svg>
            </div>
            <h2 className="font-heading text-2xl font-bold mb-2.5">Already Submitted</h2>
            <p className="text-muted-foreground text-sm max-w-[440px] mx-auto leading-relaxed mb-3">
              {inviteName ? `Thanks ${inviteName} — y` : 'Y'}our response has already been recorded. We appreciate your time!
            </p>
            <p className="text-sm text-muted-foreground/70 max-w-[400px] mx-auto leading-relaxed mb-8">
              You can safely close this browser window now.
            </p>
            <div className="card-flat p-4 sm:p-5 max-w-[400px] mx-auto text-center">
              <p className="text-xs text-muted-foreground leading-relaxed">
                Have feedback unrelated to the survey?{' '}
                <a href="mailto:feedback@resolutionflow.com" className="text-primary hover:underline font-medium">
                  feedback@resolutionflow.com
                </a>
              </p>
            </div>
          </div>
        </div>
      </div>
    )
  }

  return (
    <div ref={topRef} className="min-h-screen bg-background text-foreground">
      <PageMeta
        title="Product Survey"
        description="Help shape the future of ResolutionFlow by sharing your feedback"
      />
      {/* Top bar */}
      <div className="sticky top-0 z-50" style={{ background: 'rgba(26, 28, 35, 0.95)', borderBottom: '1px solid var(--color-border-default)' }}>
        <div className="mx-auto flex max-w-[680px] items-center justify-between gap-3 px-4 py-3 sm:px-5 sm:py-3.5">
          <a href="https://resolutionflow.com" target="_blank" rel="noreferrer" className="flex items-center gap-2 sm:gap-2.5 text-sm font-heading font-bold text-muted-foreground no-underline shrink-0">
            <BrandLogo size="sm" />
            <span className="hidden sm:inline">Resolution<span className="text-accent-text">Flow</span></span>
          </a>
          <div className="flex flex-1 items-center gap-2 sm:gap-2.5" style={{ maxWidth: '280px' }}>
            <div className="flex-1 h-[3px] rounded-full overflow-hidden" style={{ background: 'var(--color-border)' }}>
              <div className="h-full rounded-full bg-primary transition-[width] duration-500" style={{ width: `${progressPct}%` }} />
            </div>
            <span className="text-[11px] font-sans text-xs text-muted-foreground whitespace-nowrap tabular-nums">{answeredCount}/{TOTAL_QUESTIONS}</span>
          </div>
        </div>
      </div>

      <div className="relative z-10 mx-auto max-w-[680px] px-4 pb-20 sm:px-5 sm:pb-24">
        {/* Hero — visible only on first slide */}
        {currentSlide === 0 && !isComplete && (
          <div className="text-center pt-10 pb-8 sm:pt-[72px] sm:pb-10 animate-fade-in-up">
            <div className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-[10px] sm:text-[11px] font-semibold font-sans text-xs uppercase tracking-widest mb-4 sm:mb-5" style={{ background: 'rgba(96, 165, 250, 0.10)', border: '1px solid rgba(96, 165, 250, 0.15)', color: 'var(--color-primary)' }}>
              <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
              FlowPilot Research
            </div>
            <h1 className="font-heading text-[clamp(24px,5vw,36px)] font-extrabold leading-tight mb-3">
              Help Build an AI That<br/>Thinks Like <span className="text-accent-text">You</span>
            </h1>
            <p className="text-[14px] sm:text-[15px] text-muted-foreground max-w-[500px] mx-auto leading-relaxed">
              We're building an AI assistant for MSP engineers. Your expertise shapes how it thinks. Takes about 5 minutes.
            </p>
            <div className="flex flex-wrap justify-center gap-4 sm:gap-7 mt-4 sm:mt-5 text-[11px] sm:text-[12px] text-muted-foreground">
              <span className="flex items-center gap-1.5">
                <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="var(--color-primary)" strokeWidth="2"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
                ~5 minutes
              </span>
              <span className="flex items-center gap-1.5">
                <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="var(--color-primary)" strokeWidth="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
                Confidential
              </span>
              <span className="flex items-center gap-1.5">
                <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="var(--color-primary)" strokeWidth="2"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
                16 questions
              </span>
            </div>
          </div>
        )}

        {/* Step dots */}
        {!isComplete && (
          <div className="flex gap-1 mb-6 sm:mb-9">
            {SLIDES.map((_, i) => (
              <div
                key={i}
                className="flex-1 h-1 sm:h-[3px] rounded-full transition-colors duration-300"
                style={{
                  background: i < currentSlide ? 'oklch(0.76 0.15 163)' : i === currentSlide ? 'linear-gradient(90deg, var(--color-primary), var(--color-brand-gradient-to))' : 'var(--color-border)',
                }}
              />
            ))}
          </div>
        )}

        {/* Slides */}
        {!isComplete && SLIDES.map((slide, si) => (
          si === currentSlide && (
            <div key={slide.id} className="animate-fade-in-up">
              {slide.scenario && <ScenarioBox scenario={slide.scenario} />}
              {slide.questions.map(q => (
                <QuestionCard key={q.id} question={q} answer={answers[q.id]} setAnswer={setAnswer} />
              ))}
              <div className="flex justify-between mt-6 sm:mt-7 gap-3">
                {si > 0 ? (
                  <button onClick={() => goSlide(si - 1)} className="inline-flex items-center gap-2 px-4 py-2.5 sm:px-6 sm:py-3 rounded-lg text-sm font-semibold text-muted-foreground transition-all duration-150 hover:text-foreground" style={{ background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.06)' }}>
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M19 12H5"/><path d="M12 19l-7-7 7-7"/></svg>
                    Back
                  </button>
                ) : <div />}
                {si < SLIDES.length - 1 ? (
                  <button onClick={() => goSlide(si + 1)} className="inline-flex items-center gap-2 px-5 py-2.5 sm:px-6 sm:py-3 rounded-lg text-sm font-semibold bg-primary text-white transition-all duration-150 hover:brightness-110 active:scale-[0.98]">
                    Next
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14"/><path d="M12 5l7 7-7 7"/></svg>
                  </button>
                ) : (
                  <button onClick={handleSubmit} disabled={isSubmitting} className="inline-flex items-center gap-2 px-5 py-2.5 sm:px-6 sm:py-3 rounded-lg text-sm font-semibold bg-primary text-white transition-all duration-150 hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed">
                    {isSubmitting ? 'Submitting...' : 'Submit'}
                    {!isSubmitting && <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M20 6L9 17l-5-5"/></svg>}
                  </button>
                )}
              </div>
              {submitError && (
                <div className="mt-4 p-3 rounded-lg text-sm text-rose-400" style={{ background: 'rgba(244, 63, 94, 0.1)', border: '1px solid rgba(244, 63, 94, 0.2)' }}>
                  {submitError}
                  <button onClick={copyAll} className="ml-3 underline text-muted-foreground hover:text-foreground">Copy responses instead</button>
                </div>
              )}
            </div>
          )
        ))}

        {/* Completion */}
        {isComplete && (
          <div className="text-center pt-10 sm:pt-16 animate-fade-in-up">
            <div className="w-16 h-16 mx-auto mb-5 rounded-full flex items-center justify-center" style={{ background: 'rgba(52, 211, 153, 0.1)' }}>
              <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="oklch(0.76 0.15 163)" strokeWidth="2.5"><path d="M20 6L9 17l-5-5"/></svg>
            </div>
            <h2 className="font-heading text-2xl font-bold mb-2.5">Response Submitted!</h2>
            <p className="text-muted-foreground text-sm max-w-[440px] mx-auto mb-6 sm:mb-8 leading-relaxed">
              Your answers will directly shape how FlowPilot troubleshoots. Would you like a copy of your responses?
            </p>

            {/* Email a copy */}
            <div className="card-flat p-4 sm:p-6 max-w-[420px] mx-auto mb-5">
              <p className="font-sans text-xs text-[0.625rem] uppercase tracking-widest text-muted-foreground mb-3">
                Email a copy to yourself
              </p>
              {!emailSent ? (
                <div className="flex flex-col sm:flex-row gap-2">
                  <input
                    type="email"
                    value={emailInput}
                    onChange={e => setEmailInput(e.target.value)}
                    placeholder="your@email.com"
                    className="flex-1 rounded-[9px] px-3.5 py-2.5 text-sm text-foreground placeholder:text-text-muted focus:outline-hidden"
                    style={{ background: 'rgba(16, 17, 20, 0.6)', border: '1px solid var(--color-border-default)' }}
                    onFocus={e => { e.currentTarget.style.borderColor = 'var(--color-primary)' }}
                    onBlur={e => { e.currentTarget.style.borderColor = 'var(--color-border-default)' }}
                    disabled={emailSending}
                  />
                  <button
                    onClick={async () => {
                      if (!emailInput.trim() || !responseId) return
                      setEmailSending(true)
                      setEmailError('')
                      try {
                        const apiUrl = import.meta.env.VITE_API_URL || 'http://localhost:8000'
                        const res = await fetch(`${apiUrl}/api/v1/survey/email-copy`, {
                          method: 'POST',
                          headers: { 'Content-Type': 'application/json' },
                          body: JSON.stringify({ email: emailInput.trim(), response_id: responseId }),
                        })
                        if (!res.ok) {
                          const err = await res.json().catch(() => null)
                          throw new Error(err?.detail || 'Failed to send')
                        }
                        setEmailSent(true)
                      } catch (err) {
                        setEmailError(err instanceof Error ? err.message : 'Failed to send email')
                      } finally {
                        setEmailSending(false)
                      }
                    }}
                    disabled={!emailInput.trim() || emailSending}
                    className="inline-flex items-center justify-center gap-2 px-5 py-2.5 rounded-[9px] text-sm font-semibold bg-primary text-white transition-all duration-150 hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed whitespace-nowrap"
                  >
                    {emailSending ? (
                      <>
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="animate-spin"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
                        Sending...
                      </>
                    ) : 'Send'}
                  </button>
                </div>
              ) : (
                <div className="flex items-center justify-center gap-2 py-2 text-sm text-emerald-400">
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M20 6L9 17l-5-5"/></svg>
                  Email sent! Check your inbox.
                </div>
              )}
              {emailError && (
                <p className="text-xs text-rose-400 mt-2">{emailError}</p>
              )}
            </div>

            {/* Copy + Finish buttons */}
            <div className="flex gap-2.5 justify-center flex-wrap">
              <button onClick={copyAll} className="inline-flex items-center gap-2 px-4 py-2.5 sm:px-5 rounded-lg text-sm font-semibold transition-all duration-150 text-muted-foreground hover:text-foreground" style={{ background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.06)' }}>
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
                Copy to Clipboard
              </button>
              <button
                onClick={() => navigate('/survey/thank-you')}
                className="inline-flex items-center gap-2 px-5 py-2.5 sm:px-6 rounded-lg text-sm font-semibold bg-primary text-white transition-all duration-150 hover:brightness-110 active:scale-[0.98]"
              >
                Finish
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14"/><path d="M12 5l7 7-7 7"/></svg>
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  )
}

// ── Sub-components ──

function ScenarioBox({ scenario }: { scenario: { title: string; symptom: string; details: string } }) {
  return (
    <div className="rounded-lg p-3.5 px-4 sm:p-4 sm:px-5 mb-4 text-[13px]" style={{ background: 'rgba(96, 165, 250, 0.04)', border: '1px solid color-mix(in srgb, var(--color-primary) 12%, transparent)' }}>
      <div className="font-sans text-xs text-[10px] uppercase tracking-widest mb-2 font-semibold" style={{ color: 'var(--color-primary)' }}>{scenario.title}</div>
      <div className="sm:flex gap-2 mb-1">
        <span className="text-muted-foreground font-medium whitespace-nowrap">Symptom:</span>
        <span className="text-muted-foreground/80">{scenario.symptom}</span>
      </div>
      <div className="sm:flex gap-2">
        <span className="text-muted-foreground font-medium whitespace-nowrap">Details:</span>
        <span className="text-muted-foreground/80">{scenario.details}</span>
      </div>
    </div>
  )
}

function QuestionCard({ question: q, answer, setAnswer }: { question: SurveyQuestion; answer?: string | string[]; setAnswer: (id: string, val: string | string[]) => void }) {
  return (
    <div className="card-flat p-4 sm:p-7 mb-3 sm:mb-4 transition-[border-color] duration-200 focus-within:border-primary/25!">
      <div className="font-sans text-xs text-[11px] mb-1.5 font-medium" style={{ color: 'var(--color-primary)' }}>Q{q.num}</div>
      <div className="font-heading text-[14px] sm:text-[15px] font-semibold text-foreground leading-snug mb-1">{q.text}</div>
      {q.hint && <div className="text-[12px] text-muted-foreground mb-3 sm:mb-4 leading-snug">{q.hint}</div>}
      {!q.hint && <div className="mb-3 sm:mb-4" />}

      {q.type === 'mc' && q.options && (
        <div className="flex flex-col gap-2">
          {q.options.map(opt => (
            <button
              key={opt}
              onClick={() => setAnswer(q.id, opt)}
              className="flex items-start gap-3 px-3.5 py-3 sm:px-4 rounded-[9px] text-left text-[13px] sm:text-sm transition-all duration-150 select-none"
              style={{
                background: answer === opt ? 'rgba(96, 165, 250, 0.10)' : 'rgba(16, 17, 20, 0.6)',
                border: `1px solid ${answer === opt ? 'var(--color-primary)' : 'var(--color-border-default)'}`,
                color: answer === opt ? 'var(--color-foreground)' : 'var(--color-muted-foreground)',
              }}
            >
              <div className="w-[18px] h-[18px] rounded-full shrink-0 flex items-center justify-center transition-all duration-150 mt-0.5" style={{ border: `2px solid ${answer === opt ? 'var(--color-primary)' : 'var(--color-border-default)'}` }}>
                {answer === opt && <div className="w-2 h-2 rounded-full" style={{ background: 'var(--color-primary)' }} />}
              </div>
              <span className="leading-snug">{opt}</span>
            </button>
          ))}
        </div>
      )}

      {q.type === 'mc-multi' && q.options && (
        <div className="flex flex-col gap-2">
          {q.options.map(opt => {
            const selected = Array.isArray(answer) && answer.includes(opt)
            return (
              <button
                key={opt}
                onClick={() => {
                  const current = Array.isArray(answer) ? answer : []
                  setAnswer(q.id, selected ? current.filter(v => v !== opt) : [...current, opt])
                }}
                className="flex items-start gap-3 px-3.5 py-3 sm:px-4 rounded-[9px] text-left text-[13px] sm:text-sm transition-all duration-150 select-none"
                style={{
                  background: selected ? 'rgba(96, 165, 250, 0.10)' : 'rgba(16, 17, 20, 0.6)',
                  border: `1px solid ${selected ? 'var(--color-primary)' : 'var(--color-border-default)'}`,
                  color: selected ? 'var(--color-foreground)' : 'var(--color-muted-foreground)',
                }}
              >
                <div className="w-[18px] h-[18px] rounded-[5px] shrink-0 flex items-center justify-center text-[11px] transition-all duration-150 mt-0.5" style={{ border: `2px solid ${selected ? 'var(--color-primary)' : 'var(--color-border-default)'}`, background: selected ? 'var(--color-primary)' : 'transparent', color: selected ? 'white' : 'transparent' }}>
                  {'\u2713'}
                </div>
                <span className="leading-snug">{opt}</span>
              </button>
            )
          })}
        </div>
      )}

      {q.type === 'range' && (
        <RangeInput question={q} value={answer as string | undefined} onChange={(val) => setAnswer(q.id, val)} />
      )}

      {q.type === 'text' && (
        <textarea
          value={(answer as string) || ''}
          onChange={e => setAnswer(q.id, e.target.value)}
          placeholder="Type your answer here..."
          className="w-full min-h-[100px] rounded-[9px] p-3 sm:p-3.5 text-[13px] sm:text-sm text-foreground leading-relaxed resize-y transition-all duration-200 placeholder:text-text-muted focus:outline-hidden"
          style={{
            background: 'rgba(16, 17, 20, 0.6)',
            border: '1px solid var(--color-border-default)',
          }}
          onFocus={e => { e.currentTarget.style.borderColor = 'var(--color-primary)'; e.currentTarget.style.boxShadow = '0 0 0 3px rgba(96, 165, 250, 0.10)' }}
          onBlur={e => { e.currentTarget.style.borderColor = 'var(--color-border-default)'; e.currentTarget.style.boxShadow = 'none' }}
        />
      )}

      {q.type === 'rank' && q.items && (
        <DragRank items={Array.isArray(answer) ? answer as string[] : q.items} onChange={(items) => setAnswer(q.id, items)} />
      )}
    </div>
  )
}

function RangeInput({ question: q, value, onChange }: { question: SurveyQuestion; value?: string; onChange: (val: string) => void }) {
  const numVal = value ? parseInt(value) : q.min || 0
  return (
    <div className="py-2">
      <div className="text-center font-sans text-xs text-2xl font-semibold mb-3" style={{ color: 'var(--color-primary)' }}>
        {numVal}{q.suffix || ''}
      </div>
      <input
        type="range"
        min={q.min}
        max={q.max}
        step={q.step}
        value={numVal}
        onChange={e => onChange(e.target.value + (q.suffix || ''))}
        className="w-full h-2 sm:h-1 rounded-full appearance-none cursor-pointer touch-none"
        style={{
          background: `linear-gradient(to right, var(--color-primary) 0%, var(--color-primary) ${((numVal - (q.min || 0)) / ((q.max || 10) - (q.min || 0))) * 100}%, var(--color-border) ${((numVal - (q.min || 0)) / ((q.max || 10) - (q.min || 0))) * 100}%, var(--color-border) 100%)`,
        }}
      />
      <div className="flex justify-between text-[11px] text-muted-foreground mt-2.5">
        <span>{q.low_label}</span>
        <span>{q.high_label}</span>
      </div>
    </div>
  )
}

function DragRank({ items, onChange }: { items: string[]; onChange: (items: string[]) => void }) {
  const dragItem = useRef<number | null>(null)
  const dragOverItem = useRef<number | null>(null)
  const [draggingIdx, setDraggingIdx] = useState<number | null>(null)
  const [overIdx, setOverIdx] = useState<number | null>(null)

  const handleDragStart = (idx: number) => {
    dragItem.current = idx
    setDraggingIdx(idx)
  }

  const handleDragOver = (e: React.DragEvent, idx: number) => {
    e.preventDefault()
    dragOverItem.current = idx
    setOverIdx(idx)
  }

  const handleDrop = () => {
    if (dragItem.current === null || dragOverItem.current === null) return
    const newItems = [...items]
    const [removed] = newItems.splice(dragItem.current, 1)
    newItems.splice(dragOverItem.current, 0, removed)
    onChange(newItems)
    dragItem.current = null
    dragOverItem.current = null
    setDraggingIdx(null)
    setOverIdx(null)
  }

  const handleDragEnd = () => {
    setDraggingIdx(null)
    setOverIdx(null)
  }

  // Touch support
  const touchItem = useRef<number | null>(null)
  const listRef = useRef<HTMLDivElement>(null)

  const handleTouchStart = (idx: number) => {
    touchItem.current = idx
    setDraggingIdx(idx)
  }

  const handleTouchMove = (e: React.TouchEvent) => {
    if (touchItem.current === null || !listRef.current) return
    e.preventDefault()
    const touch = e.touches[0]
    const elements = listRef.current.querySelectorAll<HTMLDivElement>('[data-rank-item]')
    elements.forEach((el, i) => {
      const rect = el.getBoundingClientRect()
      if (touch.clientY >= rect.top && touch.clientY <= rect.bottom) {
        setOverIdx(i)
        dragOverItem.current = i
      }
    })
  }

  const handleTouchEnd = () => {
    if (touchItem.current !== null && dragOverItem.current !== null && touchItem.current !== dragOverItem.current) {
      const newItems = [...items]
      const [removed] = newItems.splice(touchItem.current, 1)
      newItems.splice(dragOverItem.current, 0, removed)
      onChange(newItems)
    }
    touchItem.current = null
    dragOverItem.current = null
    setDraggingIdx(null)
    setOverIdx(null)
  }

  return (
    <div ref={listRef} className="flex flex-col gap-1.5" onTouchMove={handleTouchMove} onTouchEnd={handleTouchEnd}>
      {items.map((item, idx) => (
        <div
          key={item}
          data-rank-item
          draggable
          onDragStart={() => handleDragStart(idx)}
          onDragOver={(e) => handleDragOver(e, idx)}
          onDrop={handleDrop}
          onDragEnd={handleDragEnd}
          onDragLeave={() => setOverIdx(null)}
          onTouchStart={() => handleTouchStart(idx)}
          className="flex items-center gap-2.5 sm:gap-3 px-3 py-3 sm:px-4 sm:py-2.5 rounded-[9px] text-[13px] sm:text-sm transition-all duration-150 select-none"
          style={{
            background: overIdx === idx ? 'rgba(96, 165, 250, 0.10)' : 'rgba(16, 17, 20, 0.6)',
            border: `1px solid ${overIdx === idx || draggingIdx === idx ? 'var(--color-primary)' : 'var(--color-border-default)'}`,
            opacity: draggingIdx === idx ? 0.5 : 1,
            cursor: 'grab',
            color: 'var(--color-muted-foreground)',
          }}
        >
          <div className="shrink-0 text-text-muted">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="9" cy="6" r="1"/><circle cx="15" cy="6" r="1"/><circle cx="9" cy="12" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="9" cy="18" r="1"/><circle cx="15" cy="18" r="1"/></svg>
          </div>
          <div className="font-sans text-xs text-[11px] font-semibold w-5 text-center shrink-0" style={{ color: 'var(--color-primary)' }}>{idx + 1}</div>
          <div className="flex-1 leading-snug">{item}</div>
        </div>
      ))}
    </div>
  )
}
