'use client'

import React, { useState, useEffect, useRef } from 'react'
import {
  X, Loader2, CheckCircle2, AlertTriangle,
  Download, Sparkles, FileText, RefreshCw
} from 'lucide-react'
import {
  Document, Packer, Paragraph, TextRun, HeadingLevel,
  AlignmentType, BorderStyle, ShadingType
} from 'docx'

// ── Types ─────────────────────────────────────────────────────────────────────

export interface BatchItem {
  id: string
  title: string         // titre de l'article source
  keyword: string       // titres[0] du brief ou title
  url?: string          // URL de l'article d'origine
  source_name?: string  // nom de la source / publication
  brief_data: {
    angle?: string
    importance?: string
    fenetre?: string
    mots_cles?: string[]
    titres?: string[]
    format?: string
  } | null
}

interface GuideResult extends BatchItem {
  step: 'pending' | 'briefing' | 'guiding' | 'done' | 'error'
  brief_data_resolved?: BatchItem['brief_data']
  guide_plan?: string
  errorMsg?: string
}

interface Props {
  items: BatchItem[]
  clientId: string | null
  onClose: () => void
}

// ── Markdown → HTML (léger, pour l'export) ────────────────────────────────────

function mdToHtml(md: string): string {
  if (!md) return ''
  const lines = md.split('\n')
  const out: string[] = []
  let ulBuf: string[] = []
  let olBuf: string[] = []

  const flushUl = () => {
    if (ulBuf.length) { out.push(`<ul>${ulBuf.map(i => `<li>${i}</li>`).join('')}</ul>`); ulBuf = [] }
  }
  const flushOl = () => {
    if (olBuf.length) { out.push(`<ol>${olBuf.map(i => `<li>${i}</li>`).join('')}</ol>`); olBuf = [] }
  }
  const inline = (t: string) =>
    t.replace(/\*\*\*([^*]+)\*\*\*/g, '<strong><em>$1</em></strong>')
     .replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
     .replace(/\*([^*]+)\*/g, '<em>$1</em>')
     .replace(/__([^_]+)__/g, '<strong>$1</strong>')
     .replace(/_([^_]+)_/g, '<em>$1</em>')

  for (const raw of lines) {
    const line = raw.trim()
    if (/^#{1,6}\s/.test(line)) {
      flushUl(); flushOl()
      const lvl = Math.min(Math.max(line.match(/^(#{1,6})\s/)![1].length, 2), 4)
      out.push(`<h${lvl}>${inline(line.replace(/^#{1,6}\s+/, ''))}</h${lvl}>`)
    } else if (/^[-*+]\s+/.test(line)) {
      flushOl(); ulBuf.push(inline(line.replace(/^[-*+]\s+/, '')))
    } else if (/^\d+\.\s+/.test(line)) {
      flushUl(); olBuf.push(inline(line.replace(/^\d+\.\s+/, '')))
    } else if (line === '') {
      flushUl(); flushOl(); out.push('<p><br></p>')
    } else {
      flushUl(); flushOl(); out.push(`<p>${inline(line)}</p>`)
    }
  }
  flushUl(); flushOl()
  return out.join('\n').replace(/(<p><br><\/p>\s*){2,}/g, '<p><br></p>')
}

// ── Parseur markdown → paragraphes docx ──────────────────────────────────────

function mdToDocxParagraphs(md: string): Paragraph[] {
  if (!md) return []
  const paragraphs: Paragraph[] = []

  // Parse les runs inline (gras, italique)
  function parseRuns(text: string): TextRun[] {
    const runs: TextRun[] = []
    // Regex pour **gras**, *italique*, ***gras+italique***
    const regex = /\*\*\*([^*]+)\*\*\*|\*\*([^*]+)\*\*|\*([^*]+)\*/g
    let last = 0, match: RegExpExecArray | null
    while ((match = regex.exec(text)) !== null) {
      if (match.index > last) runs.push(new TextRun({ text: text.slice(last, match.index) }))
      if (match[1]) runs.push(new TextRun({ text: match[1], bold: true, italics: true }))
      else if (match[2]) runs.push(new TextRun({ text: match[2], bold: true }))
      else if (match[3]) runs.push(new TextRun({ text: match[3], italics: true }))
      last = match.index + match[0].length
    }
    if (last < text.length) runs.push(new TextRun({ text: text.slice(last) }))
    return runs.length > 0 ? runs : [new TextRun({ text })]
  }

  const lines = md.split('\n')
  for (const raw of lines) {
    const line = raw.trim()
    if (!line) {
      paragraphs.push(new Paragraph({ text: '' }))
      continue
    }
    // Titres
    const hMatch = line.match(/^(#{1,4})\s+(.+)$/)
    if (hMatch) {
      const lvl = hMatch[1].length
      const headingMap: Record<number, HeadingLevel> = {
        1: HeadingLevel.HEADING_1,
        2: HeadingLevel.HEADING_2,
        3: HeadingLevel.HEADING_3,
        4: HeadingLevel.HEADING_4,
      }
      paragraphs.push(new Paragraph({
        text: hMatch[2],
        heading: headingMap[Math.min(lvl, 4)],
      }))
      continue
    }
    // Liste non ordonnée
    if (/^[-*+]\s+/.test(line)) {
      paragraphs.push(new Paragraph({
        children: parseRuns(line.replace(/^[-*+]\s+/, '')),
        bullet: { level: 0 },
      }))
      continue
    }
    // Liste ordonnée
    if (/^\d+\.\s+/.test(line)) {
      paragraphs.push(new Paragraph({
        children: parseRuns(line.replace(/^\d+\.\s+/, '')),
        numbering: { reference: 'default-numbering', level: 0 },
      }))
      continue
    }
    // Paragraphe normal
    paragraphs.push(new Paragraph({ children: parseRuns(line) }))
  }
  return paragraphs
}

// ── Génération du fichier .docx ───────────────────────────────────────────────

// ── Helpers titres sans style Word natif (évite l'auto-capitalisation Title Case) ──
function h1Manual(text: string): Paragraph {
  return new Paragraph({
    children: [new TextRun({ text, bold: true, size: 36, color: '2E74B5' })],
    spacing: { before: 360, after: 160 },
  })
}
function h2Manual(text: string): Paragraph {
  return new Paragraph({
    children: [new TextRun({ text, bold: true, size: 26, color: '2E74B5' })],
    spacing: { before: 280, after: 100 },
  })
}

async function buildDocx(results: GuideResult[]): Promise<Blob> {
  const date = new Date().toLocaleDateString('fr-FR', { day: 'numeric', month: 'long', year: 'numeric' })
  const children: Paragraph[] = []
  const doneResults = results.filter(r => r.guide_plan)

  // ── Page de titre ──────────────────────────────────────────────
  children.push(
    new Paragraph({ text: 'Système Argos', heading: HeadingLevel.TITLE }),
    h1Manual('Guides de rédaction'),
    new Paragraph({ text: `Généré le ${date} · ${doneResults.length} guide(s)`, style: 'aside' }),
    new Paragraph({ text: '' }),
  )

  for (const r of doneResults) {
    const bData = r.brief_data_resolved || r.brief_data

    // ── 1. Titre d'origine ─────────────────────────────────────
    children.push(
      new Paragraph({ text: '' }),
      h1Manual(r.title),
    )

    // ── 2. Source ──────────────────────────────────────────────
    if (r.source_name || r.url) {
      const sourceRuns: TextRun[] = [new TextRun({ text: 'Source : ', bold: true })]
      if (r.source_name) sourceRuns.push(new TextRun({ text: r.source_name }))
      if (r.source_name && r.url) sourceRuns.push(new TextRun({ text: ' — ' }))
      if (r.url) sourceRuns.push(new TextRun({ text: r.url, style: 'Hyperlink' }))
      children.push(new Paragraph({ children: sourceRuns }))
    }

    children.push(new Paragraph({ text: '' }))

    // ── 3. Suggestions de titres alternatifs ───────────────────
    if (Array.isArray(bData?.titres) && bData.titres.length > 0) {
      children.push(h2Manual('Titres alternatifs suggérés'))
      bData.titres.forEach((titre, i) => {
        children.push(new Paragraph({
          children: [
            new TextRun({ text: `#${i + 1}  `, bold: true, color: '7C3AED' }),
            new TextRun({ text: titre, bold: true }),
          ],
          indent: { left: 360 },
        }))
      })
      children.push(new Paragraph({ text: '' }))
    }

    // ── 4. Brief stratégique ───────────────────────────────────
    if (bData && (bData.angle || bData.importance || bData.fenetre || bData.mots_cles?.length || bData.format)) {
      children.push(h2Manual('Brief stratégique'))

      const briefFields: Array<[string, string | undefined]> = [
        ['Angle',    bData.angle],
        ['Enjeu',    bData.importance],
        ['Fenêtre',  bData.fenetre],
        ['Format',   bData.format],
      ]
      for (const [label, value] of briefFields) {
        if (!value) continue
        children.push(new Paragraph({
          children: [
            new TextRun({ text: `${label} : `, bold: true }),
            new TextRun({ text: value }),
          ]
        }))
      }
      if (Array.isArray(bData.mots_cles) && bData.mots_cles.length) {
        children.push(new Paragraph({
          children: [
            new TextRun({ text: 'Mots-clés : ', bold: true }),
            new TextRun({ text: bData.mots_cles.join(', '), italics: true }),
          ]
        }))
      }
      children.push(new Paragraph({ text: '' }))
    }

    // ── 5. Plan de Rédaction ───────────────────────────────────
    children.push(h2Manual('Plan de rédaction'))
    children.push(...mdToDocxParagraphs(r.guide_plan!))
    children.push(new Paragraph({ text: '' }))
  }

  const doc = new Document({
    numbering: {
      config: [{
        reference: 'default-numbering',
        levels: [{ level: 0, format: 'decimal', text: '%1.', alignment: AlignmentType.LEFT }],
      }],
    },
    sections: [{ properties: {}, children }],
  })

  return await Packer.toBlob(doc)
}

// ── Composant principal ───────────────────────────────────────────────────────

export default function BatchGuideModal({ items, clientId, onClose }: Props) {
  const [results, setResults] = useState<GuideResult[]>(
    items.map(item => ({ ...item, step: 'pending' }))
  )
  const [isRunning, setIsRunning] = useState(false)
  const [isDone, setIsDone] = useState(false)
  const hasStarted = useRef(false)

  const doneCount  = results.filter(r => r.step === 'done').length
  const errorCount = results.filter(r => r.step === 'error').length
  const totalCount = results.length

  // ── Lance la génération au montage ─────────────────────────────
  useEffect(() => {
    if (hasStarted.current) return
    hasStarted.current = true
    runBatch()
  }, [])

  const updateResult = (id: string, patch: Partial<GuideResult>) =>
    setResults(prev => prev.map(r => r.id === id ? { ...r, ...patch } : r))

  async function runBatch() {
    setIsRunning(true)
    const successTitles: string[] = []

    for (const item of items) {
      // ── Étape 1 : générer le brief si absent ─────────────────
      let briefData = item.brief_data
      if (!briefData) {
        updateResult(item.id, { step: 'briefing' })
        try {
          const res = await fetch('/api/brief-discover', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              title: item.title,
              card_type: 'article',
            }),
          })
          const data = await res.json()
          if (res.ok && data.brief) briefData = data.brief
        } catch (_) { /* on continue sans brief */ }
      }

      // ── Étape 2 : générer le guide ────────────────────────────
      updateResult(item.id, { step: 'guiding', brief_data_resolved: briefData })
      try {
        const res = await fetch('/api/content/guide-from-brief', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            keyword: item.keyword,
            brief_data: briefData,
            client_id: clientId,
          }),
        })
        const data = await res.json()
        if (!res.ok) throw new Error(data.error || 'Erreur API')
        updateResult(item.id, { step: 'done', guide_plan: data.guide_plan, brief_data_resolved: briefData ?? undefined })
        successTitles.push(item.title)
      } catch (err: any) {
        updateResult(item.id, { step: 'error', errorMsg: err.message })
      }
    }

    setIsRunning(false)
    setIsDone(true)

    // ── Enregistrement en base (non-bloquant) ─────────────────────
    if (successTitles.length > 0) {
      fetch('/api/batch-guides', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          client_id: clientId || null,
          article_count: successTitles.length,
          article_titles: successTitles,
        }),
      }).catch(err => console.warn('[batch-guides save]', err))
    }
  }

  async function handleDownload() {
    try {
      const blob = await buildDocx(results)
      const url  = URL.createObjectURL(blob)
      const a    = document.createElement('a')
      a.href     = url
      a.download = `guides-redaction-argos-${new Date().toISOString().slice(0, 10)}.docx`
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      URL.revokeObjectURL(url)
    } catch (err) {
      console.error('[docx export]', err)
      alert('Erreur lors de la génération du fichier.')
    }
  }

  // ── Rendu ─────────────────────────────────────────────────────
  const progressPct = totalCount > 0 ? Math.round((doneCount + errorCount) / totalCount * 100) : 0

  return (
    <>
      {/* Overlay */}
      <div className="fixed inset-0 bg-black/70 backdrop-blur-sm z-[200]" onClick={isDone ? onClose : undefined} />

      {/* Modal */}
      <div className="fixed inset-0 z-[201] flex items-center justify-center p-4">
        <div className="w-full max-w-xl bg-[#0e0e16] border border-white/10 rounded-3xl shadow-2xl overflow-hidden">

          {/* Header */}
          <div className="px-6 py-5 border-b border-white/5 flex items-center justify-between bg-gradient-to-r from-indigo-500/10 to-purple-500/10">
            <div className="flex items-center gap-3">
              <div className="w-9 h-9 rounded-xl bg-indigo-500/20 flex items-center justify-center">
                <Sparkles size={16} className="text-indigo-400" />
              </div>
              <div>
                <h2 className="text-sm font-black text-white tracking-tight">Génération en batch</h2>
                <p className="text-[10px] text-white/40 uppercase tracking-widest font-bold">
                  {isRunning ? 'En cours…' : isDone ? 'Terminé' : 'Prêt'}
                </p>
              </div>
            </div>
            {isDone && (
              <button onClick={onClose} className="p-2 rounded-xl hover:bg-white/10 text-white/40 hover:text-white transition-all">
                <X size={16} />
              </button>
            )}
          </div>

          {/* Barre de progression globale */}
          <div className="px-6 pt-5 pb-2">
            <div className="flex items-center justify-between mb-2">
              <span className="text-xs text-white/60">
                {doneCount + errorCount} / {totalCount} traités
              </span>
              <span className="text-xs font-black text-indigo-400">{progressPct}%</span>
            </div>
            <div className="w-full h-1.5 bg-white/5 rounded-full overflow-hidden">
              <div
                className="h-full bg-gradient-to-r from-indigo-500 to-purple-500 rounded-full transition-all duration-500"
                style={{ width: `${progressPct}%` }}
              />
            </div>
          </div>

          {/* Liste des items */}
          <div className="px-6 py-4 space-y-2 max-h-72 overflow-y-auto">
            {results.map(r => (
              <div
                key={r.id}
                className={`flex items-center gap-3 p-3 rounded-xl border transition-all ${
                  r.step === 'done'     ? 'bg-emerald-500/5 border-emerald-500/20' :
                  r.step === 'error'    ? 'bg-red-500/5 border-red-500/20' :
                  r.step === 'guiding' || r.step === 'briefing' ? 'bg-indigo-500/10 border-indigo-500/30' :
                  'bg-white/2 border-white/5'
                }`}
              >
                {/* Icône statut */}
                <div className="shrink-0">
                  {r.step === 'done'     && <CheckCircle2 size={16} className="text-emerald-400" />}
                  {r.step === 'error'    && <AlertTriangle size={16} className="text-red-400" />}
                  {(r.step === 'guiding' || r.step === 'briefing') && (
                    <Loader2 size={16} className="text-indigo-400 animate-spin" />
                  )}
                  {r.step === 'pending'  && <div className="w-4 h-4 rounded-full border-2 border-white/10" />}
                </div>

                {/* Titre + statut */}
                <div className="flex-1 min-w-0">
                  <p className="text-xs font-bold text-white truncate">{r.title}</p>
                  <p className={`text-[10px] mt-0.5 ${
                    r.step === 'done'    ? 'text-emerald-400' :
                    r.step === 'error'   ? 'text-red-400' :
                    r.step === 'guiding' ? 'text-indigo-400' :
                    r.step === 'briefing'? 'text-amber-400' :
                    'text-white/30'
                  }`}>
                    {r.step === 'pending'   && 'En attente…'}
                    {r.step === 'briefing'  && 'Génération du brief…'}
                    {r.step === 'guiding'   && 'Génération du guide…'}
                    {r.step === 'done'      && 'Guide prêt ✓'}
                    {r.step === 'error'     && (r.errorMsg || 'Erreur')}
                  </p>
                </div>
              </div>
            ))}
          </div>

          {/* Footer */}
          <div className="px-6 py-5 border-t border-white/5 bg-white/2">
            {isDone ? (
              <div className="space-y-3">
                {/* Résumé */}
                <div className="flex items-center gap-4 text-[11px]">
                  <span className="flex items-center gap-1.5 text-emerald-400 font-bold">
                    <CheckCircle2 size={12} /> {doneCount} guide{doneCount > 1 ? 's' : ''} générés
                  </span>
                  {errorCount > 0 && (
                    <span className="flex items-center gap-1.5 text-red-400 font-bold">
                      <AlertTriangle size={12} /> {errorCount} erreur{errorCount > 1 ? 's' : ''}
                    </span>
                  )}
                </div>

                {/* Bouton téléchargement */}
                {doneCount > 0 && (
                  <>
                    <button
                      onClick={handleDownload}
                      className="w-full flex items-center justify-center gap-2 py-3 bg-gradient-to-r from-indigo-500 to-purple-600 text-white rounded-xl text-xs font-black uppercase tracking-widest hover:opacity-90 transition-all shadow-lg shadow-indigo-500/20"
                    >
                      <Download size={14} />
                      Télécharger les guides (.docx)
                    </button>
                    <p className="text-[10px] text-white/30 text-center leading-relaxed">
                      Glissez le fichier dans <strong className="text-white/50">Google Drive</strong> → clic droit → <em>Ouvrir avec Google Docs</em>
                    </p>
                  </>
                )}
              </div>
            ) : (
              <div className="flex items-center gap-2 text-[11px] text-white/40">
                <Loader2 size={12} className="animate-spin text-indigo-400" />
                <span>Génération en cours, ne fermez pas cette fenêtre…</span>
              </div>
            )}
          </div>

        </div>
      </div>
    </>
  )
}
