import { useState, useEffect, useRef, useCallback } from 'react';
import { api, S } from '../lib.js';

// ── Spracherkennung ───────────────────────────────────────────────────────────
const LANG_PATTERNS = [
  { lang:'javascript', label:'JavaScript', patterns:[/\b(const|let|var|function|=>|require|import|export|console\.log)\b/] },
  { lang:'typescript', label:'TypeScript', patterns:[/\b(interface|type\s+\w+\s*=|:\s*(string|number|boolean|void)|<T>)\b/] },
  { lang:'python',     label:'Python',     patterns:[/\b(def |import |from .* import|elif |print\(|self\.|__init__)\b/] },
  { lang:'jsx',        label:'JSX/React',  patterns:[/<[A-Z][a-zA-Z]+|useState|useEffect|return\s*\([\s\S]*<|className=/] },
  { lang:'html',       label:'HTML',       patterns:[/<html|<body|<div|<span|<head|<!DOCTYPE/i] },
  { lang:'css',        label:'CSS',        patterns:[/\{[\s\S]*:\s*[^;]+;\s*\}|@media|@keyframes|\.[\w-]+\s*\{/] },
  { lang:'sql',        label:'SQL',        patterns:[/\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|JOIN|CREATE TABLE)\b/i] },
  { lang:'bash',       label:'Bash/Shell', patterns:[/^#!/m, /\b(echo|grep|sed|awk|chmod|sudo|apt|curl|wget)\b/] },
  { lang:'json',       label:'JSON',       patterns:[/^\s*[\[{][\s\S]*[\]}]\s*$/, /"\w+":\s*[\w"[\]{]/] },
  { lang:'rust',       label:'Rust',       patterns:[/\b(fn |let mut|impl |pub fn|use std|println!)\b/] },
  { lang:'go',         label:'Go',         patterns:[/\b(func |package |import |fmt\.|var |:=)\b/] },
  { lang:'java',       label:'Java',       patterns:[/\b(public class|private |protected |void |System\.out)\b/] },
  { lang:'php',        label:'PHP',        patterns:[/<\?php|\$\w+\s*=|echo |function \w+|\$this->/] },
  { lang:'csharp',     label:'C#',         patterns:[/\b(using System|namespace |class \w+|public void|Console\.Write)\b/] },
  { lang:'cpp',        label:'C/C++',      patterns:[/#include|std::|cout <<|int main\(|nullptr/] },
  { lang:'yaml',       label:'YAML',       patterns:[/^[\w-]+:\s*$/m, /^\s+-\s+\w/m] },
  { lang:'dockerfile', label:'Dockerfile', patterns:[/^FROM |^RUN |^CMD |^EXPOSE |^COPY /m] },
];

const LANG_COLORS = {
  javascript:'#f7df1e', typescript:'#3178c6', python:'#3572a5', jsx:'#61dafb',
  html:'#e34c26', css:'#563d7c', sql:'#e38c00', bash:'#4EAA25',
  json:'#4ecdc4', rust:'#dea584', go:'#00add8', java:'#b07219',
  php:'#4f5d95', csharp:'#178600', cpp:'#f34b7d', yaml:'#cb171e',
  dockerfile:'#2496ed', text:'rgba(255,255,255,0.3)',
};

function detectLanguage(code) {
  if (!code?.trim()) return 'text';
  for (const { lang, patterns } of LANG_PATTERNS) {
    if (patterns.some(p => p.test(code))) return lang;
  }
  return 'text';
}

function getLangLabel(lang) {
  return LANG_PATTERNS.find(l=>l.lang===lang)?.label || lang.toUpperCase();
}

function fmtDt(s) {
  if (!s) return '';
  const d = new Date(s.replace(' ','T'));
  return isNaN(d) ? '' : d.toLocaleString('de-DE',{day:'2-digit',month:'2-digit',year:'numeric',hour:'2-digit',minute:'2-digit'});
}

// ── Share Modal ───────────────────────────────────────────────────────────────
function SnippetShareModal({ snippet, onClose, toast }) {
  const [username, setUsername] = useState('');
  const [shares,   setShares]   = useState([]);
  const load = () => api(`/tools/snippets/${snippet.id}/shares`).then(setShares).catch(()=>{});
  useEffect(()=>{ load(); },[]);
  const share = async () => {
    if (!username.trim()) return;
    try { await api(`/tools/snippets/${snippet.id}/share`,{body:{username:username.trim()}}); toast('Geteilt ✓'); setUsername(''); load(); }
    catch(e){ toast(e.message,'error'); }
  };
  const unshare = async uid => {
    try { await api(`/tools/snippets/${snippet.id}/share/${uid}`,{method:'DELETE'}); setShares(p=>p.filter(s=>s.id!==uid)); }
    catch(e){ toast(e.message,'error'); }
  };
  const isMob = window.innerWidth < 768;
  return (
    <div style={{position:'fixed',inset:0,background:'rgba(0,0,0,0.8)',zIndex:7000,
      display:'flex',alignItems:isMob?'flex-end':'center',justifyContent:'center',padding:isMob?0:24}}
      onClick={e=>e.target===e.currentTarget&&onClose()}>
      <div style={{background:'#1a1a1e',borderRadius:isMob?'16px 16px 0 0':14,
        width:'100%',maxWidth:400,padding:'20px 20px 28px',border:'1px solid rgba(255,255,255,0.12)'}}>
        {isMob&&<div style={{width:36,height:4,background:'rgba(255,255,255,0.15)',borderRadius:2,margin:'0 auto 14px'}}/>}
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:12}}>
          <div style={{color:'#fff',fontFamily:"'Space Mono',monospace",fontSize:13,fontWeight:700,
            overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',flex:1}}>🤝 {snippet.title}</div>
          <button onClick={onClose} style={{background:'transparent',border:'none',color:'rgba(255,255,255,0.4)',cursor:'pointer',fontSize:18,marginLeft:8}}>✕</button>
        </div>
        <p style={{color:'rgba(255,255,255,0.35)',fontFamily:'monospace',fontSize:10,marginBottom:12,lineHeight:1.6}}>
          Empfänger können lesen, aber nicht bearbeiten.
        </p>
        <div style={{display:'flex',gap:8,marginBottom:14}}>
          <input value={username} onChange={e=>setUsername(e.target.value)} onKeyDown={e=>e.key==='Enter'&&share()}
            placeholder="Benutzername" autoCapitalize="none" style={{...S.inp,flex:1}}/>
          <button onClick={share} style={S.btn('#4ecdc4')}>Teilen</button>
        </div>
        {shares.length>0 ? shares.map(s=>(
          <div key={s.id} style={{display:'flex',justifyContent:'space-between',alignItems:'center',
            padding:'7px 0',borderBottom:'1px solid rgba(255,255,255,0.05)'}}>
            <span style={{color:'rgba(255,255,255,0.7)',fontFamily:'monospace',fontSize:13}}>{s.username}</span>
            <button onClick={()=>unshare(s.id)} style={S.btn('#ff6b9d',true)}>✕</button>
          </div>
        )) : <div style={{color:'rgba(255,255,255,0.3)',fontFamily:'monospace',fontSize:11}}>Noch nicht geteilt.</div>}
      </div>
    </div>
  );
}

// ── Simple Diff ───────────────────────────────────────────────────────────────
function DiffView({ oldCode, newCode }) {
  if (!oldCode) return (
    <pre style={{margin:0,padding:'12px 14px',color:'#d0d0d0',fontFamily:"'Courier New',monospace",
      fontSize:11,lineHeight:1.6,whiteSpace:'pre-wrap',wordBreak:'break-all',
      background:'rgba(0,0,0,0.35)'}}>
      {newCode}
    </pre>
  );
  const oldLines = oldCode.split('\n');
  const newLines = newCode.split('\n');
  const maxLen = Math.max(oldLines.length, newLines.length);
  const rows = [];
  for (let i = 0; i < maxLen; i++) {
    const o = oldLines[i];
    const n = newLines[i];
    if (o === n) {
      rows.push({ type:'same', text: n ?? '' });
    } else {
      if (o !== undefined) rows.push({ type:'del', text: o });
      if (n !== undefined) rows.push({ type:'add', text: n });
    }
  }
  return (
    <div style={{background:'rgba(0,0,0,0.4)',border:'1px solid rgba(255,255,255,0.08)',
      borderRadius:8,overflow:'auto',maxHeight:320,fontFamily:"'Courier New',monospace",fontSize:11,lineHeight:1.6}}>
      {rows.map((r,i) => (
        <div key={i} style={{
          padding:'0 12px',whiteSpace:'pre-wrap',wordBreak:'break-all',
          background: r.type==='add'?'rgba(78,205,196,0.12)':r.type==='del'?'rgba(255,107,157,0.12)':'transparent',
          borderLeft:`2px solid ${r.type==='add'?'#4ecdc4':r.type==='del'?'#ff6b9d':'transparent'}`,
        }}>
          <span style={{color: r.type==='add'?'#4ecdc4':r.type==='del'?'rgba(255,107,157,0.7)':'rgba(255,255,255,0.2)',
            marginRight:6,userSelect:'none',fontSize:10}}>
            {r.type==='add'?'+':r.type==='del'?'−':' '}
          </span>
          <span style={{color: r.type==='same'?'#d0d0d0':'#fff'}}>{r.text}</span>
        </div>
      ))}
    </div>
  );
}
function HistoryModal({ snippet, onClose, onRestore, toast }) {
  const [history, setHistory] = useState([]);
  const [selected, setSelected] = useState(null);
  const [showDiff, setShowDiff] = useState(true);
  useEffect(()=>{
    api(`/tools/snippets/${snippet.id}/history`).then(h=>{ setHistory(h); if(h.length) setSelected(h[0]); }).catch(()=>{});
  },[]);
  const isMob = window.innerWidth < 768;
  const getOlderCode = (h) => {
    const idx = history.indexOf(h);
    // Newest history entry (idx=0) compares against CURRENT snippet code
    if (idx === 0) return snippet.code;
    // Older entries compare against the next newer history entry
    return history[idx - 1].code;
  };
  return (
    <div style={{position:'fixed',inset:0,background:'rgba(0,0,0,0.85)',zIndex:7000,
      display:'flex',alignItems:isMob?'flex-end':'center',justifyContent:'center',padding:isMob?0:24}}
      onClick={e=>e.target===e.currentTarget&&onClose()}>
      <div style={{background:'#1a1a1e',borderRadius:isMob?'16px 16px 0 0':14,
        width:'100%',maxWidth:680,border:'1px solid rgba(255,255,255,0.12)',
        display:'flex',flexDirection:'column',maxHeight:isMob?'88vh':'82vh',overflow:'hidden'}}>
        <div style={{padding:'14px 20px',borderBottom:'1px solid rgba(255,255,255,0.08)',
          display:'flex',justifyContent:'space-between',alignItems:'center',flexShrink:0,gap:10}}>
          <div style={{color:'#fff',fontFamily:"'Space Mono',monospace",fontSize:13,fontWeight:700}}>📜 Versionshistorie</div>
          <div style={{display:'flex',gap:6,alignItems:'center'}}>
            <button onClick={()=>setShowDiff(v=>!v)} style={{
              background:showDiff?'rgba(78,205,196,0.12)':'rgba(255,255,255,0.05)',
              border:`1px solid ${showDiff?'rgba(78,205,196,0.3)':'rgba(255,255,255,0.1)'}`,
              borderRadius:6,color:showDiff?'#4ecdc4':'rgba(255,255,255,0.4)',
              cursor:'pointer',fontSize:9,fontFamily:'monospace',padding:'3px 8px'}}>
              {showDiff?'± Diff':'Code'}
            </button>
            <button onClick={onClose} style={{background:'transparent',border:'none',color:'rgba(255,255,255,0.4)',cursor:'pointer',fontSize:18}}>✕</button>
          </div>
        </div>
        {history.length===0 ? (
          <div style={{padding:32,textAlign:'center',color:'rgba(255,255,255,0.3)',fontFamily:'monospace',fontSize:11}}>Keine älteren Versionen vorhanden.</div>
        ) : (
          <div style={{display:'flex',flex:1,overflow:'hidden'}}>
            <div style={{width:150,borderRight:'1px solid rgba(255,255,255,0.07)',overflowY:'auto',flexShrink:0}}>
              {history.map((h,i)=>(
                <button key={h.id} onClick={()=>setSelected(h)} style={{
                  width:'100%',padding:'10px 12px',
                  background:selected?.id===h.id?'rgba(78,205,196,0.1)':'transparent',
                  borderLeft:`2px solid ${selected?.id===h.id?'#4ecdc4':'transparent'}`,
                  border:'none',borderRight:'none',borderTop:'none',borderBottom:'1px solid rgba(255,255,255,0.05)',
                  cursor:'pointer',textAlign:'left'}}>
                  <div style={{color:'rgba(255,255,255,0.6)',fontFamily:'monospace',fontSize:9}}>v{history.length-i}</div>
                  <div style={{color:'rgba(255,255,255,0.3)',fontFamily:'monospace',fontSize:8,marginTop:2}}>{fmtDt(h.saved_at)}</div>
                </button>
              ))}
            </div>
            <div style={{flex:1,overflow:'auto',padding:14,display:'flex',flexDirection:'column',gap:10}}>
              {selected && (
                <>
                  <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',flexWrap:'wrap',gap:6}}>
                    <span style={{color:'rgba(255,255,255,0.35)',fontFamily:'monospace',fontSize:10}}>
                      {getLangLabel(selected.language)} · {fmtDt(selected.saved_at)}
                      {history.indexOf(selected) === history.length-1 && <span style={{color:'rgba(255,255,255,0.2)',marginLeft:6}}>(älteste Version)</span>}
                    </span>
                    {!snippet.is_shared && selected.code !== snippet.code && (
                      <button onClick={()=>onRestore(selected)} style={{
                        background:'rgba(255,230,109,0.1)',border:'1px solid rgba(255,230,109,0.25)',
                        borderRadius:6,color:'#ffe66d',cursor:'pointer',fontSize:10,padding:'4px 10px'}}>
                        ↩ Wiederherstellen
                      </button>
                    )}
                  </div>
                  {showDiff
                    ? <DiffView oldCode={getOlderCode(selected)} newCode={selected.code}/>
                    : <pre style={{margin:0,padding:'12px 14px',color:'#d0d0d0',fontFamily:"'Courier New',monospace",
                        fontSize:11,lineHeight:1.6,background:'rgba(0,0,0,0.35)',border:'1px solid rgba(255,255,255,0.08)',
                        borderRadius:8,overflowX:'auto',whiteSpace:'pre-wrap',wordBreak:'break-all',maxHeight:320,overflowY:'auto'}}>
                        {selected.code}
                      </pre>
                  }
                </>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ── Snippet Card ──────────────────────────────────────────────────────────────
function SnippetCard({ snippet, onEdit, onDelete, onShare, onHistory, toast }) {
  const [expanded, setExpanded] = useState(false);
  const [copied,   setCopied]   = useState(false);
  const langColor = LANG_COLORS[snippet.language] || LANG_COLORS.text;

  const copy = async () => {
    try { await navigator.clipboard.writeText(snippet.code); setCopied(true); setTimeout(()=>setCopied(false),1500); }
    catch { toast('Kopieren fehlgeschlagen','error'); }
  };

  return (
    <div style={{...S.card,marginBottom:10,padding:0,overflow:'hidden'}}>
      {/* Header */}
      <div onClick={()=>setExpanded(v=>!v)} style={{padding:'12px 14px',cursor:'pointer',
        display:'flex',alignItems:'center',gap:10}}>
        <div style={{width:8,height:8,borderRadius:'50%',background:langColor,flexShrink:0,
          boxShadow:`0 0 6px ${langColor}80`}}/>
        <div style={{flex:1,minWidth:0}}>
          <div style={{display:'flex',alignItems:'center',gap:6,flexWrap:'wrap'}}>
            <span style={{color:'#fff',fontFamily:'monospace',fontSize:13,fontWeight:700,
              overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{snippet.title}</span>
            {snippet.is_shared && (
              <span style={{fontSize:9,fontFamily:'monospace',color:'rgba(78,205,196,0.6)',
                background:'rgba(78,205,196,0.08)',border:'1px solid rgba(78,205,196,0.2)',
                borderRadius:4,padding:'1px 5px',flexShrink:0}}>von {snippet.owner}</span>
            )}
          </div>
          {snippet.description && (
            <div style={{color:'rgba(255,255,255,0.38)',fontFamily:'monospace',fontSize:10,
              marginTop:2,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
              {snippet.description}
            </div>
          )}
          <div style={{display:'flex',alignItems:'center',gap:6,marginTop:2,flexWrap:'wrap'}}>
            <span style={{fontSize:9,fontFamily:'monospace',color:langColor,opacity:0.8}}>
              {getLangLabel(snippet.language)}
            </span>
            {snippet.tags?.map(t=>(
              <span key={t} style={{fontSize:8,fontFamily:'monospace',
                color:'rgba(255,255,255,0.4)',background:'rgba(255,255,255,0.05)',
                border:'1px solid rgba(255,255,255,0.08)',borderRadius:4,padding:'1px 5px'}}>
                {t}
              </span>
            ))}
          </div>
        </div>
        <span style={{color:'rgba(255,255,255,0.3)',fontSize:10,
          transform:expanded?'rotate(90deg)':'rotate(0)',transition:'transform 0.2s',flexShrink:0}}>▶</span>
      </div>

      {/* Expanded */}
      {expanded && (
        <div style={{borderTop:'1px solid rgba(255,255,255,0.06)'}}>
          {snippet.description && (
            <div style={{padding:'8px 14px',color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:11,
              borderBottom:'1px solid rgba(255,255,255,0.04)'}}>
              {snippet.description}
            </div>
          )}

          {/* Code */}
          <div style={{position:'relative'}}>
            <pre style={{margin:0,padding:'12px 14px',paddingRight:48,
              color:'#d0d0d0',fontFamily:"'Courier New',Courier,monospace",
              fontSize:12,lineHeight:1.65,overflowX:'auto',
              background:'rgba(0,0,0,0.35)',whiteSpace:'pre',maxHeight:320,overflowY:'auto'}}>
              {snippet.code}
            </pre>
            <button onClick={copy} title="Kopieren" style={{
              position:'absolute',top:8,right:8,
              background:'rgba(255,255,255,0.07)',border:'1px solid rgba(255,255,255,0.12)',
              borderRadius:6,color: copied?'#4ecdc4':'rgba(255,255,255,0.5)',
              cursor:'pointer',fontSize:13,padding:'4px 8px',transition:'color 0.2s',
            }}>{copied?'✓':'⎘'}</button>
          </div>

          {/* Meta + Aktionen */}
          <div style={{padding:'10px 14px',display:'flex',alignItems:'center',
            justifyContent:'space-between',gap:8,flexWrap:'wrap',
            borderTop:'1px solid rgba(255,255,255,0.05)'}}>
            <div style={{color:'rgba(255,255,255,0.2)',fontFamily:'monospace',fontSize:9,lineHeight:1.7}}>
              <div>erstellt: {fmtDt(snippet.created_at)}</div>
              {snippet.updated_at !== snippet.created_at && (
                <div>bearbeitet: {fmtDt(snippet.updated_at)}</div>
              )}
            </div>
            <div style={{display:'flex',gap:5,flexWrap:'wrap'}}>
              <button onClick={()=>onHistory(snippet)}
                style={{background:'rgba(255,255,255,0.07)',border:'1px solid rgba(255,255,255,0.12)',
                  borderRadius:6,color:'rgba(255,255,255,0.5)',cursor:'pointer',
                  fontSize:10,padding:'4px 8px'}}>📜</button>
              {!snippet.is_shared && (
                <>
                  <button onClick={()=>onShare(snippet)}
                    style={{...S.btn('#ffe66d',true),fontSize:10,padding:'4px 8px'}}>🤝</button>
                  <button onClick={()=>onEdit(snippet)}
                    style={{...S.btn('#4ecdc4',true),fontSize:10,padding:'4px 8px'}}>✎</button>
                  <button onClick={()=>onDelete(snippet.id)}
                    style={{...S.btn('#ff6b9d',true),fontSize:10,padding:'4px 8px'}}>✕</button>
                </>
              )}
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ── Snippet Form ──────────────────────────────────────────────────────────────
function SnippetForm({ initial, onSave, onCancel, toast, existingTags=[] }) {
  const ALL_LANGS = ['text',...LANG_PATTERNS.map(l=>l.lang)];
  const [title,   setTitle]   = useState(initial?.title || '');
  const [code,    setCode]    = useState(initial?.code  || '');
  const [lang,    setLang]    = useState(initial?.language || 'text');
  const [desc,    setDesc]    = useState(initial?.description || '');
  const [tags,    setTags]    = useState(initial?.tags?.filter(t=>t!==initial?.language).join(', ') || '');
  const [busy,    setBusy]    = useState(false);
  const [autoLang,setAutoLang]= useState(!initial?.id);

  useEffect(()=>{
    if (!autoLang) return;
    const detected = detectLanguage(code);
    setLang(detected);
  },[code, autoLang]);

  // Nur Komma als Trennzeichen
  const parseTags = () => {
    const langTag = lang !== 'text' ? [lang] : [];
    const manual = tags.split(',').map(t=>t.trim().toLowerCase()).filter(Boolean);
    return [...new Set([...langTag, ...manual])];
  };

  const addSuggestedTag = tag => {
    const cur = tags.split(',').map(t=>t.trim()).filter(Boolean);
    if (cur.includes(tag)) return;
    setTags(cur.length ? cur.join(', ') + ', ' + tag : tag);
  };

  // Tags die noch nicht eingetragen sind als Vorschläge
  const currentParsed = parseTags();
  const suggestions = existingTags.filter(t => t !== lang && !currentParsed.includes(t));

  const save = async () => {
    if (!title.trim()) { toast('Titel erforderlich','error'); return; }
    setBusy(true);
    try {
      await onSave({ title:title.trim(), code, language:lang, description:desc.trim(), tags:parseTags() });
    } catch(e) { toast(e.message,'error'); }
    setBusy(false);
  };

  return (
    <div style={{...S.card,marginBottom:14}}>
      <div style={{...S.head,marginBottom:10}}>{initial?.id ? 'BEARBEITEN' : 'NEUER SCHNIPSEL'}</div>

      <input value={title} onChange={e=>setTitle(e.target.value)} placeholder="Titel *"
        style={{...S.inp,marginBottom:8}}/>
      <input value={desc} onChange={e=>setDesc(e.target.value)} placeholder="Beschreibung (optional)"
        style={{...S.inp,marginBottom:8,fontSize:12}}/>

      {/* Code */}
      <textarea value={code} onChange={e=>setCode(e.target.value)} placeholder="Code einfügen…"
        rows={8} style={{...S.inp,resize:'vertical',fontFamily:"'Courier New',monospace",
          fontSize:12,lineHeight:1.6,marginBottom:8,width:'100%',boxSizing:'border-box'}}/>

      {/* Sprache */}
      <div style={{display:'flex',gap:8,marginBottom:8,alignItems:'center'}}>
        <select value={lang} onChange={e=>{setLang(e.target.value);setAutoLang(false);}}
          style={{...S.inp,flex:1,fontSize:12}}>
          {ALL_LANGS.map(l=>(
            <option key={l} value={l} style={{background:'#1a1a1e'}}>
              {getLangLabel(l)}
            </option>
          ))}
        </select>
        <label style={{display:'flex',alignItems:'center',gap:5,cursor:'pointer',flexShrink:0}}>
          <input type="checkbox" checked={autoLang} onChange={e=>setAutoLang(e.target.checked)}
            style={{accentColor:'#4ecdc4'}}/>
          <span style={{color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:10}}>Auto</span>
        </label>
        {lang!=='text'&&<div style={{width:10,height:10,borderRadius:'50%',
          background:LANG_COLORS[lang]||'#fff',flexShrink:0}}/>}
      </div>

      {/* Tags */}
      <div style={{marginBottom:12}}>
        <label style={{...S.head,display:'block',marginBottom:4,fontSize:9}}>WEITERE TAGS (kommagetrennt)</label>
        <input value={tags} onChange={e=>setTags(e.target.value)} placeholder="z.B. api, auth, utils"
          autoCapitalize="none" style={{...S.inp,fontSize:12}}/>
        {/* Vorhandene Tags als Vorschläge */}
        {suggestions.length>0 && (
          <div style={{marginTop:6}}>
            <div style={{color:'rgba(255,255,255,0.25)',fontFamily:'monospace',fontSize:8,marginBottom:4}}>VORHANDENE TAGS HINZUFÜGEN:</div>
            <div style={{display:'flex',gap:4,flexWrap:'wrap'}}>
              {suggestions.map(t=>(
                <button key={t} onClick={()=>addSuggestedTag(t)} style={{
                  fontSize:9,fontFamily:'monospace',padding:'2px 8px',borderRadius:12,cursor:'pointer',
                  background:'rgba(255,255,255,0.04)',border:'1px solid rgba(255,255,255,0.1)',
                  color:'rgba(255,255,255,0.4)',
                }}>+ {t}</button>
              ))}
            </div>
          </div>
        )}
        {parseTags().length>0&&(
          <div style={{display:'flex',gap:4,flexWrap:'wrap',marginTop:6}}>
            {parseTags().map(t=>(
              <span key={t} style={{fontSize:9,fontFamily:'monospace',
                color:t===lang?LANG_COLORS[lang]:'rgba(255,255,255,0.5)',
                background:'rgba(255,255,255,0.06)',borderRadius:4,padding:'2px 7px',
                border:`1px solid ${t===lang?(LANG_COLORS[lang]+'40'):'rgba(255,255,255,0.1)'}`}}>
                {t}
              </span>
            ))}
          </div>
        )}
      </div>

      <div style={{display:'flex',gap:8}}>
        <button onClick={save} disabled={busy}
          style={{...S.btn('#4ecdc4'),flex:1,textAlign:'center',padding:'10px 0',opacity:busy?0.5:1}}>
          {busy?'…':initial?.id?'✓ Aktualisieren':'↓ Speichern'}
        </button>
        <button onClick={onCancel} style={{...S.btn('#ff6b9d',true),padding:'0 16px'}}>Abbrechen</button>
      </div>
    </div>
  );
}

// ── Main Component ────────────────────────────────────────────────────────────
export default function CodeSchnipsel({ toast, mobile }) {
  const [own,       setOwn]       = useState([]);
  const [shared,    setShared]    = useState([]);
  const [sharedByMe,setSharedByMe]= useState([]);
  const [tab,       setTab]       = useState('own');
  const [search,    setSearch]    = useState('');
  const [tagFilters,setTagFilters]= useState([]); // multi-select array
  const [showForm,  setShowForm]  = useState(false);
  const [editItem,  setEditItem]  = useState(null);
  const [shareItem, setShareItem] = useState(null);
  const [histItem,  setHistItem]  = useState(null);

  const load = useCallback(()=>{
    api('/tools/snippets').then(d=>{ setOwn(d.own||[]); setShared(d.shared||[]); setSharedByMe(d.sharedByMe||[]); }).catch(()=>{});
  },[]);

  useEffect(()=>{ load(); },[load]);

  // Only tags that are currently in use
  const allItems = [...own, ...shared];
  const allTags = [...new Set(allItems.flatMap(s=>s.tags||[]))].sort();

  const toggleTag = t => setTagFilters(p => p.includes(t) ? p.filter(x=>x!==t) : [...p, t]);

  const filterItems = items => {
    let res = items;
    if (tagFilters.length) res = res.filter(s => tagFilters.every(t=>s.tags?.includes(t)));
    if (search.trim()) {
      const q = search.toLowerCase();
      res = res.filter(s =>
        s.title.toLowerCase().includes(q) ||
        s.code.toLowerCase().includes(q) ||
        s.description?.toLowerCase().includes(q) ||
        s.tags?.some(t=>t.includes(q)) ||
        s.language.includes(q)
      );
    }
    return res;
  };

  const curList = tab==='own' ? own : tab==='shared' ? shared : sharedByMe;
  const items = filterItems(curList);

  const handleSave = async form => {
    if (editItem?.id) {
      const r = await api(`/tools/snippets/${editItem.id}`,{method:'PUT',body:form});
      setOwn(p=>p.map(s=>s.id===r.id?r:s)); setEditItem(null);
    } else {
      const r = await api('/tools/snippets',{body:form});
      setOwn(p=>[r,...p]); setShowForm(false);
    }
    toast('Gespeichert ✓');
  };

  const handleDelete = async id => {
    if (!window.confirm('Schnipsel wirklich löschen?')) return;
    await api(`/tools/snippets/${id}`,{method:'DELETE'});
    setOwn(p=>p.filter(s=>s.id!==id)); toast('Gelöscht');
  };

  const handleRestore = async (histEntry) => {
    if (!histItem) return;
    const r = await api(`/tools/snippets/${histItem.id}`,{method:'PUT',body:{
      code: histEntry.code, language: histEntry.language
    }});
    setOwn(p=>p.map(s=>s.id===r.id?r:s));
    setHistItem(null); toast('Version wiederhergestellt ✓');
  };

  return (
    <div style={{padding:mobile?'14px 14px 90px':'36px 44px',maxWidth:860}}>
      {shareItem && <SnippetShareModal snippet={shareItem} onClose={()=>{setShareItem(null);load();}} toast={toast}/>}
      {histItem  && <HistoryModal snippet={histItem} onClose={()=>setHistItem(null)} onRestore={handleRestore} toast={toast}/>}

      {/* Header */}
      <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:14}}>
        <h1 style={{color:'#fff',fontFamily:"'Space Mono',monospace",fontSize:mobile?17:22,margin:0}}>Code-Schnipsel</h1>
        <div style={{display:'flex',gap:8}}>
          <button onClick={load} title="Neu laden"
            style={{background:'transparent',border:'1px solid rgba(255,255,255,0.1)',borderRadius:8,
              color:'rgba(255,255,255,0.4)',cursor:'pointer',padding:'6px 10px',fontSize:14,fontFamily:'monospace'}}>↺</button>
          {!showForm && !editItem && tab==='own' && (
            <button onClick={()=>setShowForm(true)}
              style={{...S.btn('#4ecdc4'),padding:'7px 16px',fontSize:12}}>+ Neu</button>
          )}
        </div>
      </div>

      {/* Form */}
      {(showForm || editItem) && (
        <SnippetForm
          initial={editItem}
          onSave={handleSave}
          onCancel={()=>{ setShowForm(false); setEditItem(null); }}
          toast={toast}
          existingTags={allTags}
        />
      )}

      {/* Tabs */}
      <div style={{display:'flex',gap:6,marginBottom:12,flexWrap:'wrap'}}>
        {[['own','Meine',own.length],['shared','Geteilt mit mir',shared.length],['sharedByMe','Geteilt von mir',sharedByMe.length]].map(([k,l,cnt])=>(
          <button key={k} onClick={()=>{setTab(k);setSearch('');setTagFilters([]);}} style={{
            padding:'6px 14px',borderRadius:20,fontFamily:'monospace',fontSize:11,cursor:'pointer',
            background:tab===k?'#4ecdc4':'rgba(255,255,255,0.05)',
            color:tab===k?'#0d0d0f':'rgba(255,255,255,0.55)',
            border:tab===k?'none':'1px solid rgba(255,255,255,0.1)',
            fontWeight:tab===k?700:400,
          }}>
            {l}{cnt>0&&<span style={{marginLeft:4,opacity:0.7}}>({cnt})</span>}
          </button>
        ))}
      </div>

      {/* Suche */}
      <div style={{position:'relative',marginBottom:10}}>
        <span style={{position:'absolute',left:12,top:'50%',transform:'translateY(-50%)',
          color:'rgba(255,255,255,0.4)',pointerEvents:'none'}}>⌕</span>
        <input value={search} onChange={e=>setSearch(e.target.value)} placeholder="Suchen (Titel, Code, Tags…)"
          style={{...S.inp,paddingLeft:34}}/>
        {search && <button onClick={()=>setSearch('')} style={{position:'absolute',right:10,top:'50%',
          transform:'translateY(-50%)',background:'transparent',border:'none',
          color:'rgba(255,255,255,0.4)',cursor:'pointer',fontSize:16}}>✕</button>}
      </div>

      {/* Tag-Filter (Mehrfachauswahl) */}
      {allTags.length>0 && (
        <div style={{display:'flex',gap:5,flexWrap:'wrap',marginBottom:14,alignItems:'center'}}>
          <button onClick={()=>setTagFilters([])} style={{
            fontSize:9,fontFamily:'monospace',padding:'3px 9px',borderRadius:20,cursor:'pointer',
            background:!tagFilters.length?'rgba(78,205,196,0.15)':'rgba(255,255,255,0.04)',
            border:`1px solid ${!tagFilters.length?'rgba(78,205,196,0.3)':'rgba(255,255,255,0.08)'}`,
            color:!tagFilters.length?'#4ecdc4':'rgba(255,255,255,0.4)',
          }}>Alle</button>
          {allTags.map(t=>{
            const active = tagFilters.includes(t);
            const c = LANG_COLORS[t] || '#4ecdc4';
            return (
              <button key={t} onClick={()=>toggleTag(t)} style={{
                fontSize:9,fontFamily:'monospace',padding:'3px 9px',borderRadius:20,cursor:'pointer',
                background:active?`${c}20`:'rgba(255,255,255,0.04)',
                border:`1px solid ${active?`${c}50`:'rgba(255,255,255,0.08)'}`,
                color:active?c:'rgba(255,255,255,0.45)',
              }}>{active?'✓ ':''}{t}</button>
            );
          })}
          {tagFilters.length>0 && (
            <span style={{color:'rgba(255,255,255,0.25)',fontFamily:'monospace',fontSize:9,marginLeft:2}}>
              ({tagFilters.length} aktiv)
            </span>
          )}
        </div>
      )}

      {/* Liste */}
      {items.length===0 ? (
        <div style={{...S.card,textAlign:'center',padding:40}}>
          <div style={{fontSize:28,marginBottom:10}}>{'</>'}</div>
          <div style={{color:'rgba(255,255,255,0.35)',fontFamily:'monospace',fontSize:12}}>
            {search||tagFilters.length ? 'Keine Treffer.' : tab==='own' ? 'Noch keine Schnipsel – füge deinen ersten hinzu.' : 'Noch nichts geteilt.'}
          </div>
        </div>
      ) : items.map(s=>(
        <SnippetCard
          key={s.id} snippet={s} toast={toast}
          onEdit={setEditItem}
          onDelete={handleDelete}
          onShare={setShareItem}
          onHistory={setHistItem}
        />
      ))}
    </div>
  );
}
