'use client'

/**
 * CookieFindings — bereitet die Library-Befunde bearbeitbar auf, statt als
 * Fließtext-Liste. Zwei Sichten (Umschalter):
 *  - Nach Fehlertyp: je Typ eine Maßnahme + betroffene Cookies + Ticket-Text
 *    (= eine Ticket-Einheit). Getrennt in FINDINGS (zu beheben) und HINWEISE
 *    (neutral, gegen DSE zu prüfen: Drittland, EU-Alternative).
 *  - Matrix: Zeilen = Cookies, Spalten = Fehlertypen, Markierung wo nachzubessern
 *    ist (ein Cookie, alle Probleme auf einen Blick).
 */

import React, { useMemo, useState } from 'react'

import type { CookieFinding } from './CookieLibraryPanel'

const TYPE_LABEL: Record<string, string> = {
  tracker_as_necessary: 'Tracker als „notwendig" deklariert',
  missing_purpose: 'Zweck fehlt',
  excessive_lifetime: 'Speicherdauer zu lang',
  vague_duration: 'Speicherdauer nicht konkret',
  missing_retention: 'Keine Speicherdauer/Löschfrist',
  missing_opt_out: 'Opt-Out-/Widerspruchs-Link fehlt',
  storage_transparency: 'Speichertyp nicht transparent',
  third_country: 'Drittland-Transfer',
  eu_alternative: 'EU-Alternative verfügbar',
}
const TYPE_MEASURE: Record<string, string> = {
  tracker_as_necessary: 'Als einwilligungspflichtig einstufen (§ 25 Abs. 1 TDDDG).',
  missing_purpose: 'Zweck je Cookie ergänzen (Art. 13 DSGVO).',
  vague_duration: 'Konkrete Speicherdauer oder Löschkriterium angeben (Art. 5 Abs. 1 lit. e).',
  missing_retention: 'Speicherdauer/Löschfrist je Verarbeiter festlegen (Art. 5 Abs. 1 lit. e).',
  missing_opt_out: 'Opt-Out-/Widerspruchs-Link je Anbieter angeben (Art. 7 Abs. 3 + Art. 21).',
  excessive_lifetime: 'Speicherdauer auf das Erforderliche reduzieren (Art. 5 Abs. 1 lit. e).',
  storage_transparency: 'Speichertyp + -dauer je Objekt transparent ausweisen (§ 25 TDDDG).',
  third_country: 'Geeignete Garantien je Verarbeiter prüfen (SCC Art. 46 / Art. 49).',
  eu_alternative: 'EU-Alternative prüfen (kommerziell, kein Drittland-Transfer).',
}
const TYPE_ORDER = [
  'tracker_as_necessary', 'missing_purpose', 'vague_duration', 'missing_retention',
  'missing_opt_out', 'excessive_lifetime', 'storage_transparency',
  'third_country', 'eu_alternative',
]
const SEV_ORDER: Record<string, number> = { HIGH: 0, MEDIUM: 1, LOW: 2 }
const SEV_COLOR: Record<string, string> = {
  HIGH: 'bg-red-100 text-red-700',
  MEDIUM: 'bg-amber-100 text-amber-700',
  LOW: 'bg-blue-100 text-blue-700',
}

interface Group { type: string; items: CookieFinding[]; severity: string }

function groupByType(findings: CookieFinding[]): Group[] {
  const m = new Map<string, CookieFinding[]>()
  for (const f of findings) {
    if (!m.has(f.type)) m.set(f.type, [])
    m.get(f.type)!.push(f)
  }
  const groups = [...m.entries()].map(([type, items]) => ({
    type, items,
    severity: items.reduce(
      (s, f) => (SEV_ORDER[f.severity] ?? 3) < (SEV_ORDER[s] ?? 3) ? f.severity : s, 'LOW'),
  }))
  groups.sort((a, b) =>
    (TYPE_ORDER.indexOf(a.type) + 99) % 100 - (TYPE_ORDER.indexOf(b.type) + 99) % 100)
  return groups
}

function cookieLabel(f: CookieFinding): string {
  const v = f.vendor && f.vendor !== '—' ? ` (${f.vendor})` : ''
  const d = f.declared ? ` — ${f.declared}` : ''
  return `${f.cookie}${v}${d}`
}

function ticketText(g: Group): string {
  return [
    `${TYPE_LABEL[g.type] || g.type} — ${g.items.length} betroffen`,
    `Maßnahme: ${TYPE_MEASURE[g.type] || ''}`,
    '',
    ...g.items.map(f => `- ${cookieLabel(f)}`),
  ].join('\n')
}

