const { Card, SectionHeading, Badge, StatusBadge, Select, TextInput, Textarea, Button, IconButton, Icon, FilterChip, DefinitionRow, HistoryList, StatTile, STATUS } = window.TersusDesignSystem_b3db99;

const STATUS_OPTIONS = ["neu","angeschrieben","verhandlung","bestandskunde","absage"].map(k=>({value:k,label:STATUS[k].label}));

/* Farbiger Statuspunkt wie bei den Filter-Chips; der feine Rand haelt auch den weissen "Neu"-Punkt sichtbar. */
function StatusPunkt({ status }) {
  return <span aria-hidden="true" style={{flex:"0 0 auto",width:8,height:8,borderRadius:"var(--radius-pill)",background:STATUS[status].color,boxShadow:"inset 0 0 0 1px rgba(0,0,0,.25)"}} />;
}

/* Status-Dropdown mit farbigen Punkten auch in der aufgeklappten Liste. Ein natives <select> kann
   in den Optionen keine Symbole zeigen, daher Button + Listbox nach dem ARIA-Muster "Select-only Combobox". */
function StatusWahl({ objekt, onPatch }) {
  const [offen, setOffen] = React.useState(false);
  const [markiert, setMarkiert] = React.useState(0);
  const wurzel = React.useRef(null);
  const knopf = React.useRef(null);
  const aktuell = STATUS_OPTIONS.findIndex(o => o.value === objekt.status);

  /* Klick ausserhalb schliesst die Liste. */
  React.useEffect(() => {
    if (!offen) return;
    const zu = (e) => { if (wurzel.current && !wurzel.current.contains(e.target)) setOffen(false); };
    document.addEventListener("mousedown", zu);
    return () => document.removeEventListener("mousedown", zu);
  }, [offen]);
  React.useEffect(() => { setOffen(false); }, [objekt.id]);

  const oeffnen = () => { setMarkiert(Math.max(0, aktuell)); setOffen(true); };
  const waehlen = (i) => {
    const v = STATUS_OPTIONS[i].value;
    setOffen(false);
    knopf.current && knopf.current.focus();
    if (v !== objekt.status) onPatch(objekt.id, { status: v });
  };
  const taste = (e) => {
    const n = STATUS_OPTIONS.length;
    if (!offen) {
      if (["ArrowDown","ArrowUp","Enter"," "].includes(e.key)) { e.preventDefault(); oeffnen(); }
      return;
    }
    if (e.key === "ArrowDown") { e.preventDefault(); setMarkiert(i => Math.min(n - 1, i + 1)); }
    else if (e.key === "ArrowUp") { e.preventDefault(); setMarkiert(i => Math.max(0, i - 1)); }
    else if (e.key === "Home") { e.preventDefault(); setMarkiert(0); }
    else if (e.key === "End") { e.preventDefault(); setMarkiert(n - 1); }
    else if (e.key === "Enter" || e.key === " ") { e.preventDefault(); waehlen(markiert); }
    else if (e.key === "Escape" || e.key === "Tab") { setOffen(false); }
  };

  return (
    <div ref={wurzel} style={{position:"relative"}}>
      <div id="statuswahl-label" style={{marginBottom:6,font:"var(--text-label)",letterSpacing:"var(--ls-label)",textTransform:"uppercase",color:"var(--text-muted)"}}>Status aendern</div>
      <button ref={knopf} type="button" role="combobox" aria-haspopup="listbox" aria-expanded={offen}
        aria-controls="statuswahl-liste" aria-labelledby="statuswahl-label"
        aria-activedescendant={offen ? "statuswahl-" + markiert : undefined}
        onClick={() => (offen ? setOffen(false) : oeffnen())} onKeyDown={taste}
        style={{width:"100%",height:"var(--control-h)",display:"flex",alignItems:"center",gap:9,padding:"0 10px 0 11px",
          background:"var(--control-bg)",color:"var(--text-primary)",font:"var(--fw-medium) var(--fs-sm)/1 var(--font-sans)",
          border:"1px solid " + (offen ? "var(--focus-ring)" : "var(--control-border)"),boxShadow:offen ? "0 0 0 1px var(--focus-ring)" : "none",
          borderRadius:"var(--radius)",cursor:"pointer",textAlign:"left"}}>
        <StatusPunkt status={objekt.status} />
        <span style={{flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{STATUS[objekt.status].label}</span>
        <Icon name="chevron-down" size={14} style={{color:"var(--text-muted)",transform:offen ? "rotate(180deg)" : "none",transition:"transform var(--dur-fast) var(--ease)"}} />
      </button>
      {offen ? (
        <ul id="statuswahl-liste" role="listbox" aria-labelledby="statuswahl-label"
          style={{position:"absolute",left:0,right:0,top:"100%",marginTop:4,zIndex:40,listStyle:"none",padding:4,
            background:"var(--surface-popover)",border:"1px solid var(--border)",borderRadius:"var(--radius)",boxShadow:"var(--shadow-popover)"}}>
          {STATUS_OPTIONS.map((o, i) => {
            const gewaehlt = o.value === objekt.status;
            return (
              <li key={o.value} id={"statuswahl-" + i} role="option" aria-selected={gewaehlt}
                onMouseEnter={() => setMarkiert(i)} onMouseDown={e => e.preventDefault()} onClick={() => waehlen(i)}
                style={{display:"flex",alignItems:"center",gap:9,height:32,padding:"0 8px",borderRadius:"var(--radius-sm)",cursor:"pointer",
                  fontSize:"var(--fs-sm)",fontWeight:gewaehlt ? "var(--fw-semibold)" : "var(--fw-regular)",
                  background:i === markiert ? "var(--surface-row-hover)" : "transparent"}}>
                <StatusPunkt status={o.value} />
                <span style={{flex:1}}>{o.label}</span>
                {gewaehlt ? <Icon name="check" size={14} style={{color:"var(--text-muted)"}} /> : null}
              </li>
            );
          })}
        </ul>
      ) : null}
    </div>
  );
}
const ARTEN = [{value:"anruf",label:"Anruf"},{value:"email",label:"E-Mail"},{value:"termin",label:"Termin vor Ort"},{value:"sonstiges",label:"Sonstiges"}];
const ERGEBNISSE = ["Erreicht","Nicht erreicht","Rueckruf vereinbart","Ansprechpartner erfragt","Unterlagen angefordert","Kein Interesse"];
const ART_LABEL = Object.fromEntries(ARTEN.map(a=>[a.value,a.label]));

const telHref = (t) => "tel:" + t.replace(/[^\d+]/g, "");
const webHref = (w) => (/^https?:\/\//.test(w) ? w : "https://" + w);
const zeitDe = (iso) => {
  const d = new Date(iso);
  return d.toLocaleDateString("de-DE",{day:"2-digit",month:"2-digit",year:"numeric"}) + ", " + d.toLocaleTimeString("de-DE",{hour:"2-digit",minute:"2-digit"});
};

function EmptyState({ objekte, hq }) {
  const counts = objekte.reduce((a,o)=>((a[o.status]=(a[o.status]||0)+1),a),{});
  const faellig = objekte.filter(terminFaellig).length;
  const geplant = objekte.filter(o=>o.wiedervorlage).length;
  return (
    <div style={{padding:"var(--pad-section)",display:"grid",gap:"var(--space-5)",alignContent:"start",overflowY:"auto"}}>
      <div>
        <h2 style={{font:"var(--text-h1)"}}>Keine Karteikarte ausgewaehlt</h2>
        <p style={{margin:"6px 0 0",fontSize:"var(--fs-sm)",color:"var(--text-muted)",maxWidth:340}}>
          Eintrag in der Anrufliste oder Pin auf der Karte anklicken, um Kontaktdaten, Notizen und das Kontaktprotokoll zu sehen.
        </p>
      </div>
      <div>
        <SectionHeading icon="alarm-clock">Naechste Anrufe</SectionHeading>
        <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"var(--space-2)"}}>
          <StatTile value={faellig} label="Heute anrufen (inkl. ueberfaellig)" />
          <StatTile value={geplant} label="Eingeplant gesamt" />
        </div>
      </div>
      <div>
        <SectionHeading icon="chart-no-axes-column">Karteikarten je Status</SectionHeading>
        <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"var(--space-2)"}}>
          {["neu","angeschrieben","verhandlung","bestandskunde","absage"].map(k=>(
            <StatTile key={k} value={counts[k]||0} label={STATUS[k].label.split(" / ")[0]} dot={STATUS[k].color} />
          ))}
          <StatTile value={objekte.length} label="Gesamt" />
        </div>
      </div>
      <div>
        <SectionHeading icon="building-2">Firmenstandort</SectionHeading>
        <Card padding="12px">
          <div style={{fontSize:"var(--fs-sm)",fontWeight:"var(--fw-semibold)"}}>{hq.name}</div>
          <div style={{fontSize:"var(--fs-xs)",color:"var(--text-muted)",marginTop:3}}>{hq.strasse} · {hq.plz} {hq.ort}</div>
        </Card>
      </div>
    </div>
  );
}

