'use client'

/**
 * Bulk-Generate-Modal: ruft den Compliance-Recommend-Endpoint mit dem aktuellen
 * Profil/Scope-Stand, matched die empfohlenen Dokumenttypen gegen die geladenen
 * Templates, und rendert + speichert alle markierten Dokumente in einem Rutsch
 * (als compliance_legal_documents + version v1.0 draft).
 *
 * Verwendet die existierende Render-Pipeline aus GeneratorSection.tsx:
 *   runRuleset -> applyBlockRemoval -> applyConditionalBlocks -> placeholder-Replace
 */

import { useEffect, useMemo, useState } from 'react'
import {
  applyBlockRemoval,
  applyConditionalBlocks,
  buildBoolContext,
  getDocType,
  runRuleset,
} from '../ruleEngine'
import { contextToPlaceholders, type TemplateContext } from '../contextBridge'
import type { LegalTemplateResult } from '@/lib/sdk/types'
import type { CompanyProfile } from '@/lib/sdk/types/company-profile'
import type { ComplianceScopeState } from '@/lib/sdk/compliance-scope-types/state'

const RECOMMEND_ENDPOINT = '/api/sdk/v1/compliance/recommend'
const DOC_ENDPOINT       = '/api/sdk/v1/compliance/legal-documents/documents'
const VERSION_ENDPOINT   = '/api/sdk/v1/compliance/legal-documents/versions'

interface RecommendedItem {
  document_type: string
  title: string
  rule_id: string
  rule_key: string
  classification: 'required' | 'recommended' | 'optional'
  base_classification: 'required' | 'recommended' | 'optional'
  source_citation: string
  reason: string
  override_applied: boolean
}

interface RecommendationResult {
  required: RecommendedItem[]
  recommended: RecommendedItem[]
  optional: RecommendedItem[]
}

interface Row {
  item: RecommendedItem
  template: LegalTemplateResult | undefined
  selected: boolean
  state: 'idle' | 'generating' | 'done' | 'skipped' | 'error'
  errorMessage?: string
}

interface Props {
  allTemplates: LegalTemplateResult[]
  context: TemplateContext
  extraPlaceholders: Record<string, string>
  enabledModules: string[]
  companyProfile: CompanyProfile | null
  complianceScope: ComplianceScopeState | null
  onClose: () => void
}

