import { useState, useEffect, useRef, useCallback } from 'react';
import { api, S } from '../lib.js';
import { useConfirm } from '../confirm.jsx';
import { UploadIcon, DownloadIcon, TrashIcon, SearchIcon, ChevronIcon } from '../icons.jsx';

const fmtSize = b => b<1024?`${b} B`:b<1024*1024?`${(b/1024).toFixed(1)} KB`:`${(b/(1024*1024)).toFixed(1)} MB`;
const fmtDate = s => { if (!s) return ''; const d = new Date(String(s).replace(' ','T')); return isNaN(d)?'':d.toLocaleDateString('de-DE',{day:'2-digit',month:'2-digit',year:'numeric'}); };
const extIcon = name => {
  const e = name.split('.').pop().toLowerCase();
  if (['jpg','jpeg','png','gif','webp'].includes(e)) return '🖼';
  if (e==='pdf') return '📄'; if (['zip','rar','7z'].includes(e)) return '📦';
  if (['mp4','mov','avi'].includes(e)) return '🎬'; if (['mp3','wav'].includes(e)) return '🎵';
  if (['stl','3mf'].includes(e)) return '🖨'; if (['txt','md'].includes(e)) return '📝';
  if (['xlsx','csv'].includes(e)) return '📊'; if (['docx','doc'].includes(e)) return '📃';
  return '📎';
};

const IconBtn = ({ onClick, color, title, children, stop }) => (
  <button onClick={stop ? e=>{e.stopPropagation();onClick(e);} : onClick}
    title={title}
    style={{ background:`${color}14`, border:`1px solid ${color}35`,
      borderRadius:7, padding:'6px 8px', cursor:'pointer',
      display:'flex', alignItems:'center', justifyContent:'center', gap:4,
      color, fontFamily:'monospace', fontSize:11, flexShrink:0 }}>
    {children}
  </button>
);