const KONTAKT_FELDER = ["strasse","plz","ort","telefon","email","website","kontakt","position"];

/* Neue Koordinaten fuer eine korrigierte Adresse (OpenStreetMap Nominatim).
   Liefert [lat,lng], null wenn die Adresse nicht gefunden wurde, oder wirft bei Netzfehlern. */
async function geokodieren({ strasse, plz, ort }) {
  const q = [strasse, [plz, ort].filter(Boolean).join(" "), "Deutschland"].filter(Boolean).join(", ");
  const res = await fetch("https://nominatim.openstreetmap.org/search?format=json&limit=1&countrycodes=de&q=" + encodeURIComponent(q));
  if (!res.ok) throw new Error("HTTP " + res.status);
  const daten = await res.json();
  return daten.length ? [parseFloat(daten[0].lat), parseFloat(daten[0].lon)] : null;
}

/* Adresse und Kontakt: Anzeige mit Stift oben rechts, im Bearbeitungsmodus Eingabefelder. */
function KontaktAbschnitt({ objekt, onPatch }) {
  const [bearbeiten, setBearbeiten] = React.useState(false);
  const [werte, setWerte] = React.useState({});
  const [speichert, setSpeichert] = React.useState(false);
  const [hinweis, setHinweis] = React.useState(null);

  /* Beim Wechsel der Karteikarte Bearbeitung verwerfen. */
  React.useEffect(() => { setBearbeiten(false); setHinweis(null); }, [objekt.id]);

  const starten = () => {
    setWerte(Object.fromEntries(KONTAKT_FELDER.map(f => [f, objekt[f] || ""])));
    setHinweis(null);
    setBearbeiten(true);
  };
  const feld = (f) => ({ value: werte[f], onChange: e => setWerte(w => ({ ...w, [f]: e.target.value })) });

  const speichern = async () => {
    const aenderung = {};
    KONTAKT_FELDER.forEach(f => {
      const neu = (werte[f] || "").trim();
      if (neu !== (objekt[f] || "")) aenderung[f] = neu;
    });
    if (aenderung.website) aenderung.website = aenderung.website.replace(/^https?:\/\//, "").replace(/\/$/, "");
    if (!Object.keys(aenderung).length) { setBearbeiten(false); return; }

    setSpeichert(true);
    let meldung = null;
    if ("strasse" in aenderung || "plz" in aenderung || "ort" in aenderung) {
      try {
        const punkt = await geokodieren({ ...objekt, ...aenderung });
        if (punkt) { aenderung.lat = punkt[0]; aenderung.lng = punkt[1]; }
        else { aenderung.lat = null; aenderung.lng = null; meldung = "Neue Adresse nicht auf der Karte gefunden, Pin entfernt."; }
      } catch (err) {
        meldung = "Kartenposition konnte nicht aktualisiert werden, Pin bleibt an der alten Stelle.";
      }
    }
    const res = await onPatch(objekt.id, aenderung);
    setSpeichert(false);
    if (res && res.ok === false) { setHinweis("Speichern fehlgeschlagen: " + res.error); return; }
    setHinweis(meldung);
    setBearbeiten(false);
  };

  const aktion = bearbeiten ? null
    : <IconButton icon="pencil" label="Adresse und Kontakt bearbeiten" size="sm" variant="ghost" onClick={starten} />;

  return (
    <section>
      <SectionHeading icon="map-pin" action={aktion}>Adresse und Kontakt</SectionHeading>
      {bearbeiten ? (
        <div style={{display:"grid",gap:"var(--space-3)"}}>
          <TextInput label="Strasse und Hausnummer" size="sm" {...feld("strasse")} />
          <div style={{display:"grid",gridTemplateColumns:"96px 1fr",gap:"var(--space-2)"}}>
            <TextInput label="PLZ" size="sm" inputMode="numeric" {...feld("plz")} />
            <TextInput label="Ort" size="sm" {...feld("ort")} />
          </div>
          <TextInput label="Telefon" size="sm" type="tel" {...feld("telefon")} />
          <TextInput label="E-Mail" size="sm" type="email" {...feld("email")} />
          <TextInput label="Website" size="sm" {...feld("website")} />
          <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"var(--space-2)"}}>
            <TextInput label="Ansprechpartner" size="sm" {...feld("kontakt")} />
            <TextInput label="Funktion" size="sm" {...feld("position")} />
          </div>
          {hinweis ? <div role="alert" style={{fontSize:"var(--fs-sm)",color:"var(--status-declined)"}}>{hinweis}</div> : null}
          <div style={{display:"flex",gap:"var(--space-2)"}}>
            <Button variant="secondary" size="sm" icon={speichert?"loader":"check"} disabled={speichert} onClick={speichern}>Aenderungen speichern</Button>
            <Button variant="ghost" size="sm" disabled={speichert} onClick={() => setBearbeiten(false)}>Abbrechen</Button>
          </div>
        </div>
      ) : (
        <React.Fragment>
          <DefinitionRow label="Adresse" value={objekt.strasse || "–"} />
          <DefinitionRow label="Ort" value={[objekt.plz, objekt.ort].filter(Boolean).join(" ") || "–"} />
          <DefinitionRow label="Telefon" icon="phone" value={objekt.telefon || "fehlt"} href={objekt.telefon ? telHref(objekt.telefon) : undefined} />
          <DefinitionRow label="E-Mail" icon="mail" value={objekt.email || "fehlt"} href={objekt.email ? "mailto:" + objekt.email : undefined} />
          {/* Eigener Link statt href, damit die Website in einem neuen Tab aufgeht und das Tool offen bleibt. */}
          <DefinitionRow label="Website" icon="globe" value={objekt.website
            ? <a href={webHref(objekt.website)} target="_blank" rel="noopener noreferrer" title="Website in neuem Tab oeffnen"
                style={{display:"inline-flex",alignItems:"center",gap:4,minWidth:0,maxWidth:"100%"}}>
                <span style={{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{objekt.website}</span>
                <Icon name="external-link" size={12} style={{flex:"0 0 auto",color:"var(--text-muted)"}} />
              </a>
            : "fehlt"} />
          <DefinitionRow label="Ansprechpartner" value={objekt.kontakt ? objekt.kontakt + (objekt.position ? ", " + objekt.position : "") : "noch nicht bekannt"} />
          {objekt.lat == null ? <DefinitionRow label="Karte" icon="map-pin-off" value="Adresse nicht auf der Karte gefunden" /> : null}
          {hinweis ? <div role="status" style={{fontSize:"var(--fs-xs)",color:"var(--text-muted)",marginTop:6}}>{hinweis}</div> : null}
        </React.Fragment>
      )}
    </section>
  );
}

const { SCHNELLWAHL, datumIn, terminText, istFaellig: terminFaellig } = window.TersusTermine;

/* Naechster Anruf: Schnellwahl oder Kalender, speichert sofort. */
function NaechsterAnruf({ objekt, onPatch }) {
  const wert = (objekt.wiedervorlage || "").slice(0, 10);
  const setzen = (iso) => { if (iso !== wert) onPatch(objekt.id, { wiedervorlage: iso || null }); };
  const termin = wert ? terminText(wert) : null;
  return (
    <div>
      <div style={{font:"var(--text-label)",letterSpacing:"var(--ls-label)",textTransform:"uppercase",color:"var(--text-muted)",marginBottom:6}}>Naechster Anruf</div>
      <div style={{display:"flex",flexWrap:"wrap",gap:6,marginBottom:"var(--space-2)"}}>
        {SCHNELLWAHL.map(s => {
          const iso = datumIn(s);
          return <FilterChip key={s.label} active={iso === wert} onClick={() => setzen(iso)}>{s.label}</FilterChip>;
        })}
      </div>
      <div style={{display:"flex",gap:"var(--space-2)",alignItems:"center"}}>
        <div style={{flex:1}}>
          {/* colorScheme light: sonst ist das Kalendersymbol im hellen Theme weiss auf weiss. */}
          <TextInput type="date" aria-label="Datum fuer den naechsten Anruf" value={wert}
            style={{colorScheme:"light",cursor:"pointer"}}
            onClick={e => { try { e.currentTarget.showPicker(); } catch (err) {} }}
            onChange={e => setzen(e.target.value)} />
        </div>
        {wert ? <IconButton icon="calendar-x" label="Kein Anruf geplant" size="md" variant="ghost" onClick={() => setzen("")} /> : null}
      </div>
      <div style={{fontSize:"var(--fs-xs)",marginTop:6,fontVariantNumeric:"tabular-nums",color:termin && termin.faellig ? "var(--status-declined)" : "var(--text-muted)"}}>
        {termin ? termin.text : "Kein Anruf geplant"}
      </div>
    </div>
  );
}

/* Notizfeld mit automatischem Speichern: kurz nach dem Tippen und beim Verlassen des Feldes. */
function NotizFeld({ objekt, onPatch }) {
  const [text, setText] = React.useState(objekt.notiz || "");
  const [zustand, setZustand] = React.useState(null); // null | "offen" | "speichert" | "gespeichert" | Fehlertext
  const timer = React.useRef(null);
  const offen = React.useRef(null); // { id, text } noch nicht gespeichert

  const sichern = React.useCallback(async () => {
    clearTimeout(timer.current);
    const eintrag = offen.current;
    if (!eintrag) return;
    offen.current = null;
    setZustand("speichert");
    const res = await onPatch(eintrag.id, { notiz: eintrag.text });
    setZustand(res && res.ok === false ? "Speichern fehlgeschlagen" : "gespeichert");
  }, [onPatch]);

  /* Karteikarte gewechselt: Offenes der alten Karte sichern, neue laden. */
  React.useEffect(() => {
    setText(objekt.notiz || ""); setZustand(null);
    return () => { sichern(); };
  }, [objekt.id]);

  const aendern = (e) => {
    const t = e.target.value;
    setText(t);
    offen.current = { id: objekt.id, text: t };
    setZustand("offen");
    clearTimeout(timer.current);
    timer.current = setTimeout(sichern, 1200);
  };

  const hinweis = zustand === "offen" ? "Aenderung wird gleich gespeichert"
    : zustand === "speichert" ? "Speichert"
    : zustand === "gespeichert" ? "Gespeichert"
    : zustand;
  return (
    <div>
      <Textarea label="Notizen" rows={4} value={text} onChange={aendern} onBlur={sichern}
        placeholder="Feste Infos zur Einrichtung, z. B. Entscheider, aktueller Dienstleister, Vertragsende" />
      <div style={{fontSize:"var(--fs-xs)",marginTop:4,minHeight:14,color:zustand && zustand.startsWith("Speichern fehl") ? "var(--status-declined)" : "var(--text-muted)"}}>{hinweis || ""}</div>
    </div>
  );
}

/* Recherche-Notiz aus dem Import zerlegen. Aufbau: Teile getrennt durch " | ",
   bekannte Praefixe "Traegerart:", "Leistungen:", "Zielfunktion:", der Rest sind Einschaetzungen
   wie "Einzelhaus oder kleine Gruppe – Entscheider meist vor Ort". */
function rechercheTeile(notiz) {
  const teile = { traegerart: "", anbieten: "", ansprechen: "", ansprechenHinweis: "", einschaetzung: [] };
  (notiz || "").split(" | ").map(t => t.trim()).filter(Boolean).forEach(t => {
    const m = t.match(/^(Trägerart|Leistungen|Zielfunktion):\s*(.*)$/);
    if (!m) { teile.einschaetzung.push(t); return; }
    if (m[1] === "Trägerart") teile.traegerart = m[2];
    else if (m[1] === "Leistungen") teile.anbieten = m[2];
    else {
      /* "Hauswirtschaftsleitung / Einkauf – Name telefonisch erfragen" */
      const [wer, hinweis] = m[2].split(/\s+–\s+/);
      teile.ansprechen = wer;
      teile.ansprechenHinweis = hinweis || "";
    }
  });
  return teile;
}

/* Gespraechshilfe: wen ansprechen, was anbieten, Einschaetzung aus der Recherche. */
function Gespraechshilfe({ objekt }) {
  const t = rechercheTeile(objekt.recherche_notiz);
  if (!t.ansprechen && !t.anbieten && !t.einschaetzung.length) return null;
  return (
    <section>
      <SectionHeading icon="message-square-text">Gespraechshilfe</SectionHeading>
      {t.ansprechen ? (
        <DefinitionRow label="Ansprechen" value={
          <span>{t.ansprechen}{t.ansprechenHinweis ? <span style={{display:"block",fontSize:"var(--fs-xs)",color:"var(--text-muted)",marginTop:2}}>{t.ansprechenHinweis}</span> : null}</span>
        } />
      ) : null}
      {t.anbieten ? <DefinitionRow label="Anbieten" value={t.anbieten} /> : null}
      {t.einschaetzung.length ? <DefinitionRow label="Einschaetzung" value={t.einschaetzung.join(". ")} /> : null}
      {objekt.quelle ? <div style={{fontSize:"var(--fs-xs)",color:"var(--text-muted)",marginTop:6}}>Quelle der Adressdaten: {objekt.quelle}</div> : null}
    </section>
  );
}

/* Kontaktprotokoll: Eintraege laden und neue anlegen. */
function Kontaktprotokoll({ objektId }) {
  const [eintraege, setEintraege] = React.useState([]);
  const [laden, setLaden] = React.useState(true);
  const [art, setArt] = React.useState("anruf");
  const [ergebnis, setErgebnis] = React.useState("Erreicht");
  const [text, setText] = React.useState("");
  const [speichert, setSpeichert] = React.useState(false);
  const [fehler, setFehler] = React.useState(null);

  React.useEffect(() => {
    let aktiv = true;
    setLaden(true); setFehler(null); setText("");
    window.TersusDB.loadKontakte(objektId).then(res => {
      if (!aktiv) return;
      setEintraege(res.rows); setFehler(res.error || null); setLaden(false);
    });
    return () => { aktiv = false; };
  }, [objektId]);

  const hinzufuegen = async () => {
    setSpeichert(true); setFehler(null);
    const res = await window.TersusDB.addKontakt(objektId, { art, ergebnis, text: text.trim() });
    setSpeichert(false);
    if (res.ok) { setEintraege(e => [res.row, ...e]); setText(""); } else setFehler(res.error);
  };

  return (
    <section>
      <SectionHeading icon="history">Kontaktprotokoll</SectionHeading>
      <Card padding="12px" style={{display:"grid",gap:"var(--space-3)",marginBottom:"var(--space-4)"}}>
        <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"var(--space-2)"}}>
          <Select label="Art" size="sm" value={art} options={ARTEN} onChange={e=>setArt(e.target.value)} />
          <Select label="Ergebnis" size="sm" value={ergebnis} options={ERGEBNISSE} onChange={e=>setErgebnis(e.target.value)} />
        </div>
        <Textarea label="Gespraechsnotiz" rows={2} value={text} onChange={e=>setText(e.target.value)} placeholder="z. B. Hauswirtschaftsleitung Frau Meier, Angebot bis Ende Oktober" />
        <div><Button variant="secondary" size="sm" icon={speichert?"loader":"plus"} disabled={speichert} onClick={hinzufuegen}>Eintrag hinzufuegen</Button></div>
      </Card>
      {fehler ? <div role="alert" style={{fontSize:"var(--fs-sm)",color:"var(--status-declined)",marginBottom:8}}>{fehler}</div> : null}
      {laden ? <div style={{fontSize:"var(--fs-sm)",color:"var(--text-muted)"}}>Wird geladen</div>
        : eintraege.length
          ? <HistoryList items={eintraege.map(k=>({date:zeitDe(k.datum),text:[ART_LABEL[k.art]||k.art,k.ergebnis].filter(Boolean).join(" · ")+(k.text?" — "+k.text:"")}))} />
          : <div style={{fontSize:"var(--fs-sm)",color:"var(--text-muted)"}}>Noch kein Kontakt dokumentiert.</div>}
    </section>
  );
}