export default function BulkGenerateModal({
  allTemplates, context, extraPlaceholders, enabledModules,
  companyProfile, complianceScope, onClose,
}: Props) {
  const [loading, setLoading] = useState(true)
  const [loadError, setLoadError] = useState<string | null>(null)
  const [rows, setRows] = useState<Row[]>([])
  const [running, setRunning] = useState(false)
  const [summary, setSummary] = useState<{ done: number; skipped: number; failed: number } | null>(null)

  const recommendProfile = useMemo(
    () => buildRecommendProfile(companyProfile, complianceScope),
    [companyProfile, complianceScope],
  )

  // Templates nach document_type indizieren — ein Document_type hat oft nur EIN Template
  const templatesByType = useMemo(() => {
    const map = new Map<string, LegalTemplateResult>()
    for (const t of allTemplates) {
      if (t.templateType && !map.has(t.templateType)) {
        map.set(t.templateType, t)
      }
    }
    return map
  }, [allTemplates])

  // Recommend abrufen sobald das Modal geöffnet ist
  useEffect(() => {
    let cancelled = false
    async function load() {
      setLoading(true)
      setLoadError(null)
      try {
        const res = await fetch(RECOMMEND_ENDPOINT, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            profile: recommendProfile,
            compliance_depth_level: recommendProfile.compliance_depth_level ?? 'L2',
          }),
        })
        if (!res.ok) throw new Error(`Recommend-API: ${res.status}`)
        const data = (await res.json()) as RecommendationResult
        if (cancelled) return
        const all: RecommendedItem[] = [...data.required, ...data.recommended, ...data.optional]
        const newRows: Row[] = all.map((item) => ({
          item,
          template: templatesByType.get(item.document_type),
          // Default: required + recommended sind aktiv, optional inaktiv,
          // und ohne Template generell deaktiviert
          selected: item.classification !== 'optional' && templatesByType.has(item.document_type),
          state: 'idle',
        }))
        setRows(newRows)
      } catch (e) {
        if (!cancelled) setLoadError((e as Error).message)
      } finally {
        if (!cancelled) setLoading(false)
      }
    }
    load()
    return () => { cancelled = true }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  const selectedCount = rows.filter((r) => r.selected && r.template).length
  const unmatchedCount = rows.filter((r) => !r.template).length

  function toggle(i: number) {
    setRows((rs) => rs.map((r, idx) => idx === i ? { ...r, selected: !r.selected } : r))
  }

  function setAll(selected: boolean) {
    setRows((rs) => rs.map((r) => r.template ? { ...r, selected } : r))
  }

  async function runBulk() {
    setRunning(true)
    setSummary(null)
    let done = 0
    let failed = 0
    let skipped = 0

    for (let i = 0; i < rows.length; i++) {
      const row = rows[i]
      if (!row.selected) continue
      if (!row.template) { skipped++; continue }

      setRows((rs) => rs.map((r, idx) => idx === i ? { ...r, state: 'generating' } : r))
      try {
        const rendered = renderTemplate(row.template, context, extraPlaceholders, enabledModules)
        await saveDocAndVersion(row.template, rendered)
        setRows((rs) => rs.map((r, idx) => idx === i ? { ...r, state: 'done' } : r))
        done++
      } catch (e) {
        setRows((rs) => rs.map((r, idx) =>
          idx === i ? { ...r, state: 'error', errorMessage: (e as Error).message } : r,
        ))
        failed++
      }
    }

    setSummary({ done, skipped, failed })
    setRunning(false)
  }

  return (
    <div className="fixed inset-0 bg-black/40 z-50 flex items-center justify-center p-4" onClick={onClose}>
      <div
        className="bg-white rounded-lg shadow-2xl w-[820px] max-h-[90vh] flex flex-col"
        onClick={(e) => e.stopPropagation()}
      >
        <header className="px-5 py-3 border-b border-gray-200 flex items-center justify-between">
          <div>
            <h3 className="font-semibold text-gray-800">Alle empfohlenen Dokumente generieren</h3>
            <p className="text-xs text-gray-500 mt-0.5">
              Compliance-Recommend wertet das aktuelle CompanyProfile + ComplianceScope aus
              und schlägt Vorlagen vor. Markierte werden client-seitig gerendert und als
              Drafts v1.0 in der Document-Library angelegt.
            </p>
          </div>
          <button className="text-gray-400 hover:text-gray-700 text-2xl" onClick={onClose}>×</button>
        </header>

        <div className="flex-1 overflow-y-auto">
          {loading && (
            <div className="p-8 text-center text-sm text-gray-500">Lade Empfehlungen…</div>
          )}
          {loadError && (
            <div className="m-5 p-3 text-sm text-rose-800 bg-rose-50 border border-rose-200 rounded">
              {loadError}
            </div>
          )}
          {!loading && !loadError && rows.length === 0 && (
            <div className="p-8 text-center text-sm text-gray-500">
              Keine Empfehlungen für dieses Profil.
              Stell sicher dass CompanyProfile + ComplianceScope ausgefüllt sind.
            </div>
          )}

          {!loading && rows.length > 0 && (
            <>
              <div className="px-5 py-2 bg-gray-50 border-b border-gray-200 flex items-center justify-between text-xs">
                <div className="text-gray-600">
                  <b>{selectedCount}</b> von {rows.length} ausgewählt
                  {unmatchedCount > 0 && (
                    <span className="ml-2 text-amber-700">
                      ({unmatchedCount} ohne Template — kann nicht generiert werden)
                    </span>
                  )}
                </div>
                <div className="flex gap-1">
                  <button
                    className="px-2 py-1 border border-gray-300 rounded hover:bg-white"
                    onClick={() => setAll(true)}
                    disabled={running}
                  >
                    Alle wählen
                  </button>
                  <button
                    className="px-2 py-1 border border-gray-300 rounded hover:bg-white"
                    onClick={() => setAll(false)}
                    disabled={running}
                  >
                    Keine wählen
                  </button>
                </div>
              </div>
              <ul className="divide-y divide-gray-100">
                {rows.map((row, i) => (
                  <BulkRow key={row.item.rule_id} row={row} onToggle={() => toggle(i)} running={running} />
                ))}
              </ul>
            </>
          )}
        </div>

        <footer className="px-5 py-3 border-t border-gray-200 bg-gray-50 flex items-center gap-3">
          {summary ? (
            <div className="text-sm text-gray-700">
              <b className="text-emerald-700">{summary.done} erstellt</b>
              {summary.skipped > 0 && <span className="ml-2 text-amber-700">· {summary.skipped} übersprungen</span>}
              {summary.failed > 0 && <span className="ml-2 text-rose-700">· {summary.failed} fehlgeschlagen</span>}
            </div>
          ) : (
            <div className="text-xs text-gray-500">
              Erzeugt {selectedCount} neue Drafts in der Document-Library.
            </div>
          )}
          <button className="ml-auto px-3 py-1.5 text-sm text-gray-600 hover:text-gray-800" onClick={onClose}>
            Schließen
          </button>
          {!summary && (
            <button
              className="px-4 py-1.5 text-sm bg-emerald-600 text-white rounded hover:bg-emerald-700 disabled:opacity-50"
              disabled={running || loading || selectedCount === 0}
              onClick={runBulk}
            >
              {running ? 'Generiere…' : `${selectedCount} Dokumente generieren`}
            </button>
          )}
        </footer>
      </div>
    </div>
  )
}