// ── Öffentlicher Link-Share Modal ─────────────────────────────────────────────
function PublicShareModal({ item, itemType, onClose, onShareCreated, toast }) {
  const [password,    setPassword]    = useState(() => genPw());
  const [expiresH,    setExpiresH]    = useState(1);
  const [label,       setLabel]       = useState('');
  const [shares,      setShares]      = useState([]);
  const [creating,    setCreating]    = useState(false);
  const [newLink,     setNewLink]     = useState(null);
  const [newPw,       setNewPw]       = useState('');

  const isFolder = itemType === 'folder';
  const base = '/tools/dateien/public-shares';

  function genPw() {
    const upper   = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
    const lower   = 'abcdefghjkmnpqrstuvwxyz';
    const digits  = '23456789';
    const special = '!@#$%&*-+?';
    const all     = upper + lower + digits + special;
    // Mindestens je 1 aus jeder Kategorie, Rest zufällig
    const pick = s => s[Math.floor(Math.random()*s.length)];
    const base = [pick(upper), pick(lower), pick(digits), pick(special)];
    const rest = Array.from({length:8}, () => pick(all));
    return [...base, ...rest].sort(() => Math.random()-0.5).join('');
  }

  useEffect(() => {
    api(base).then(d => setShares((d.shares||[]).filter(s => isFolder
      ? s.folder_id === item.id
      : s.file_id === item.id
    ))).catch(()=>{});
  }, []);

  async function createShare() {
    if (!password.trim()) { toast('Passwort ist Pflicht'); return; }
    setCreating(true);
    try {
      const body = {
        [isFolder ? 'folder_id' : 'file_id']: item.id,
        password: password.trim(),
        expires_hours: expiresH,
        label: label || undefined,
      };
      const d = await api(base, { body });
      const link = `${window.location.origin}/s/${d.token}`;
      setNewLink(link);
      setNewPw(password.trim());
      setShares(p => [d.share, ...p]);
      onShareCreated?.(d.token, password.trim());
      navigator.clipboard?.writeText(link).catch(()=>{});
      toast('Link erstellt & kopiert ✓');
      setPassword(genPw());
    } catch(e) { toast('Fehler: ' + e.message); }
    finally { setCreating(false); }
  }

  async function deleteShare(id) {
    await api(`${base}/${id}`, { method:'DELETE' });
    setShares(p => p.filter(s => s.id !== id));
    toast('Link gelöscht');
  }

  function copyLink(token) {
    const link = `${window.location.origin}/s/${token}`;
    navigator.clipboard?.writeText(link).then(() => toast('Link kopiert ✓')).catch(() => toast(link));
  }

  function fmtExp(exp) {
    if (!exp) return 'Kein Ablauf';
    const d = new Date(exp * 1000);
    return d.toLocaleDateString('de-DE') + ' ' + d.toLocaleTimeString('de-DE', {hour:'2-digit',minute:'2-digit'});
  }

  const expiryOptions = [
    { label:'1 Stunde',   h:1 },
    { label:'24 Stunden', h:24 },
    { label:'7 Tage',     h:168 },
    { label:'30 Tage',    h:720 },
  ];

  return (
    <div style={{position:'fixed',inset:0,background:'rgba(0,0,0,0.7)',zIndex:1000,display:'flex',alignItems:'center',justifyContent:'center',padding:16}}
      onClick={e=>e.target===e.currentTarget&&onClose()}>
      <div style={{background:'#1a1d2e',border:'1px solid rgba(255,255,255,0.1)',borderRadius:14,padding:24,width:'100%',maxWidth:440,maxHeight:'85vh',overflowY:'auto'}}>
        <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:16}}>
          <div style={{color:'#fff',fontFamily:'monospace',fontSize:14,fontWeight:700}}>🔗 Öffentlicher Link</div>
          <button onClick={onClose} style={{background:'none',border:'none',color:'rgba(255,255,255,0.5)',fontSize:18,cursor:'pointer'}}>✕</button>
        </div>
        <div style={{color:'rgba(255,255,255,0.5)',fontFamily:'monospace',fontSize:11,marginBottom:20}}>
          {isFolder ? '📁' : '📄'} {item.name}
        </div>

        {/* Neuer Link */}
        <div style={{marginBottom:20}}>
          <div style={{color:'rgba(255,255,255,0.4)',fontFamily:'monospace',fontSize:10,marginBottom:8,letterSpacing:1}}>NEUEN LINK ERSTELLEN</div>

          <input value={label} onChange={e=>setLabel(e.target.value)}
            placeholder="Bezeichnung (optional)"
            style={{...S.inp, width:'100%', boxSizing:'border-box', marginBottom:8}} />

          {/* Passwort Pflicht + Generator */}
          <div style={{display:'flex',gap:6,marginBottom:8}}>
            <div style={{flex:1}}>
              <input
                type="text"
                value={password}
                onChange={e=>setPassword(e.target.value)}
                placeholder="Passwort (Pflicht)"
                style={{...S.inp, width:'100%', boxSizing:'border-box', fontFamily:'monospace', letterSpacing:1}}
              />
            </div>
            <button onClick={()=>setPassword(genPw())} title="Passwort generieren"
              style={{background:'rgba(245,158,11,0.12)',border:'1px solid rgba(245,158,11,0.3)',borderRadius:7,padding:'0 10px',color:'#f59e0b',cursor:'pointer',fontSize:14,flexShrink:0}}>
              🔀
            </button>
          </div>

          {/* Ablauf – kein "Kein Ablauf" */}
          <div style={{display:'flex',gap:6,flexWrap:'wrap',marginBottom:12}}>
            {expiryOptions.map(o => (
              <button key={o.h} onClick={()=>setExpiresH(o.h)}
                style={{
                  background: expiresH===o.h ? '#f59e0b22' : 'rgba(255,255,255,0.05)',
                  border: `1px solid ${expiresH===o.h ? '#f59e0b88' : 'rgba(255,255,255,0.1)'}`,
                  borderRadius:6, padding:'4px 10px',
                  color: expiresH===o.h ? '#f59e0b' : 'rgba(255,255,255,0.5)',
                  fontFamily:'monospace', fontSize:10, cursor:'pointer',
                }}>
                {o.label}
              </button>
            ))}
          </div>

          <button onClick={createShare} disabled={creating||!password.trim()}
            style={{...S.btn('#4ade80'), width:'100%', opacity:(creating||!password.trim())?0.5:1}}>
            {creating ? '⏳ Erstelle...' : '🔗 Link erstellen'}
          </button>

          {newLink && (
            <div style={{marginTop:10, padding:'10px 12px', background:'rgba(74,222,128,0.08)', border:'1px solid rgba(74,222,128,0.3)', borderRadius:8}}>
              <div style={{color:'rgba(255,255,255,0.4)',fontFamily:'monospace',fontSize:9,marginBottom:4}}>LINK (in Zwischenablage)</div>
              <div style={{color:'#4ade80',fontFamily:'monospace',fontSize:10,wordBreak:'break-all',marginBottom:6}}>{newLink}</div>
              <div style={{color:'rgba(255,255,255,0.4)',fontFamily:'monospace',fontSize:9,marginBottom:2}}>PASSWORT</div>
              <div style={{display:'flex',alignItems:'center',gap:8}}>
                <div style={{color:'#f59e0b',fontFamily:'monospace',fontSize:12,letterSpacing:2}}>{newPw}</div>
                <button onClick={()=>navigator.clipboard?.writeText(newPw).then(()=>toast('Passwort kopiert ✓'))}
                  style={{background:'rgba(245,158,11,0.1)',border:'1px solid rgba(245,158,11,0.3)',borderRadius:5,padding:'2px 8px',color:'#f59e0b',fontFamily:'monospace',fontSize:9,cursor:'pointer'}}>
                  📋
                </button>
              </div>
            </div>
          )}
        </div>

        {/* Bestehende Links */}
        {shares.length > 0 && (
          <div>
            <div style={{color:'rgba(255,255,255,0.4)',fontFamily:'monospace',fontSize:10,marginBottom:8,letterSpacing:1}}>AKTIVE LINKS</div>
            {shares.map(s => (
              <div key={s.id} style={{padding:'10px 12px',background:'rgba(255,255,255,0.04)',border:'1px solid rgba(255,255,255,0.08)',borderRadius:8,marginBottom:8}}>
                <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:4}}>
                  <div style={{color:'rgba(255,255,255,0.6)',fontFamily:'monospace',fontSize:11}}>
                    {s.label || '—'} <span style={{color:'#f59e0b',fontSize:9}}>🔒</span>
                  </div>
                  <div style={{display:'flex',gap:6}}>
                    <button onClick={()=>copyLink(s.token)}
                      style={{background:'rgba(74,222,128,0.1)',border:'1px solid rgba(74,222,128,0.3)',borderRadius:5,padding:'3px 8px',color:'#4ade80',fontFamily:'monospace',fontSize:9,cursor:'pointer'}}>
                      📋 Kopieren
                    </button>
                    <button onClick={()=>deleteShare(s.id)}
                      style={{background:'rgba(248,113,113,0.1)',border:'1px solid rgba(248,113,113,0.3)',borderRadius:5,padding:'3px 8px',color:'#f87171',fontFamily:'monospace',fontSize:9,cursor:'pointer'}}>
                      ✕
                    </button>
                  </div>
                </div>
                <div style={{color:'rgba(255,255,255,0.3)',fontFamily:'monospace',fontSize:9}}>
                  Ablauf: {fmtExp(s.expires_at)} · {s.download_count} Abrufe
                </div>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

// ── Share Modal ───────────────────────────────────────────────────────────────
function ShareModal({ item, type, onClose, toast }) {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [shares,   setShares]   = useState([]);
  const base = type==='folder' ? `/tools/dateien/folders/${item.id}` : `/tools/dateien/${item.id}`;
  useEffect(() => { api(`${base}/shares`).then(setShares).catch(()=>{}); }, [base]);

  const share = async () => {
    if (!username.trim()) return;
    try {
      await api(`${base}/share`, { body: { username: username.trim(), password: password.trim() || undefined } });
      toast('Geteilt ✓'); setUsername(''); setPassword('');
      api(`${base}/shares`).then(setShares);
    } catch(e) { toast(e.message,'error'); }
  };
  const unshare = async uid => {
    try { await api(`${base}/share/${uid}`,{method:'DELETE'}); setShares(p=>p.filter(s=>s.id!==uid)); toast('Freigabe entfernt'); }
    catch(e) { toast(e.message,'error'); }
  };
  const isMobile = window.innerWidth<768;
  return (
    <div style={{position:'fixed',inset:0,background:'rgba(0,0,0,0.8)',zIndex:6000,
      display:'flex',alignItems:isMobile?'flex-end':'center',justifyContent:'center',padding:isMobile?0:24}}
      onClick={e=>e.target===e.currentTarget&&onClose()}>
      <div style={{background:'#1a1a1e',borderRadius:isMobile?'16px 16px 0 0':16,
        width:'100%',maxWidth:440,padding:'20px 20px 28px',border:'1px solid rgba(255,255,255,0.12)'}}>
        {isMobile&&<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:14}}>
          <div style={{color:'#fff',fontFamily:"'Space Mono',monospace",fontSize:13,fontWeight:700}}>
            {type==='folder'?'📁':'📎'} {item.name||item.originalname}
          </div>
          <button onClick={onClose} style={{background:'transparent',border:'none',color:'rgba(255,255,255,0.4)',cursor:'pointer',fontSize:18,padding:'0 4px'}}>✕</button>
        </div>

        {/* Teilen-Formular */}
        {type==='file' && (
          <div style={{marginBottom:10}}>
            <div style={{display:'flex',gap:8,marginBottom:6}}>
              <input value={username} onChange={e=>setUsername(e.target.value)} onKeyDown={e=>e.key==='Enter'&&share()}
                placeholder="Benutzername" autoCapitalize="none" style={{...S.inp,flex:1,fontSize:15}}/>
              <button onClick={share} style={S.btn('#4ecdc4')}>Teilen</button>
            </div>
            <input value={password} onChange={e=>setPassword(e.target.value)}
              placeholder="Passwort (optional)" type="text" autoCapitalize="none"
              style={{...S.inp,fontSize:13,padding:'7px 10px'}}/>
            {password && <div style={{color:'rgba(255,230,109,0.6)',fontSize:9,fontFamily:'monospace',marginTop:4}}>
              ⚠ Teile das Passwort separat mit dem Empfänger
            </div>}
          </div>
        )}
        {type==='folder' && (
          <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,fontSize:15}}/>
            <button onClick={share} style={S.btn('#4ecdc4')}>Teilen</button>
          </div>
        )}

        {/* Bestehende Shares */}
        {shares.length>0 && (
          <div>
            <div style={{...S.head,marginBottom:6,marginTop:4}}>GETEILT MIT</div>
            {shares.map(s=>(
              <div key={s.id} style={{display:'flex',justifyContent:'space-between',alignItems:'center',
                padding:'8px 0',borderBottom:'1px solid rgba(255,255,255,0.05)'}}>
                <div>
                  <div style={{display:'flex',alignItems:'center',gap:6}}>
                    <span style={{color:'rgba(255,255,255,0.8)',fontFamily:'monospace',fontSize:13}}>{s.username}</span>
                    {s.has_password ? <span title="Passwortgeschützt" style={{fontSize:10}}>🔑</span> : null}
                  </div>
                  <div style={{color:'rgba(255,255,255,0.3)',fontFamily:'monospace',fontSize:10,marginTop:2}}>
                    {s.shared_at && `geteilt ${fmtDate(s.shared_at)}`}
                    {s.accessed_at
                      ? <span style={{color:'rgba(78,205,196,0.7)',marginLeft:8}}>✓ zugegriffen {fmtDate(s.accessed_at)}</span>
                      : <span style={{color:'rgba(255,255,255,0.25)',marginLeft:8}}>○ noch nicht geöffnet</span>
                    }
                  </div>
                </div>
                <button onClick={()=>unshare(s.id)} style={S.btn('#ff6b9d',true)}>✕</button>
              </div>
            ))}
          </div>
        )}
        {shares.length===0 && <div style={{color:'rgba(255,255,255,0.3)',fontFamily:'monospace',fontSize:11,marginTop:4}}>Noch mit niemandem geteilt.</div>}
      </div>
    </div>
  );
}

