'use client'
import { useCallback, useEffect, useRef, useState, useTransition } from 'react'
import type { FormAnswers, Question, Survey } from '@/lib/types'
import { clearDraft, loadDraft, saveDraft } from '@/lib/storage'
import { getHiddenCodes, isQuestionVisible, ruleQuestionCodes } from '@/lib/conditional'
import { submitSurvey } from '@/app/actions/submit-survey'
import { ConsentScreen } from './consent-screen'
import { ProgressBar } from './progress-bar'
import { QuestionRenderer } from './question-renderer'

// Section metadata (code prefix → display title)
const SECTIONS: { prefix: string; title: string }[] = [
  { prefix: 'A', title: 'Datos Generales' },
  { prefix: '1', title: 'Prevalencia: cuidado y discapacidad' },
  { prefix: '2', title: 'Intensidad y rol del cuidado' },
  { prefix: '3', title: 'Impacto económico del cuidado' },
  { prefix: '4', title: 'Tiempo y descanso' },
  { prefix: '5', title: 'Impacto en el trabajo' },
  { prefix: '6', title: 'Conciencia organizacional' },
  { prefix: '7', title: 'Para cerrar' },
]

function getSectionPrefix(code: string): string {
  const m = code.match(/^([A-Za-z]+|\d+)/)
  return m ? m[1] : code
}

type FormStage = 'consent' | 'form' | 'success' | 'error'

interface SurveyFormProps {
  survey: Survey
  questions: Question[]
}