function DetailSidebar({ objekt, hq, alleObjekte, onPatch, onClose }) {
  if (!objekt) return <EmptyState objekte={alleObjekte} hq={hq} />;

  const traegerart = rechercheTeile(objekt.recherche_notiz).traegerart;

  return (
    <div style={{display:"flex",flexDirection:"column",height:"100%",minHeight:0}}>
      <div style={{padding:"var(--pad-section)",borderBottom:"1px solid var(--divider)"}}>
        <div style={{display:"flex",alignItems:"flex-start",gap:"var(--space-3)"}}>
          <div style={{minWidth:0}}>
            <h2 style={{font:"var(--text-h1)",overflowWrap:"anywhere"}}>{objekt.name}</h2>
            {objekt.traeger || traegerart ? <div style={{fontSize:"var(--fs-sm)",color:"var(--text-muted)",marginTop:4}}>{[objekt.traeger, traegerart].filter(Boolean).join(" · ")}</div> : null}
            <div style={{display:"flex",gap:6,marginTop:9,flexWrap:"wrap"}}>
              <Badge>{objekt.kategorie}</Badge>
              <StatusBadge status={objekt.status} size="sm" />
            </div>
          </div>
          <div style={{marginLeft:"auto",flex:"0 0 auto"}}>
            <Button variant="ghost" size="sm" icon="x" onClick={onClose}>Schliessen</Button>
          </div>
        </div>
        <div className="spalten-auto" style={{marginTop:"var(--space-4)",rowGap:"var(--space-4)"}}>
          <StatusWahl objekt={objekt} onPatch={onPatch} />
          <NaechsterAnruf objekt={objekt} onPatch={onPatch} />
        </div>
      </div>

      <div style={{overflowY:"auto",padding:"var(--pad-section)",display:"grid",gap:"var(--space-6)",alignContent:"start",flex:1,minHeight:0}}>
        {/* Breite Seitenleiste: je zwei Bereiche nebeneinander, schmale: untereinander. */}
        <div className="spalten-auto">
          <KontaktAbschnitt objekt={objekt} onPatch={onPatch} />
          <Gespraechshilfe objekt={objekt} />
        </div>

        <div className="spalten-auto">
          <section>
            <SectionHeading icon="notebook-pen">Notizen</SectionHeading>
            <NotizFeld objekt={objekt} onPatch={onPatch} />
          </section>
          <Kontaktprotokoll objektId={objekt.id} />
        </div>
      </div>

      {objekt.telefon ? (
        <div style={{padding:"12px var(--pad-section)",borderTop:"1px solid var(--divider)"}}>
          <Button variant="primary" icon="phone" fullWidth onClick={()=>{ window.location.href = telHref(objekt.telefon); }}>{objekt.telefon} anrufen</Button>
        </div>
      ) : null}
    </div>
  );
}

Object.assign(window, { DetailSidebar, EmptyState, geokodieren });