// ── Haupt-Komponente ──────────────────────────────────────────────────────────
// ── Passwort-Prompt Modal (ersetzt window.prompt – kein 1Password-Trigger) ────
function PasswordPromptModal({ filename, onSubmit, onCancel }) {
  const [pw, setPw] = useState('');
  const isMobile = window.innerWidth < 768;
  return (
    <div style={{position:'fixed',inset:0,background:'rgba(0,0,0,0.8)',zIndex:7000,
      display:'flex',alignItems:isMobile?'flex-end':'center',justifyContent:'center',padding:isMobile?0:24}}
      onClick={e=>e.target===e.currentTarget&&onCancel()}>
      <div style={{background:'#1a1a1e',borderRadius:isMobile?'16px 16px 0 0':16,
        width:'100%',maxWidth:400,padding:'22px 20px 28px',border:'1px solid rgba(255,255,255,0.12)'}}>
        {isMobile&&<div style={{width:36,height:4,background:'rgba(255,255,255,0.15)',borderRadius:2,margin:'0 auto 14px'}}/>}
        <div style={{color:'#fff',fontFamily:"'Space Mono',monospace",fontSize:13,fontWeight:700,marginBottom:6}}>
          🔒 Passwortgeschützte Datei
        </div>
        <div style={{color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:11,marginBottom:14,lineHeight:1.6}}>
          {filename}
        </div>
        <input
          autoFocus
          type="text"
          autoComplete="off"
          data-1p-ignore
          data-lpignore="true"
          value={pw}
          onChange={e=>setPw(e.target.value)}
          onKeyDown={e=>{ if(e.key==='Enter'&&pw)onSubmit(pw); if(e.key==='Escape')onCancel(); }}
          placeholder="Passwort eingeben…"
          style={{...S.inp,marginBottom:12,fontSize:14}}
        />
        <div style={{display:'flex',gap:8}}>
          <button onClick={()=>{if(pw)onSubmit(pw);}} disabled={!pw}
            style={{...S.btn('#4ecdc4'),flex:1,textAlign:'center',padding:'10px 0',opacity:pw?1:0.4}}>
            ↓ Herunterladen
          </button>
          <button onClick={onCancel} style={{...S.btn('#ff6b9d',true),padding:'0 16px'}}>Abbrechen</button>
        </div>
      </div>
    </div>
  );
}