function BulkRow({ row, onToggle, running }: { row: Row; onToggle: () => void; running: boolean }) {
  const hasTemplate = !!row.template
  const cls = row.item.classification

  const stateBadge = (() => {
    switch (row.state) {
      case 'generating': return <span className="text-amber-700">⏳ generiere…</span>
      case 'done':       return <span className="text-emerald-700">✓ erstellt</span>
      case 'error':      return <span className="text-rose-700" title={row.errorMessage}>✗ Fehler</span>
      case 'skipped':    return <span className="text-gray-500">— übersprungen</span>
      default:           return null
    }
  })()

  return (
    <li className="px-5 py-2 flex items-start gap-3 hover:bg-gray-50">
      <input
        type="checkbox"
        className="mt-1"
        checked={row.selected}
        onChange={onToggle}
        disabled={!hasTemplate || running}
      />
      <div className="flex-1 min-w-0">
        <div className="flex items-center gap-2 flex-wrap">
          <ClassChip classification={cls} />
          <span className="text-sm font-medium text-gray-800">{row.item.title}</span>
          {!hasTemplate && (
            <span className="px-1.5 py-0.5 text-xs rounded border bg-amber-50 text-amber-800 border-amber-300">
              kein Template
            </span>
          )}
          <span className="ml-auto text-xs">{stateBadge}</span>
        </div>
        <div className="text-xs text-gray-500 mt-0.5">
          <code>{row.item.document_type}</code>
          {row.item.source_citation && <> · {row.item.source_citation}</>}
        </div>
        {row.errorMessage && (
          <div className="text-xs text-rose-700 mt-0.5">{row.errorMessage}</div>
        )}
      </div>
    </li>
  )
}

