'use client'

import { useEffect, useState } from 'react'
import { Clapperboard, Loader2, Globe } from 'lucide-react'
import { toast } from 'sonner'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { PageView } from '@/components/interactive-page/page-view'
import {
  generateInteractivePage,
  generateInteractivePagePlan,
  generateInteractivePageSection,
  type PagePlan,
} from '@/lib/ai/services/interactive-page-client.service'
import {
  validateInteractivePage,
  type PageSection,
  type PageSpecV1,
} from '@/lib/interactive-page'
import { useLanguage } from '@/lib/i18n'

type Phase = 'idle' | 'generating' | 'preview' | 'publishing' | 'error'

function slugId(title: string): string {
  const s = title
    .toLowerCase()
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-|-$/g, '')
    .slice(0, 40)
  return s ? `page.${s}` : 'page.generated'
}

/** Degraded section when its LLM call failed — page still completes. */
function fallbackSection(
  sectionId: string,
  plan: PagePlan['sections'][number],
  lang: string
): PageSection {
  const fr = lang.startsWith('fr')
  return {
    id: sectionId,
    title: plan.title,
    blocks: [
      { type: 'prose', md: plan.goal },
      {
        type: 'callout',
        kind: 'note',
        title: fr ? 'En bref' : 'In short',
        md: plan.demoGoal || plan.goal,
      },
    ],
  }
}

function assemblePage(
  plan: PagePlan,
  sections: PageSection[],
  lang: string
): PageSpecV1 {
  return {
    schemaVersion: 1,
    id: slugId(plan.heroTitle),
    lang,
    hero: {
      kicker: lang.startsWith('fr')
        ? 'EXPLAINER INTERACTIF'
        : 'INTERACTIVE EXPLAINER',
      title: plan.heroTitle,
      subtitle: plan.heroSubtitle,
      meta: lang.startsWith('fr')
        ? 'Généré depuis votre note'
        : 'Generated from your note',
    },
    overview: {
      lead: plan.overviewLead,
      cards: plan.overviewCards.map((c) => ({
        badge: c.badge,
        title: c.title,
        body: c.body,
         
        intent: c.intent as any,
      })),
    },
    sections,
  }
}

/**
 * Author flow (§8.7): LLM plan → one LLM call per section (progress shown)
 * → validate → preview → publish (pageSpec snapshot, no double quota).
 * Falls back to the deterministic page when the LLM path is unavailable.
 */