// ── Upload-Ordner & Share-Verwaltung ─────────────────────────────────────────
function UploadShareManager({ toast }) {
  const [shares,      setShares]      = useState([]);
  const [folder,      setFolder]      = useState(null);
  const [logs,        setLogs]        = useState([]);
  const [showCreate,  setShowCreate]  = useState(false);
  const [showLogs,    setShowLogs]    = useState(false);
  const [form,        setForm]        = useState({ password:'', expires_hours:1, max_size_mb:10 });
  const [busy,        setBusy]        = useState(false);
  const [copied,      setCopied]      = useState(null);
  const [sharePws,    setSharePws]    = useState({}); // {shareId: password} für Passwort-Kopieren

  const load = () => api('/upload-shares').then(d=>{ setShares(d.shares||[]); setFolder(d.folder); }).catch(()=>{});
  useEffect(()=>{ load(); },[]);

  const genPw = () => {
    const chars='ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789!@#$%';
    setForm(p=>({...p, password: Array.from({length:12},()=>chars[Math.floor(Math.random()*chars.length)]).join('')}));
  };

  const create = async () => {
    if (!form.password.trim()) { toast('Passwort erforderlich','error'); return; }
    setBusy(true);
    try {
      const r = await api('/upload-shares', { body: form });
      setSharePws(p=>({...p, [r.id]: form.password}));
      toast('Upload-Link erstellt ✓'); setShowCreate(false); setForm({password:'',expires_hours:1,max_size_mb:10}); load();
    } catch(e) { toast(e.message,'error'); }
    setBusy(false);
  };

  const deactivate = async id => {
    await api(`/upload-shares/${id}`, { method:'DELETE' });
    load(); toast('Link deaktiviert');
  };
  const removeShare = async id => {
    await api(`/upload-shares/${id}/remove`, { method:'DELETE' });
    setShares(p => p.filter(s => s.id !== id));
    toast('Entfernt');
  };

  const shorten = async (shareId, token) => {
    setShortening(shareId);
    const url = `${window.location.origin}/u/${token}`;
    try {
      // is.gd – kostenloser URL-Shortener, kein API-Key nötig
      const r = await fetch(`https://is.gd/create.php?format=simple&url=${encodeURIComponent(url)}`);
      const short = await r.text();
      if (short.startsWith('http')) {
        setShortUrls(p=>({...p,[shareId]:short.trim()}));
        navigator.clipboard?.writeText(short.trim()).catch(()=>{});
        toast('Kurz-URL erstellt & kopiert ✓');
      } else {
        toast('Shortener nicht verfügbar','error');
      }
    } catch { toast('Shortener nicht erreichbar','error'); }
    setShortening(null);
  };

  const copyLink = (token) => {
    const url = `${window.location.origin}/u/${token}`;
    if (navigator.clipboard) {
      navigator.clipboard.writeText(url).catch(() => {
        const ta = document.createElement('textarea');
        ta.value = url; ta.style.cssText='position:fixed;opacity:0.01';
        document.body.appendChild(ta); ta.focus(); ta.select();
        try { document.execCommand('copy'); } catch {}
        document.body.removeChild(ta);
      });
    }
    setCopied(token); setTimeout(()=>setCopied(null), 2500);
  };

  const loadLogs = () => {
    api('/upload-shares/logs').then(setLogs).catch(()=>{});
    setShowLogs(true);
  };

  const fmtDate = d => d ? new Date(d).toLocaleString('de-DE',{timeZone:'Europe/Berlin',day:'2-digit',month:'2-digit',year:'numeric',hour:'2-digit',minute:'2-digit'}) : '–';
  const fmtSize = b => b>1024*1024 ? (b/1024/1024).toFixed(1)+' MB' : (b/1024).toFixed(0)+' KB';

  const DURATION_OPTS = [
    [1,'1 Stunde'],[2,'2 Stunden'],[6,'6 Stunden'],[12,'12 Stunden'],
    [24,'1 Tag'],[48,'2 Tage'],[72,'3 Tage'],[168,'1 Woche'],[336,'2 Wochen'],
  ];
  const SIZE_OPTS = [1,2,5,10,20,50,100,250];

  return (
    <div>
      <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:12,flexWrap:'wrap',gap:8}}>
        <div>
          <div style={{color:'#fff',fontFamily:'monospace',fontSize:14,fontWeight:700}}>
            📤 Upload-Freigabe
          </div>
          {folder && <div style={{color:'rgba(255,255,255,0.35)',fontFamily:'monospace',fontSize:10,marginTop:2}}>
            Dateien landen in: {folderIcon(folder)} {folder.name}
          </div>}
        </div>
        <div style={{display:'flex',gap:6}}>
          <button onClick={loadLogs} style={{
            background:'rgba(255,255,255,0.06)',border:'1px solid rgba(255,255,255,0.15)',
            borderRadius:6,color:'rgba(255,255,255,0.6)',cursor:'pointer',
            fontFamily:'monospace',fontSize:11,padding:'6px 12px',whiteSpace:'nowrap'}}>
            📋 Log
          </button>
          <button onClick={()=>setShowCreate(p=>!p)} style={{...S.btn('#4ecdc4'),padding:'7px 14px',fontSize:12}}>
            {showCreate?'Abbrechen':'+ Link erstellen'}
          </button>
        </div>
      </div>

      {/* Erstellen-Formular */}
      {showCreate && (
        <div style={{...S.card,marginBottom:12}}>
          <div style={{...S.head,marginBottom:12}}>UPLOAD-LINK KONFIGURIEREN</div>
          <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:8,marginBottom:8}}>
            <div>
              <div style={{...S.head,fontSize:9,marginBottom:4}}>GÜLTIGKEITSDAUER</div>
              <select value={form.expires_hours} onChange={e=>setForm(p=>({...p,expires_hours:Number(e.target.value)}))}
                style={{...S.inp,width:'100%',cursor:'pointer'}}>
                {DURATION_OPTS.map(([v,l])=><option key={v} value={v}>{l}</option>)}
              </select>
            </div>
            <div>
              <div style={{...S.head,fontSize:9,marginBottom:4}}>MAX. DATEIGRÖSSE</div>
              <select value={form.max_size_mb} onChange={e=>setForm(p=>({...p,max_size_mb:Number(e.target.value)}))}
                style={{...S.inp,width:'100%',cursor:'pointer'}}>
                {SIZE_OPTS.map(v=><option key={v} value={v}>{v} MB</option>)}
              </select>
            </div>
          </div>
          <div style={{marginBottom:12}}>
            <div style={{...S.head,fontSize:9,marginBottom:4}}>PASSWORT</div>
            <div style={{display:'flex',gap:6}}>
              <input value={form.password} onChange={e=>setForm(p=>({...p,password:e.target.value}))}
                placeholder="Passwort vergeben" style={{...S.inp,flex:1,fontFamily:'monospace'}}/>
              <button onClick={genPw} style={{...S.btn('#ffe66d',true),fontSize:11,padding:'0 12px',whiteSpace:'nowrap'}}>
                ⚡ Generieren
              </button>
            </div>
            {form.password && <div style={{color:'rgba(255,255,255,0.35)',fontFamily:'monospace',fontSize:11,marginTop:4}}>
              Passwort: <strong style={{color:'#ffe66d'}}>{form.password}</strong> – notiere es jetzt
            </div>}
          </div>
          <button onClick={create} disabled={busy} style={{...S.btn('#4ecdc4'),width:'100%',textAlign:'center',padding:'10px 0',opacity:busy?0.5:1}}>
            {busy?'…':'🔗 Link erstellen'}
          </button>
        </div>
      )}

      {/* Aktive Links */}
      {shares.length===0 && !showCreate && (
        <div style={{...S.card,textAlign:'center',padding:32}}>
          <div style={{fontSize:28,marginBottom:8}}>📤</div>
          <div style={{color:'rgba(255,255,255,0.35)',fontFamily:'monospace',fontSize:12}}>
            Noch kein Upload-Link. Erstelle einen Link um anderen das Hochladen zu erlauben.
          </div>
        </div>
      )}
      {shares.map(s => {
        const expired = new Date(s.expires_at) < new Date();
        return (
          <div key={s.id} style={{...S.card,marginBottom:8,opacity:(!s.is_active||expired)?0.5:1}}>
            <div style={{display:'flex',alignItems:'center',gap:10,flexWrap:'wrap'}}>
              <div style={{flex:1,minWidth:0}}>
                <div style={{display:'flex',alignItems:'center',gap:6,flexWrap:'wrap'}}>
                  <span style={{color:!s.is_active?'#ff6b9d':expired?'#ffe66d':'#4ecdc4',fontFamily:'monospace',fontSize:11,
                    border:`1px solid currentColor`,borderRadius:4,padding:'1px 6px',flexShrink:0}}>
                    {!s.is_active?(s.deactivated_reason==='too_many_attempts'?'⚠ Gesperrt (Fehlversuche)':'Deaktiviert'):expired?'Abgelaufen':'Aktiv'}
                  </span>
                  <span style={{color:'rgba(255,255,255,0.4)',fontFamily:'monospace',fontSize:10}}>
                    bis {fmtDate(s.expires_at)} · max {s.max_size_mb} MB/Datei · {s.upload_count||0} Upload(s)
                  </span>
                </div>
                <div style={{color:'rgba(255,255,255,0.25)',fontFamily:'monospace',fontSize:10,marginTop:3,
                  overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
                  /u/{s.token}
                </div>
              </div>
              <div style={{display:'flex',gap:5,flexShrink:0}}>
                {!!s.is_active && !expired && (
                  <>
                  <button onClick={()=>copyLink(s.token)}
                    style={{...S.btn(copied===s.token?'#4ecdc4':'#ffe66d',copied!==s.token),fontSize:10,padding:'4px 10px'}}>
                    {copied===s.token?'✓ Kopiert':'📋 Link'}
                  </button>
                  {sharePws[s.id] && (
                    <button onClick={()=>{ navigator.clipboard?.writeText(sharePws[s.id]).then(()=>toast('Passwort kopiert ✓')).catch(()=>toast(sharePws[s.id])); }}
                      style={{...S.btn('#ffe66d',true),fontSize:10,padding:'4px 10px'}}>🔑 PW</button>
                  )}

                  </>
                )}
                {!!s.is_active && (
                  <button onClick={()=>deactivate(s.id)} style={{...S.btn('#ff6b9d',true),fontSize:10,padding:'4px 10px'}}>Deaktivieren</button>
                )}
                {!s.is_active && (
                  <button onClick={()=>removeShare(s.id)} style={{...S.btn('#ff6b9d',true),fontSize:10,padding:'4px 10px'}}>✕ Entfernen</button>
                )}
              </div>
            </div>
          </div>
        );
      })}

      {/* Log-Ansicht */}
      {showLogs && (
        <div style={{marginTop:12,background:'#131316',border:'1px solid rgba(255,255,255,0.08)',borderRadius:10,padding:'12px 14px'}}>
          <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:10}}>
            <div style={{...S.head,marginBottom:0}}>UPLOAD-PROTOKOLL</div>
            <button onClick={()=>setShowLogs(false)} style={{background:'transparent',border:'none',color:'rgba(255,255,255,0.4)',cursor:'pointer',fontSize:16}}>✕</button>
          </div>
          {logs.length===0
            ? <div style={{color:'rgba(255,255,255,0.35)',fontFamily:'monospace',fontSize:11}}>Noch keine Uploads über Freigabe-Links.</div>
            : logs.map(l=>(
              <div key={l.id} style={{display:'flex',gap:10,padding:'7px 0',borderBottom:'1px solid rgba(255,255,255,0.05)'}}>
                <span style={{fontSize:14,flexShrink:0}}>📄</span>
                <div style={{flex:1,minWidth:0}}>
                  <div style={{color:'#fff',fontFamily:'monospace',fontSize:12,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{l.originalname}</div>
                  <div style={{color:'rgba(255,255,255,0.35)',fontFamily:'monospace',fontSize:10}}>{fmtDate(l.uploaded_at)} · {fmtSize(l.size)}</div>
                </div>
              </div>
            ))
          }
        </div>
      )}
    </div>
  );
}