function ClassChip({ classification }: { classification: 'required' | 'recommended' | 'optional' }) {
  const map = {
    required:    { label: 'Pflicht',    cls: 'bg-rose-100 text-rose-800 border-rose-300' },
    recommended: { label: 'Empfohlen',  cls: 'bg-amber-100 text-amber-800 border-amber-300' },
    optional:    { label: 'Optional',   cls: 'bg-slate-100 text-slate-700 border-slate-300' },
  }[classification]
  return (
    <span className={`px-1.5 py-0.5 text-xs rounded border ${map.cls}`}>{map.label}</span>
  )
}

// ----- Render-Pipeline (Kopie aus GeneratorSection mit gleicher Logik) -----

function renderTemplate(
  template: LegalTemplateResult,
  context: TemplateContext,
  extraPlaceholders: Record<string, string>,
  enabledModules: string[],
): string {
  const ruleResult = runRuleset({
    doc_type: getDocType(template.templateType ?? '', template.language ?? 'de'),
    render: { lang: template.language ?? 'de', variant: 'standard' },
    context,
    modules: { enabled: enabledModules },
  })
  const allValues = {
    ...contextToPlaceholders(ruleResult?.contextAfterDefaults ?? context),
    ...extraPlaceholders,
  }
  const boolCtx = ruleResult
    ? buildBoolContext(ruleResult.contextAfterDefaults, ruleResult.computedFlags)
    : {}
  let content = applyBlockRemoval(template.text, ruleResult?.removedBlocks ?? [])
  content = applyConditionalBlocks(content, boolCtx)
  for (const [key, value] of Object.entries(allValues)) {
    if (value) {
      content = content.replace(
        new RegExp(key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
        value,
      )
    }
  }
  return content
}

async function saveDocAndVersion(
  template: LegalTemplateResult,
  renderedContent: string,
): Promise<void> {
  const docRes = await fetch(DOC_ENDPOINT, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      type: template.templateType || 'custom',
      name: template.documentTitle || 'Dokument',
      description: `Bulk-generiert aus Template ${template.templateType}`,
    }),
  })
  if (!docRes.ok) {
    throw new Error(`Document anlegen fehlgeschlagen: ${docRes.status} ${await docRes.text().catch(() => '')}`)
  }
  const doc = await docRes.json()
  const verRes = await fetch(VERSION_ENDPOINT, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      document_id: doc.id,
      title: template.documentTitle || 'Dokument',
      content: renderedContent,
      language: template.language || 'de',
      version: '1.0',
    }),
  })
  if (!verRes.ok) {
    throw new Error(`Version anlegen fehlgeschlagen: ${verRes.status} ${await verRes.text().catch(() => '')}`)
  }
}

// ----- Profile-Builder: SDK-State → /recommend Body -----

function buildRecommendProfile(
  companyProfile: CompanyProfile | null,
  complianceScope: ComplianceScopeState | null,
): Record<string, unknown> {
  const profile: Record<string, unknown> = {}

  // Aus CompanyProfile (camelCase TS-Modell)
  if (companyProfile) {
    if (companyProfile.employeeCount) {
      profile.org_employee_count = String(companyProfile.employeeCount).replace(/-/g, '_')
    }
    if (companyProfile.businessModel) {
      profile.org_business_model = String(companyProfile.businessModel).toLowerCase().replace(/\s+/g, '_')
    }
    if (companyProfile.isDataProcessor) {
      profile.comp_has_processors = 'yes'
    }
  }

  // ComplianceScope-Antworten: questionId entspricht direkt unserer Profil-
  // Feld-Konvention (proc_ai_usage, tech_third_country, prod_webshop, etc.)
  if (complianceScope?.answers) {
    for (const a of complianceScope.answers) {
      if (!a.questionId) continue
      if (a.value === null || a.value === undefined || a.value === '') continue
      profile[a.questionId] = a.value
    }
  }

  if (complianceScope?.decision?.determinedLevel) {
    profile.compliance_depth_level = complianceScope.decision.determinedLevel
  }

  return profile
}