export function InteractivePagePublishDialog({
  open,
  onOpenChange,
  noteId,
  content,
  language,
  onPublished,
}: {
  open: boolean
  onOpenChange: (open: boolean) => void
  noteId: string
  content: string
  language: string
  onPublished: (slug: string) => void
}) {
  const { t } = useLanguage()
  const [phase, setPhase] = useState<Phase>('idle')
  const [page, setPage] = useState<PageSpecV1 | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [progress, setProgress] = useState<string | null>(null)
  const [elapsedSec, setElapsedSec] = useState(0)

  useEffect(() => {
    if (!open || phase !== 'generating') {
      if (!open) setElapsedSec(0)
      return
    }
    const t0 = Date.now()
    const id = window.setInterval(() => {
      setElapsedSec(Math.floor((Date.now() - t0) / 1000))
    }, 500)
    return () => window.clearInterval(id)
  }, [open, phase])

  useEffect(() => {
    if (!open) {
      setPhase('idle')
      setPage(null)
      setError(null)
      setProgress(null)
      return
    }
    // Guard: empty content from editor race
    const wordCount = content
      .replace(/<[^>]+>/g, ' ')
      .split(/\s+/)
      .filter(Boolean).length
    if (wordCount < 30) {
      setPhase('error')
      setError(
        t('richTextEditor.publishInteractivePageTooShort') ||
          'Note trop courte — ajoutez du contenu puis réessayez'
      )
      return
    }

    let cancelled = false
    const run = async () => {
      setPhase('generating')
      setError(null)
      setPage(null)

      const legacyFallback = async (notice?: string) => {
        const result = await generateInteractivePage({
          content,
          lang: language,
          noteId,
        })
        if (cancelled) return
        if (!result.ok) {
          setPhase('error')
          setError(
            result.reason ||
              result.error ||
              t('richTextEditor.publishInteractivePageFailed') ||
              'Échec de la page interactive'
          )
          if (result.quotaExceeded) {
            toast.error(t('ai.quotaExceeded'))
          }
          window.dispatchEvent(new Event('ai-usage-changed'))
          return
        }
        window.dispatchEvent(new Event('ai-usage-changed'))
        if (notice) toast.info(notice)
        setPage(result.page)
        setPhase('preview')
      }

      // 1. LLM plan (billed)
      setProgress(
        t('richTextEditor.publishInteractivePagePlanning') ||
          'Analyse du contenu — plan de la page…'
      )
      const planResult = await generateInteractivePagePlan({
        content,
        lang: language,
        noteId,
      })
      if (cancelled) return
      if (!planResult.ok) {
        if (planResult.quotaExceeded) {
          setPhase('error')
          setError(planResult.error)
          toast.error(t('ai.quotaExceeded'))
          window.dispatchEvent(new Event('ai-usage-changed'))
          return
        }
        if (planResult.error === 'unsuitable_content') {
          setPhase('error')
          setError(
            planResult.reason ||
              t('richTextEditor.publishInteractivePageFailed') ||
              'Contenu inadapté'
          )
          window.dispatchEvent(new Event('ai-usage-changed'))
          return
        }
        // LLM plan unavailable → deterministic full page
        await legacyFallback(
          t('richTextEditor.publishInteractivePageFallback') ||
            'Génération IA indisponible — page simplifiée affichée'
        )
        return
      }
      window.dispatchEvent(new Event('ai-usage-changed'))

      // 2. One LLM call per section, with real progress
      const plan = planResult.plan
      const sections: PageSection[] = []
      let degraded = 0
      for (let i = 0; i < plan.sections.length; i++) {
        const planSection = plan.sections[i]
        const sectionId = `s${i + 1}`
        setProgress(
          (
            t('richTextEditor.publishInteractivePageSectionProgress') ||
            'Section {current}/{total} : {title}'
          )
            .replace('{current}', String(i + 1))
            .replace('{total}', String(plan.sections.length))
            .replace('{title}', planSection.title)
        )
        const sectionResult = await generateInteractivePageSection({
          content,
          lang: language,
          noteId,
          pageTitle: plan.heroTitle,
          sectionId,
          section: planSection,
        })
        if (cancelled) return
        if (sectionResult.ok) {
          sections.push(sectionResult.section)
        } else {
          degraded += 1
          sections.push(fallbackSection(sectionId, planSection, language))
        }
      }

      // 3. Assemble + hard validation client-side
      const candidate = assemblePage(plan, sections, language)
      const validated = validateInteractivePage(candidate)
      if (!validated.ok) {
        await legacyFallback(
          t('richTextEditor.publishInteractivePageFallback') ||
            'Génération IA indisponible — page simplifiée affichée'
        )
        return
      }
      if (degraded > 0) {
        toast.info(
          t('richTextEditor.publishInteractivePagePartialFallback') ||
            'Certaines sections ont été générées en mode simplifié'
        )
      }
      setPage(validated.page)
      setPhase('preview')
    }
    void run()
    return () => {
      cancelled = true
    }
    // Intentionally omit `t` — unstable identity cancels in-flight generation
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open, content, language, noteId])

  const handlePublish = async () => {
    if (!page || phase === 'publishing') return
    setPhase('publishing')
    try {
      const res = await fetch('/api/notes/publish', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          noteId,
          action: 'publish',
          mode: 'interactive-page',
          template: 'interactive-page',
          language,
          pageSpec: page,
        }),
      })
      const data = await res.json()
      if (!res.ok) {
        toast.error(
          data.reason ||
            data.error ||
            t('richTextEditor.publishInteractivePageFailed') ||
            'Échec de la publication'
        )
        setPhase('preview')
        return
      }
      toast.success(
        t('richTextEditor.publishInteractivePageSuccess') ||
          'Page interactive publiée !'
      )
      onPublished(data.slug)
      onOpenChange(false)
    } catch {
      toast.error(
        t('richTextEditor.publishInteractivePageFailed') ||
          'Échec de la publication'
      )
      setPhase('preview')
    }
  }

  const generatingHint =
    progress ||
    (elapsedSec < 15
      ? t('richTextEditor.publishInteractivePageGenerating') ||
        'Génération de la page…'
      : elapsedSec < 40
        ? t('richTextEditor.publishInteractivePageGeneratingWait') ||
          'Construction des sections et démos…'
        : t('richTextEditor.publishInteractivePageGeneratingLong') ||
          'Encore un instant — au-delà de ~90 s, annulez et réessayez')

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="flex max-h-[92vh] w-[min(1100px,96vw)] max-w-none flex-col gap-0 overflow-hidden p-0 sm:max-w-none">
        <DialogHeader className="shrink-0 border-b border-border px-5 py-4">
          <DialogTitle className="flex items-center gap-2 text-base">
            <Clapperboard className="h-4 w-4 text-brand-accent" />
            {t('richTextEditor.publishInteractivePage') ||
              'Page interactive'}
          </DialogTitle>
          <DialogDescription className="text-xs">
            {phase === 'generating'
              ? generatingHint
              : t('richTextEditor.publishInteractivePagePreviewHint') ||
                'Aperçu — vérifiez puis publiez sur l’URL publique'}
          </DialogDescription>
        </DialogHeader>

        <div className="min-h-0 flex-1 overflow-y-auto bg-background">
          {phase === 'generating' ? (
            <div className="flex flex-col items-center justify-center gap-3 py-24 text-sm text-muted-foreground">
              <Loader2 className="h-6 w-6 animate-spin text-brand-accent" />
              <p>{generatingHint}</p>
              <p className="font-mono text-xs tabular-nums text-muted-foreground/80">
                {elapsedSec}s
              </p>
            </div>
          ) : null}

          {phase === 'error' ? (
            <div className="mx-auto max-w-lg px-6 py-16 text-sm text-destructive">
              <p className="font-medium">
                {t('richTextEditor.publishInteractivePageFailed') ||
                  'Échec de la page interactive'}
              </p>
              <p className="mt-2 text-muted-foreground">{error}</p>
            </div>
          ) : null}

          {phase === 'preview' || phase === 'publishing' ? (
            page ? <PageView page={page} demoMode="interactive" /> : null
          ) : null}
        </div>

        <DialogFooter className="shrink-0 border-t border-border px-5 py-3 sm:justify-between">
          <Button
            type="button"
            variant="ghost"
            onClick={() => onOpenChange(false)}
            disabled={phase === 'publishing'}
          >
            {t('general.cancel') || 'Annuler'}
          </Button>
          <Button
            type="button"
            onClick={handlePublish}
            disabled={phase !== 'preview' || !page}
            className="gap-2"
          >
            {phase === 'publishing' ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <Globe className="h-4 w-4" />
            )}
            {t('richTextEditor.publishInteractivePageConfirm') ||
              'Publier la page'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