function folderIcon(folder) {
  if (folder?.is_upload_folder) return '📤';
  if (folder?.name === '3D-Modelle' || folder?.name?.startsWith('3D')) return '📦';
  return '📁';
}

export default function Dateien({ toast, mobile }) {
  const [data,       setData]       = useState({own:[],shared:[],sharedByMe:[]});
  const [folders,    setFolders]    = useState({own:[],shared:[],sharedByMe:[]});
  const [loading,    setLoading]    = useState(true);
  const [currentFolderId, setCurrentFolderId] = useState(null);
  const [folderPath, setFolderPath] = useState([]);
  const [tab,        setTab]        = useState('own');
  const [search,     setSearch]     = useState('');
  const [shareItem,  setShareItem]  = useState(null);
  const [publicShareItem, setPublicShareItem] = useState(null);
  const [publicShares,    setPublicShares]    = useState([]);
  const [showPublicLinks, setShowPublicLinks] = useState(false);
  const [sharePws,        setSharePws]        = useState({}); // {token: plaintext_pw}
  const [pwPrompt,   setPwPrompt]   = useState(null); // {file}
  const [uploading,  setUploading]  = useState(false);
  const [dragOver,   setDragOver]   = useState(false);
  const [newFolder,  setNewFolder]  = useState(false);
  const [folderName, setFolderName] = useState('');
  const [storage,    setStorage]    = useState(null);
  const fileRef = useRef(null);
  const { confirm, ConfirmDialog } = useConfirm();

  const load = useCallback(() => {
    setLoading(true);
    api('/tools/dateien/public-shares').then(d => setPublicShares(d.shares||[])).catch(()=>{});
    const fq = currentFolderId ? `?folder_id=${currentFolderId}` : '';
    const pq = currentFolderId ? `?parent_id=${currentFolderId}` : '';
    Promise.all([api(`/tools/dateien${fq}`), api(`/tools/dateien/folders${pq}`)])
      .then(([d,f]) => {
        setData({own:d.own||[],shared:d.shared||[],sharedByMe:d.sharedByMe||[]});
        setFolders({own:f.own||[],shared:f.shared||[],sharedByMe:f.sharedByMe||[]});
      })
      .catch(e=>toast(e.message,'error'))
      .finally(()=>setLoading(false));
    api('/tools/dateien/storage').then(setStorage).catch(()=>{});
  }, [currentFolderId]);

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

  // "3D-Modelle" Ordner beim ersten Laden automatisch anlegen
  useEffect(()=>{
    api('/tools/dateien/ensure-folder',{body:{name:'3D-Modelle'}}).catch(()=>{});
  },[]);

  const doUpload = async file => {
    if (!file) return;
    setUploading(true);
    try {
      const form = new FormData();
      form.append('file', file);
      if (currentFolderId) form.append('folder_id', currentFolderId);
      await api('/tools/dateien',{method:'POST',body:form,isFile:true});
      toast(`${file.name} hochgeladen ✓`); load();
    } catch(e) { toast(e.message,'error'); } finally { setUploading(false); }
  };

  const onFileInput = e => { doUpload(e.target.files?.[0]); e.target.value=''; };
  const onDrop = e => { e.preventDefault(); setDragOver(false); doUpload(e.dataTransfer.files?.[0]); };

  const download = async (file, pw) => {
    try {
      const url = `/api/tools/dateien/${file.id}/download${pw ? `?password=${encodeURIComponent(pw)}` : ''}`;
      const res = await fetch(url, { headers:{Authorization:`Bearer ${localStorage.getItem('sk_token')}`} });
      if (!res.ok) {
        const err = await res.json().catch(()=>({error:'Fehler'}));
        if (err.passwordRequired) {
          setPwPrompt(file);
          return;
        }
        if (pw && res.status===403) { toast('Falsches Passwort', 'error'); return; }
        toast(err.error,'error'); return;
      }
      const blob = await res.blob();
      const a = Object.assign(document.createElement('a'), {
        href: URL.createObjectURL(blob), download: file.originalname,
      });
      document.body.appendChild(a); a.click(); document.body.removeChild(a);
      setTimeout(()=>URL.revokeObjectURL(a.href),1000);
    } catch(e){toast(e.message,'error');}
  };

  const delFile = async file => {
    if (!await confirm(`"${file.originalname}" löschen?`)) return;
    try{await api(`/tools/dateien/${file.id}`,{method:'DELETE'});toast('Gelöscht');load();}
    catch(e){toast(e.message,'error');}
  };

  const delFolder = async folder => {
    if (!await confirm(`Ordner "${folder.name}" und alle Inhalte löschen?`)) return;
    try{await api(`/tools/dateien/folders/${folder.id}`,{method:'DELETE'});toast('Gelöscht');load();}
    catch(e){toast(e.message,'error');}
  };

  const createFolder = async () => {
    if (!folderName.trim()) return;
    try {
      const body={name:folderName.trim()};
      if (currentFolderId) body.parent_id=currentFolderId;
      await api('/tools/dateien/folders',{body});
      toast('Ordner erstellt'); setFolderName(''); setNewFolder(false); load();
    } catch(e){toast(e.message,'error');}
  };

  const enterFolder = (folder, isShared=false) => {
    setCurrentFolderId(folder.id);
    setFolderPath(p=>[...p,{id:folder.id,name:folder.name,isShared}]);
    setSearch('');
  };

  const navigateTo = idx => {
    if (idx<0){setCurrentFolderId(null);setFolderPath([]);}
    else{const t=folderPath[idx];setCurrentFolderId(t.id);setFolderPath(p=>p.slice(0,idx+1));}
    setSearch('');
  };

  const sq = search.toLowerCase();
  const getFolders = () => tab==='sharedByMe'?(folders.sharedByMe||[]):tab==='shared'?(folders.shared||[]):folders.own;
  const getFiles   = () => tab==='sharedByMe'?(data.sharedByMe||[]):tab==='shared'?data.shared:data.own;
  const filtFolders = sq ? getFolders().filter(f=>f.name.toLowerCase().includes(sq)) : getFolders();
  const filtFiles   = sq ? getFiles().filter(f=>f.originalname.toLowerCase().includes(sq)) : getFiles();

  const totalSize = data.own.reduce((s,f)=>s+f.size,0);
  const inSharedFolder = folderPath.some(p=>p.isShared);
  const isOwn = tab==='own' && !inSharedFolder;
  const sharedCnt  = data.shared.length + (folders.shared||[]).length;
  const byMeCnt    = (data.sharedByMe||[]).length + (folders.sharedByMe||[]).length;

  return (
    <div style={{padding:mobile?'14px 14px 90px':'36px 44px',maxWidth:960}}>
      <ConfirmDialog/>
      {/* ── Speicherplatz ─────────────────────────────────────────────────── */}
      {storage && (
        <div style={{marginBottom:14,padding:'10px 12px',background:'rgba(255,255,255,0.02)',
          border:'1px solid rgba(255,255,255,0.06)',borderRadius:8}}>
          <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',
            color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:10}}>
            <span>{fmtSize(storage.used)} / {storage.totalLimitMb} MB belegt</span>
            <span style={{fontSize:9,color:'rgba(255,255,255,0.25)'}}>max. {storage.maxSizeMb} MB pro Datei · {storage.count} Dateien</span>
          </div>
          <div style={{height:3,borderRadius:3,background:'rgba(255,255,255,0.06)',overflow:'hidden',marginTop:7}}>
            <div style={{
              height:'100%', borderRadius:3,
              width:`${Math.min(100,(storage.used/(storage.totalLimitMb*1024*1024))*100)}%`,
              background: storage.used/(storage.totalLimitMb*1024*1024) > 0.85 ? '#ff6b9d' :
                          storage.used/(storage.totalLimitMb*1024*1024) > 0.6  ? '#ffe66d' : '#4ecdc4',
              transition:'width 0.4s',
            }}/>
          </div>
        </div>
      )}
      {shareItem && <ShareModal item={shareItem.item} type={shareItem.type} onClose={()=>{setShareItem(null);load();}} toast={toast}/>}
      {publicShareItem && <PublicShareModal item={publicShareItem.item} itemType={publicShareItem.type} onClose={()=>{setPublicShareItem(null);api('/tools/dateien/public-shares').then(d=>setPublicShares(d.shares||[])).catch(()=>{});}} onShareCreated={(token,pw)=>setSharePws(p=>({...p,[token]:pw}))} toast={toast}/>}

      {/* ── Aktive öffentliche Links ──────────────────────────────────────── */}
      {publicShares.length > 0 && tab === 'own' && (
        <div style={{marginTop:24,padding:'14px 16px',background:'rgba(255,255,255,0.02)',border:'1px solid rgba(255,255,255,0.07)',borderRadius:10}}>
          <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:showPublicLinks?12:0,cursor:'pointer'}}
            onClick={()=>setShowPublicLinks(v=>!v)}>
            <div style={{display:'flex',alignItems:'center',gap:8}}>
              <span style={{color:'#4ade80',fontSize:14}}>🔗</span>
              <span style={{color:'rgba(255,255,255,0.7)',fontFamily:'monospace',fontSize:12}}>
                Aktive öffentliche Links
              </span>
              <span style={{background:'rgba(74,222,128,0.15)',border:'1px solid rgba(74,222,128,0.3)',borderRadius:10,padding:'1px 7px',color:'#4ade80',fontFamily:'monospace',fontSize:10}}>
                {publicShares.length}
              </span>
            </div>
            <span style={{color:'rgba(255,255,255,0.3)',fontSize:11}}>{showPublicLinks ? '▲' : '▼'}</span>
          </div>
          {showPublicLinks && publicShares.map(s => {
            const name = s.file_name || s.folder_name || s.label || '—';
            const isExp = s.expires_at && s.expires_at < Math.floor(Date.now()/1000);
            const fmtExp = exp => {
              if (!exp) return '∞';
              const d = new Date(exp*1000);
              return d.toLocaleDateString('de-DE')+' '+d.toLocaleTimeString('de-DE',{hour:'2-digit',minute:'2-digit'});
            };
            return (
              <div key={s.id} style={{display:'flex',alignItems:'center',gap:10,padding:'8px 10px',
                background:'rgba(255,255,255,0.03)',border:`1px solid ${isExp?'rgba(248,113,113,0.3)':'rgba(255,255,255,0.07)'}`,
                borderRadius:7,marginBottom:6}}>
                <span style={{fontSize:14}}>{s.file_id ? '📄' : '📁'}</span>
                <div style={{flex:1,minWidth:0}}>
                  <div style={{color:'rgba(255,255,255,0.7)',fontFamily:'monospace',fontSize:11,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
                    {name}
                    {s.label && s.label !== name && <span style={{color:'rgba(255,255,255,0.35)',marginLeft:6}}>({s.label})</span>}
                  </div>
                  <div style={{color:isExp?'#f87171':'rgba(255,255,255,0.3)',fontFamily:'monospace',fontSize:9}}>
                    {isExp?'⚠ Abgelaufen':'Ablauf: '}{!isExp&&fmtExp(s.expires_at)} · {s.download_count} Abrufe · 🔒
                  </div>
                </div>
                <button onClick={()=>{
                  navigator.clipboard?.writeText(window.location.origin+'/s/'+s.token)
                    .then(()=>toast('Link kopiert ✓')).catch(()=>toast(window.location.origin+'/s/'+s.token));
                }}
                  style={{background:'rgba(74,222,128,0.1)',border:'1px solid rgba(74,222,128,0.3)',borderRadius:5,padding:'4px 8px',color:'#4ade80',fontFamily:'monospace',fontSize:9,cursor:'pointer',flexShrink:0}}>
                  📋
                </button>
                {sharePws[s.token] && (
                  <button onClick={()=>{
                    navigator.clipboard?.writeText(sharePws[s.token])
                      .then(()=>toast('Passwort kopiert ✓')).catch(()=>toast(sharePws[s.token]));
                  }}
                    style={{background:'rgba(245,158,11,0.1)',border:'1px solid rgba(245,158,11,0.3)',borderRadius:5,padding:'4px 8px',color:'#f59e0b',fontFamily:'monospace',fontSize:9,cursor:'pointer',flexShrink:0}}
                    title={sharePws[s.token]}>
                    🔑
                  </button>
                )}
                <button onClick={async()=>{
                  await api(`/tools/dateien/public-shares/${s.id}`,{method:'DELETE'});
                  setPublicShares(p=>p.filter(x=>x.id!==s.id));
                  toast('Link gelöscht');
                }}
                  style={{background:'rgba(248,113,113,0.1)',border:'1px solid rgba(248,113,113,0.3)',borderRadius:5,padding:'4px 8px',color:'#f87171',fontFamily:'monospace',fontSize:9,cursor:'pointer',flexShrink:0}}>
                  ✕
                </button>
              </div>
            );
          })}
        </div>
      )}
      {pwPrompt && <PasswordPromptModal
        filename={pwPrompt.originalname}
        onSubmit={pw=>{ setPwPrompt(null); download(pwPrompt, pw); }}
        onCancel={()=>setPwPrompt(null)}
      />}
      <input ref={fileRef} type="file" onChange={onFileInput} style={{display:'none'}}/>

      {/* ── Seitentitel ──────────────────────────────────────────────────── */}
      <div style={{marginBottom:16,display:'flex',alignItems:'flex-start',justifyContent:'space-between'}}>
        <div>
          <h1 style={{color:'#fff',fontFamily:"'Space Mono',monospace",fontSize:mobile?18:22,margin:0}}>Dateien</h1>
          <div style={{color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:10,marginTop:3}}>
            {data.own.length} Dateien · {fmtSize(totalSize)}
          </div>
        </div>
        <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',marginTop:2}}>↺</button>
      </div>
      {/* ── Tabs + Neu-Ordner (überall gleich) ───────────────────────────── */}
      <div style={{display:'flex',gap:6,marginBottom:12,alignItems:'center',flexWrap:'wrap'}}>
        {[
          ['own','Dateien', null],
          ['shared','Geteilt mit mir', sharedCnt||null],
          ['sharedByMe','Geteilt von mir', byMeCnt||null],
          ['upload','📤 Upload-Freigabe', null],
        ].map(([k,l,cnt])=>(
          <button key={k} onClick={()=>{setTab(k);setSearch('');setCurrentFolderId(null);setFolderPath([]);}} style={{
            padding:'6px 14px',borderRadius:20,fontFamily:'monospace',fontSize:11,cursor:'pointer',
            border:`1px solid ${tab===k?'rgba(78,205,196,0.5)':'rgba(255,255,255,0.12)'}`,
            background:tab===k?'rgba(78,205,196,0.12)':'transparent',
            color:tab===k?'#4ecdc4':'rgba(255,255,255,0.55)',
          }}>{l}{cnt?` (${cnt})`:''}</button>
        ))}
        {/* Ordner-Button – immer am Ende der Tab-Reihe wenn own-Tab aktiv */}
        {isOwn && !newFolder && (
          <button onClick={()=>setNewFolder(true)} style={{
            marginLeft:'auto',padding:'6px 12px',borderRadius:20,fontFamily:'monospace',fontSize:11,
            cursor:'pointer',border:'1px solid rgba(255,255,255,0.15)',
            background:'rgba(255,255,255,0.05)',color:'rgba(255,255,255,0.65)',
            display:'flex',alignItems:'center',gap:5,
          }}>📁 + Ordner</button>
        )}
      </div>

      {/* ── Breadcrumb ────────────────────────────────────────────────────── */}
      {folderPath.length>0 && (
        <div style={{display:'flex',alignItems:'center',gap:4,marginBottom:12,flexWrap:'wrap'}}>
          <button onClick={()=>navigateTo(-1)} style={{background:'transparent',border:'none',
            color:'rgba(255,255,255,0.5)',cursor:'pointer',fontFamily:'monospace',fontSize:11,padding:'2px 6px'}}>
            Dateien
          </button>
          {folderPath.map((p,i)=>(
            <span key={p.id} style={{display:'flex',alignItems:'center',gap:4}}>
              <ChevronIcon size={11} color="rgba(255,255,255,0.25)" dir="right"/>
              <button onClick={()=>navigateTo(i)} style={{
                background:i===folderPath.length-1?'rgba(78,205,196,0.1)':'transparent',
                border:i===folderPath.length-1?'1px solid rgba(78,205,196,0.2)':'none',
                borderRadius:6,color:i===folderPath.length-1?'#4ecdc4':'rgba(255,255,255,0.5)',
                cursor:'pointer',fontFamily:'monospace',fontSize:11,padding:'2px 8px'}}>
                {p.name}
              </button>
            </span>
          ))}
        </div>
      )}

      {/* ── Neuer Ordner Formular ─────────────────────────────────────────── */}
      {newFolder && (
        <div style={{...S.card,marginBottom:10,display:'flex',gap:8,alignItems:'center'}}>
          <span style={{fontSize:18}}>📁</span>
          <input value={folderName} onChange={e=>setFolderName(e.target.value)}
            onKeyDown={e=>{if(e.key==='Enter')createFolder();if(e.key==='Escape'){setNewFolder(false);setFolderName('');}}}
            placeholder="Ordnername…" autoFocus style={{...S.inp,flex:1,fontSize:15}}/>
          <button onClick={createFolder} style={S.btn('#4ecdc4')}>✓</button>
          <button onClick={()=>{setNewFolder(false);setFolderName('');}} style={S.btn('#ff6b9d',true)}>✕</button>
        </div>
      )}

      {/* ── Upload-Ordner Tab ─────────────────────────────────────────────── */}
      {tab==='upload' && <UploadShareManager toast={toast}/>}

      {/* ── Suche + Upload-Zone ───────────────────────────────────────────── */}
      {tab!=='upload' && <div style={{display:mobile?'block':'flex',gap:8,marginBottom:12}}>
        <div style={{position:'relative',flex:1,marginBottom:mobile?8:0}}>
          <span style={{position:'absolute',left:12,top:'50%',transform:'translateY(-50%)'}}>
            <SearchIcon size={14} color="rgba(255,255,255,0.3)"/>
          </span>
          <input value={search} onChange={e=>setSearch(e.target.value)} placeholder="Suchen…"
            style={{...S.inp,paddingLeft:34,fontSize:15}}/>
          {search&&<button onClick={()=>setSearch('')} style={{position:'absolute',right:10,top:'50%',
            transform:'translateY(-50%)',background:'transparent',border:'none',
            color:'rgba(255,255,255,0.3)',cursor:'pointer',fontSize:16}}>✕</button>}
        </div>
        {/* Drop-Zone */}
        <div onDragOver={e=>{e.preventDefault();setDragOver(true);}} onDragLeave={()=>setDragOver(false)}
          onDrop={onDrop} onClick={()=>fileRef.current?.click()}
          style={{
            display:'flex',alignItems:'center',justifyContent:'center',gap:8,
            padding:'0 18px',height:44,borderRadius:10,cursor:'pointer',
            border:`2px dashed ${dragOver?'#4ecdc4':'rgba(255,255,255,0.15)'}`,
            background:dragOver?'rgba(78,205,196,0.08)':'transparent',
            transition:'all 0.15s',flexShrink:0,
            minWidth:mobile?'100%':200,
          }}>
          <UploadIcon size={14} color={dragOver?'#4ecdc4':'rgba(255,255,255,0.4)'}/>
          <span style={{color:dragOver?'#4ecdc4':'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:11}}>
            {uploading?'Hochladen…':dragOver?'Loslassen':mobile?'Datei hochladen':'Hier ablegen oder klicken'}
          </span>
        </div>
      </div>}

      {loading&&tab!=='upload'&&<div style={{color:'rgba(255,255,255,0.4)',fontFamily:'monospace',padding:'8px 0'}}>Lädt…</div>}

      {/* ── Ordner ────────────────────────────────────────────────────────── */}
      {tab!=='upload' && filtFolders.map(folder => {
        const canManage = !folder.owner || tab==='sharedByMe';
        return (
          <div key={folder.id} style={{...S.card,marginBottom:6,padding:'10px 14px',
            display:'flex',alignItems:'center',gap:10}}>
            <span style={{fontSize:22,flexShrink:0}}>{folderIcon(folder)}</span>
            {/* Info – klickbar zum Navigieren */}
            <div style={{flex:1,minWidth:0,cursor:'pointer'}} onClick={()=>enterFolder(folder,!!folder.owner)}>
              <div style={{color:'#fff',fontFamily:'monospace',fontSize:13,fontWeight:700}}>{folder.name}</div>
              <div style={{color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:10,marginTop:2}}>
                {[
                  folder.owner&&tab!=='sharedByMe'?`von ${folder.owner}`:null,
                  folder.subCount>0?`${folder.subCount} Ordner`:null,
                  folder.fileCount>0?`${folder.fileCount} Datei${folder.fileCount!==1?'en':''}`:null,
                  folder.fileCount>0&&folder.totalSize>0?fmtSize(folder.totalSize):null,
                  folder.subCount===0&&folder.fileCount===0?'leer':null,
                  tab==='sharedByMe'&&folder.shared_with_names?`→ ${folder.shared_with_names}`:null,
                ].filter(Boolean).join(' · ')}
              </div>
            </div>
            {/* Aktionen – feste Breite, symmetrisch */}
            <div style={{display:'flex',gap:5,flexShrink:0,alignItems:'center'}}>
              {canManage && (
                <><IconBtn onClick={()=>setShareItem({item:folder,type:'folder'})} color="#ffe66d" title="Teilen" stop>🤝</IconBtn>
                <IconBtn onClick={e=>{e.stopPropagation();setPublicShareItem({item:folder,type:'folder'});}} color="#4ade80" title="Öffentlicher Link" stop>🔗</IconBtn></>
              )}
              {canManage&&tab==='own' && (
                <IconBtn onClick={()=>delFolder(folder)} color="#ff6b9d" title="Löschen" stop>
                  <TrashIcon size={13} color="#ff6b9d"/>
                </IconBtn>
              )}
              <div style={{width:24,display:'flex',alignItems:'center',justifyContent:'center'}}>
                <ChevronIcon size={14} color="rgba(255,255,255,0.3)" dir="right"/>
              </div>
            </div>
          </div>
        );
      })}

      {/* ── Dateien ───────────────────────────────────────────────────────── */}
      {tab!=='upload' && filtFiles.map(file => {
        const canManage = isOwn || tab==='sharedByMe';
        return (
          <div key={file.id} style={{...S.card,marginBottom:6,padding:'10px 14px',
            display:'flex',alignItems:'center',gap:10}}>
            <span style={{fontSize:22,flexShrink:0}}>{extIcon(file.originalname)}</span>
            <div style={{flex:1,minWidth:0}}>
              <div style={{color:'#fff',fontFamily:'monospace',fontSize:13,fontWeight:700,
                overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',display:'flex',alignItems:'center',gap:5}}>
                <span style={{overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{file.originalname}</span>
                {file.has_password ? <span title="Passwortgeschützt" style={{fontSize:11,flexShrink:0}}>🔒</span> : null}
              </div>
              <div style={{color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:10,marginTop:2}}>
                {fmtSize(file.size)} · {fmtDate(file.created_at)}
                {tab==='shared'?` · von ${file.owner}`:''}
                {tab==='sharedByMe'&&file.shared_with_names?(
                  <span>
                    {` · → ${file.shared_with_names}`}
                    {file.accessed_at
                      ? <span style={{color:'rgba(78,205,196,0.8)'}}> · ✓ {fmtDate(file.accessed_at)}</span>
                      : <span style={{color:'rgba(255,255,255,0.25)'}}> · ○ nicht geöffnet</span>
                    }
                  </span>
                ):''}
              </div>
            </div>
            {/* Aktionen – gleiche Breite wie bei Ordnern */}
            <div style={{display:'flex',gap:5,flexShrink:0,alignItems:'center'}}>
              <IconBtn onClick={()=>download(file)} color="#4ecdc4" title="Herunterladen">
                <DownloadIcon size={13} color="#4ecdc4"/>
              </IconBtn>
              {canManage && (
                <><IconBtn onClick={()=>setShareItem({item:file,type:'file'})} color="#ffe66d" title="Teilen">🤝</IconBtn>
                <IconBtn onClick={()=>setPublicShareItem({item:file,type:'file'})} color="#4ade80" title="Öffentlicher Link">🔗</IconBtn></>
              )}
              {isOwn && (
                <IconBtn onClick={()=>delFile(file)} color="#ff6b9d" title="Löschen">
                  <TrashIcon size={13} color="#ff6b9d"/>
                </IconBtn>
              )}
              {/* Platzhalter damit Dateien-Zeile gleich breit wie Ordner-Zeile */}
              <div style={{width:24}}/>
            </div>
          </div>
        );
      })}

      {!loading&&filtFolders.length===0&&filtFiles.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?'Keine Treffer.':tab==='own'?'Noch leer – Datei hochladen oder Ordner anlegen.':tab==='upload'?'':' Noch nichts geteilt.'}
          </div>
        </div>
      )}
    </div>
  );
}

// ── Datei-Einstellungen (Admin) ───────────────────────────────────────────────
export function DateiSettings({ toast }) {
  const [s, setS] = useState({file_max_size_mb:'50',file_total_size_mb:'500',file_allowed_ext:'.pdf,.jpg,.jpeg,.png,.gif,.zip,.txt,.docx,.xlsx,.mp4,.stl,.3mf'});
  const [busy, setBusy] = useState(false);
  useEffect(()=>{api('/tools/dateien/settings').then(d=>setS(prev=>({...prev,...d}))).catch(()=>{});},[]);
  const save = async()=>{
    setBusy(true);
    try{await api('/tools/dateien/settings',{method:'PUT',body:s});toast('Gespeichert ✓');}
    catch(e){toast(e.message,'error');}finally{setBusy(false);}
  };
  return (
    <div>
      <div style={{marginBottom:10}}>
        <label style={{...S.head,display:'block',marginBottom:4}}>MAX. DATEIGRÖSSE PRO UPLOAD (MB)</label>
        <input type="number" value={s.file_max_size_mb} onChange={e=>setS(p=>({...p,file_max_size_mb:e.target.value}))} style={{...S.inp,fontSize:15}} min="1"/>
      </div>
      <div style={{marginBottom:10}}>
        <label style={{...S.head,display:'block',marginBottom:4}}>GESAMTLIMIT PRO BENUTZER (MB)</label>
        <input type="number" value={s.file_total_size_mb} onChange={e=>setS(p=>({...p,file_total_size_mb:e.target.value}))} style={{...S.inp,fontSize:15}} min="1"/>
      </div>
      <div style={{marginBottom:14}}>
        <label style={{...S.head,display:'block',marginBottom:4}}>ERLAUBTE ENDUNGEN (kommagetrennt)</label>
        <input value={s.file_allowed_ext} onChange={e=>setS(p=>({...p,file_allowed_ext:e.target.value}))} autoCapitalize="none" style={{...S.inp,fontSize:13}}/>
      </div>
      <button onClick={save} disabled={busy} style={{...S.btn('#4ecdc4'),width:'100%',textAlign:'center',padding:'10px 0'}}>
        {busy?'…':'✓ Speichern'}
      </button>
    </div>
  );
}