export function SurveyForm({ survey, questions }: SurveyFormProps) {
  const [stage, setStage] = useState<FormStage>('consent')
  const [consentOperativo, setConsentOperativo] = useState(false)
  const [consentMacroN1, setConsentMacroN1] = useState(false)
  const [answers, setAnswers] = useState<FormAnswers>({})
  const [errors, setErrors] = useState<Record<string, string>>({})
  const [submitError, setSubmitError] = useState<string | null>(null)
  const [isPending, startTransition] = useTransition()
  const [a11yAnnounce, setA11yAnnounce] = useState('')
  const [hydrated, setHydrated] = useState(false)
  const prevAnswers = useRef<FormAnswers>({})

  // Hydrate from localStorage on mount
  useEffect(() => {
    const draft = loadDraft(survey.id)
    if (Object.keys(draft).length > 0) setAnswers(draft)
    setHydrated(true)
  }, [survey.id])

  // Persist to localStorage after hydration
  useEffect(() => {
    if (!hydrated) return
    saveDraft(survey.id, answers)
    prevAnswers.current = answers
  }, [answers, hydrated, survey.id])

  const handleChange = useCallback(
    (code: string, value: FormAnswers[string]) => {
      setAnswers((prev) => {
        const updated = { ...prev, [code]: value }
        const toHide = getHiddenCodes(code, value, questions, prev)
        for (const hiddenCode of toHide) {
          updated[hiddenCode] = undefined as unknown as FormAnswers[string]
        }
        if (toHide.length > 0) {
          setA11yAnnounce('Se ocultaron preguntas relacionadas y se limpiaron sus respuestas.')
        } else {
          const appeared = questions.some(
            (q) =>
              q.conditional_rules?.some((r) => ruleQuestionCodes(r).includes(code)) &&
              isQuestionVisible(q, updated) &&
              !isQuestionVisible(q, prev)
          )
          if (appeared) setA11yAnnounce('Aparecieron nuevas preguntas según tu respuesta.')
        }
        return updated
      })
      setErrors((prev) => {
        if (!prev[code]) return prev
        const { [code]: _, ...rest } = prev
        return rest
      })
    },
    [questions]
  )

  function validate(): boolean {
    const newErrors: Record<string, string> = {}
    for (const q of questions) {
      if (!q.required) continue
      if (!isQuestionVisible(q, answers)) continue
      const val = answers[q.code]
      if (val === null || val === undefined || val === '' || (Array.isArray(val) && val.length === 0)) {
        newErrors[q.code] = 'Este campo es obligatorio.'
      }
    }
    setErrors(newErrors)
    return Object.keys(newErrors).length === 0
  }

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    if (isPending) return
    if (!validate()) {
      const firstErrorCode = Object.keys(errors)[0]
      if (firstErrorCode) document.getElementById(firstErrorCode)?.focus()
      return
    }

    const questionMap = Object.fromEntries(questions.map((q) => [q.code, q.id]))

    startTransition(async () => {
      const result = await submitSurvey({
        surveyId: survey.id,
        answers: answers as Record<string, unknown>,
        questionMap,
        consentOperativo,
        consentMacroN1,
      })
      if (result.success) {
        clearDraft(survey.id)
        setStage('success')
      } else {
        setSubmitError(result.error)
        setStage('error')
      }
    })
  }

  // ── Stage: consent ──────────────────────────────────────────
  if (stage === 'consent') {
    return (
      <ConsentScreen
        brandConfig={survey.brand_config}
        onAccept={(op, macro) => {
          setConsentOperativo(op)
          setConsentMacroN1(macro)
          setStage('form')
        }}
      />
    )
  }

  // ── Stage: success ──────────────────────────────────────────
  if (stage === 'success') {
    return (
      <div className="survey-wrapper">
        <div className="thank-you-container" role="main">
          <h1 className="thank-you-title">¡Gracias por participar!</h1>
          <p className="thank-you-body">
            Tu respuesta fue registrada correctamente. Recordá que la encuesta es anónima: no hay
            forma de vincular tus respuestas con tu identidad.
          </p>
          <p className="thank-you-body">
            Los resultados agregados ayudarán a {survey.brand_config?.org_name ?? 'tu empresa'} a
            diseñar mejores apoyos para las personas cuidadoras.
          </p>
        </div>
      </div>
    )
  }

  // ── Stage: error ────────────────────────────────────────────
  if (stage === 'error') {
    return (
      <div className="survey-wrapper">
        <div className="error-container" role="main">
          <h1 className="error-title">No se pudo enviar la encuesta</h1>
          <p>Hubo un error al guardar tus respuestas ({submitError}). Podés intentarlo de nuevo.</p>
          <button
            type="button"
            className="btn btn-primary"
            onClick={() => { setSubmitError(null); setStage('form') }}
          >
            Volver e intentar de nuevo
          </button>
        </div>
      </div>
    )
  }

  // ── Stage: form ─────────────────────────────────────────────
  const visibleQuestions = questions.filter((q) => isQuestionVisible(q, answers))
  const answeredCount = visibleQuestions.filter((q) => {
    const v = answers[q.code]
    return v !== null && v !== undefined && v !== '' && !(Array.isArray(v) && v.length === 0)
  }).length

  type Section = { prefix: string; title: string; questions: Question[] }
  const sectionMap = new Map<string, Section>()
  for (const q of visibleQuestions) {
    const prefix = getSectionPrefix(q.code)
    if (!sectionMap.has(prefix)) {
      const meta = SECTIONS.find((s) => s.prefix === prefix)
      sectionMap.set(prefix, { prefix, title: meta?.title ?? prefix, questions: [] })
    }
    sectionMap.get(prefix)!.questions.push(q)
  }

  const bc = survey.brand_config

  return (
    <div className="survey-wrapper">
      <a href="#survey-form" className="skip-link">Ir al formulario</a>

      <div aria-live="polite" aria-atomic="true" className="sr-only" role="status">
        {a11yAnnounce}
      </div>

      {/* Header contextual con org/branch si está configurado */}
      {bc?.org_name && (
        <div className="brand-header" role="note" aria-label="Información de la empresa">
          <p className="brand-text">
            Estás respondiendo esto porque pertenecés a <strong>{bc.org_name}</strong>
            {bc.branch_name && (
              <> y participás en las oficinas de <strong>{bc.branch_name}</strong>
              {bc.branch_city && <> en <strong>{bc.branch_city}</strong></>}.</>
            )}
          </p>
        </div>
      )}

      <header className="survey-header">
        <h1 className="survey-title">{survey.title}</h1>
        <p className="survey-anon-note">Esta encuesta es anónima. Tus respuestas no te identifican.</p>
      </header>

      <div className="survey-progress-sticky" aria-label="Barra de progreso">
        <ProgressBar answered={answeredCount} total={visibleQuestions.length} />
      </div>

      <main id="survey-form">
        <form onSubmit={handleSubmit} noValidate aria-label={`Encuesta: ${survey.title}`}>
          {Array.from(sectionMap.values()).map((section) => (
            <section
              key={section.prefix}
              className="survey-section"
              aria-labelledby={`section-${section.prefix}`}
            >
              <div className="section-header">
                <h2 id={`section-${section.prefix}`} className="section-title">Sección {section.prefix} · {section.title}</h2>
              </div>
              {section.questions.map((q) => (
                <div key={q.id} className="question-wrapper" data-code={q.code}>
                  <QuestionRenderer
                    question={q}
                    answers={answers}
                    onChange={handleChange}
                    errors={errors}
                  />
                </div>
              ))}
            </section>
          ))}

          <div className="form-footer">
            <button
              type="submit"
              className="btn btn-primary"
              disabled={isPending}
              aria-disabled={isPending}
            >
              {isPending ? 'Enviando…' : 'Enviar encuesta'}
            </button>
          </div>
        </form>
      </main>
    </div>
  )
}