function GroupCard({ g }: { g: Group }) {
  const [open, setOpen] = useState(false)
  const [copied, setCopied] = useState(false)
  const copy = () => {
    navigator.clipboard?.writeText(ticketText(g)).then(() => {
      setCopied(true); setTimeout(() => setCopied(false), 1500)
    }).catch(() => {})
  }
  return (
    <div className="border-b last:border-b-0">
      <button onClick={() => setOpen(o => !o)}
        className="w-full flex items-center gap-2 px-3 py-2 text-left hover:bg-gray-50 text-xs">
        <span className={`text-gray-400 transition-transform ${open ? 'rotate-90' : ''}`}>›</span>
        <span className={`text-[10px] font-semibold px-1.5 py-0.5 rounded ${SEV_COLOR[g.severity] || 'bg-gray-100'}`}>
          {g.severity}
        </span>
        <span className="font-medium text-gray-800 flex-1 min-w-0 truncate">
          {TYPE_LABEL[g.type] || g.type}
        </span>
        <span className="text-gray-500">{g.items.length}</span>
      </button>
      {open && (
        <div className="px-4 pb-3 space-y-2">
          <div className="text-xs text-gray-700 bg-blue-50 rounded px-2 py-1.5">
            <span className="font-semibold">Maßnahme:</span> {TYPE_MEASURE[g.type] || '—'}
          </div>
          <table className="w-full text-[11px]">
            <tbody>
              {g.items.map((f, i) => (
                <tr key={i} className="border-t border-gray-100 align-top">
                  <td className="px-2 py-1 font-mono text-gray-700 break-all w-40">{f.cookie}</td>
                  <td className="px-2 py-1 text-gray-400 w-32 truncate">{f.vendor}</td>
                  <td className="px-2 py-1 text-gray-500">{f.declared || ''}</td>
                </tr>
              ))}
            </tbody>
          </table>
          <button onClick={copy}
            className="text-[11px] px-2 py-1 rounded bg-gray-100 text-gray-700 hover:bg-gray-200">
            {copied ? '✓ Ticket-Text kopiert' : 'Ticket-Text kopieren'}
          </button>
        </div>
      )}
    </div>
  )
}

function Section({ title, hint, groups }: { title: string; hint?: string; groups: Group[] }) {
  if (!groups.length) return null
  return (
    <div className="border rounded-lg overflow-hidden">
      <div className="px-3 py-2 bg-slate-50 border-b">
        <span className="text-xs font-semibold text-gray-700">{title}</span>
        {hint && <span className="text-[10px] text-gray-400 ml-2">{hint}</span>}
      </div>
      {groups.map(g => <GroupCard key={g.type} g={g} />)}
    </div>
  )
}

function Matrix({ findings }: { findings: CookieFinding[] }) {
  const { rows, cols } = useMemo(() => {
    const colSet = new Set(findings.map(f => f.type))
    const cols = TYPE_ORDER.filter(t => colSet.has(t))
    const rowMap = new Map<string, { label: string; vendor: string; hits: Record<string, string> }>()
    for (const f of findings) {
      const key = `${f.cookie}@@${f.vendor}`
      if (!rowMap.has(key)) rowMap.set(key, { label: f.cookie, vendor: f.vendor, hits: {} })
      rowMap.get(key)!.hits[f.type] = (f.kind === 'hinweis') ? '⚠' : '✗'
    }
    return { rows: [...rowMap.values()], cols }
  }, [findings])

  return (
    <div className="border rounded-lg overflow-auto max-h-[32rem]">
      <table className="w-full text-[11px]">
        <thead className="bg-slate-50 sticky top-0">
          <tr>
            <th className="px-2 py-1.5 text-left font-semibold text-gray-600">Cookie</th>
            {cols.map(c => (
              <th key={c} className="px-1 py-1.5 text-center font-normal text-gray-500" title={TYPE_LABEL[c]}>
                {(TYPE_LABEL[c] || c).split(' ')[0]}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((r, i) => (
            <tr key={i} className="border-t border-gray-100">
              <td className="px-2 py-1 font-mono text-gray-700 break-all">
                {r.label}
                {r.vendor && r.vendor !== '—' && <span className="text-gray-400 ml-1">· {r.vendor}</span>}
              </td>
              {cols.map(c => (
                <td key={c} className={`px-1 py-1 text-center ${r.hits[c] === '✗' ? 'text-red-600' : r.hits[c] === '⚠' ? 'text-amber-600' : 'text-gray-200'}`}>
                  {r.hits[c] || '·'}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
      <div className="px-2 py-1.5 text-[10px] text-gray-400 border-t">
        ✗ = Handlung nötig · ⚠ = Hinweis (zu prüfen) · Spalte = Fehlertyp (Tooltip)
      </div>
    </div>
  )
}

export function CookieFindings({ findings }: { findings: CookieFinding[] }) {
  const [mode, setMode] = useState<'type' | 'matrix'>('type')
  const real = findings.filter(f => (f.kind ?? 'finding') !== 'hinweis')
  const hints = findings.filter(f => (f.kind ?? 'finding') === 'hinweis')

  if (!findings.length) {
    return <div className="px-4 py-3 text-sm text-green-700 border rounded-lg">Keine Abweichungen gegen die Library.</div>
  }

  const btn = (m: 'type' | 'matrix', label: string) => (
    <button onClick={() => setMode(m)}
      className={`px-2.5 py-1 rounded text-xs ${mode === m ? 'bg-blue-600 text-white' : 'bg-gray-100 text-gray-600 hover:bg-gray-200'}`}>
      {label}
    </button>
  )

  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between">
        <span className="text-sm font-semibold text-gray-800">
          {findings.length} Befund{findings.length !== 1 ? 'e' : ''}
          <span className="text-xs font-normal text-gray-400 ml-2">
            {real.length} zu beheben · {hints.length} Hinweise
          </span>
        </span>
        <div className="flex items-center gap-1">
          {btn('type', 'Nach Fehlertyp')}
          {btn('matrix', 'Matrix')}
        </div>
      </div>

      {mode === 'matrix' ? (
        <Matrix findings={findings} />
      ) : (
        <div className="space-y-3">
          <Section title="Findings — zu beheben" groups={groupByType(real)} />
          <Section title="Hinweise — neutral, gegen DSE/Doku zu prüfen"
            hint="z.B. Drittland: interne Verträge können wir nicht einsehen"
            groups={groupByType(hints)} />
        </div>
      )}
    </div>
  )
}
