(function(){
// ============================================================
// pickers.jsx — Date / Category / Recurring pickers + manager
// Components: Spinner, DatePicker, CatPicker, CatManager, RecurringPicker
// Depends on (window): todayISO, localISO, fmtDate, getCatColor
// ============================================================

const { useState } = React;

// ── Spinner ──────────────────────────────────────────────────────────
function Spinner(){
  return (
    <span style={{
      display: "inline-block", width: 13, height: 13,
      border: "2px solid var(--col-border)",
      borderTop: "2px solid var(--col-accent)",
      borderRadius: "50%",
      animation: "spin .7s linear infinite"
    }}/>
  );
}

// ── DatePicker ───────────────────────────────────────────────────────
function DatePicker({ value, onChange, label, dots = [] }){
  const today = todayISO();
  const todayDate = new Date(today + "T12:00:00");
  const dow0 = (todayDate.getDay() + 6) % 7; // 0=Mon…6=Sun

  const [weekOffset, setWeekOffset] = useState(() => {
    if (!value || value === "someday") return 0;
    try {
      const valDate = new Date(value + "T12:00:00");
      const weekMon = new Date(todayDate);
      weekMon.setDate(weekMon.getDate() - dow0);
      const diffDays = Math.round((valDate - weekMon) / 86400000);
      return Math.floor(diffDays / 14);
    } catch { return 0; }
  });

  const weekStart = new Date(todayDate);
  weekStart.setDate(weekStart.getDate() - dow0 + weekOffset * 14);

  const days = Array.from({length: 14}, (_, i) => {
    const d = new Date(weekStart);
    d.setDate(weekStart.getDate() + i);
    return { iso: localISO(d), day: d.getDate(), wday: d.getDay() };
  });

  const mCount = {};
  days.forEach(({iso}) => { const m = iso.slice(0,7); mCount[m] = (mCount[m]||0)+1; });
  const domMonth = Object.entries(mCount).sort((a,b)=>b[1]-a[1])[0]?.[0];
  const monthLabel = domMonth
    ? new Date(domMonth + "-15T12:00:00").toLocaleDateString("de-CH", {month:"long", year:"numeric"})
    : "";

  const navBtn = {padding:"2px 7px",fontSize:14,border:"1px solid var(--col-border)",borderRadius:4,color:"var(--col-text-sec)",background:"transparent",cursor:"pointer",lineHeight:1,display:"inline-flex",alignItems:"center"};

  const dayCell = ({iso, day, wday}) => {
    const isToday = iso === today;
    const isSel = iso === value;
    const isPast = iso < today;
    const hasDot = dots.includes(iso);
    const isWknd = wday === 0 || wday === 6;
    return (
      <div key={iso} style={{display:"flex",flexDirection:"column",alignItems:"center",gap:1}}>
        <button onClick={() => onChange(isSel ? null : iso)} style={{
          width:28, height:28, borderRadius:"50%", fontSize:12, padding:0,
          border: isToday && !isSel ? "1.5px solid var(--col-accent)" : "1.5px solid transparent",
          background: isSel ? "var(--col-accent)" : "transparent", // FIXED: heute unselektiert = nur Ring, kein Fill (war visuell wie "ausgewählt")
          color: isSel ? "var(--col-bg)" : isToday ? "var(--col-accent)" : isPast ? "var(--col-text-3)" : isWknd ? "var(--col-text-sec)" : "var(--col-text)",
          fontWeight: isToday || isSel ? 600 : 400, cursor:"pointer",
          display:"flex", alignItems:"center", justifyContent:"center",
          transition:"background 0.1s", opacity: isPast ? 0.55 : 1,
        }}>{day}</button>
        {hasDot && <span style={{width:3,height:3,borderRadius:"50%",background:isSel?"var(--col-bg)":"var(--col-accent)"}}/>}
      </div>
    );
  };

  return (
    <div>
      {label && <div style={{fontSize:11,fontWeight:500,color:"var(--col-text-sec)",textTransform:"uppercase",letterSpacing:"0.06em",marginBottom:5}}>{label}</div>}
      <div style={{background:"var(--col-bg)",border:"1px solid var(--col-border-soft)",borderRadius:8,padding:"7px 6px"}}>
        <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:5,paddingLeft:1,paddingRight:1}}>
          <button onClick={() => setWeekOffset(x=>x-1)} style={navBtn}>‹</button>
          <span style={{fontSize:11,color:"var(--col-text-sec)",fontFamily:"var(--serif)",fontStyle:"italic"}}>{monthLabel}</span>
          <button onClick={() => setWeekOffset(x=>x+1)} style={navBtn}>›</button>
        </div>
        <div style={{display:"grid",gridTemplateColumns:"repeat(7,1fr)",marginBottom:3}}>
          {["Mo","Di","Mi","Do","Fr","Sa","So"].map(l => (
            <div key={l} style={{textAlign:"center",fontSize:9,color:"var(--col-text-3)",fontFamily:"var(--mono)",letterSpacing:"0.06em",padding:"1px 0"}}>{l}</div>
          ))}
        </div>
        <div style={{display:"grid",gridTemplateColumns:"repeat(7,1fr)",marginBottom:2}}>{days.slice(0,7).map(dayCell)}</div>
        <div style={{display:"grid",gridTemplateColumns:"repeat(7,1fr)"}}>{days.slice(7).map(dayCell)}</div>
      </div>
      <div style={{display:"flex",gap:4,marginTop:5,flexWrap:"wrap",alignItems:"center"}}>
        <button onClick={() => onChange(value === "someday" ? null : "someday")} style={{
          padding:"2px 9px", borderRadius:20, fontSize:11,
          border: value === "someday" ? "2px solid var(--col-accent)" : "1px solid var(--col-border)",
          background: value === "someday" ? "var(--col-accent)" : "transparent",
          color: value === "someday" ? "var(--col-bg)" : "var(--col-text-sec)", cursor:"pointer"
        }}>Irgendwann</button>
        {value && (
          <button onClick={() => onChange(null)} style={{padding:"2px 8px",borderRadius:20,fontSize:11,border:"1px solid #fca5a5",color:"#b91c1c",cursor:"pointer"}}>✕ Löschen</button>
        )}
        {value && value !== "someday" && !days.some(d=>d.iso===value) && (
          <span style={{fontSize:10.5,color:"var(--col-accent)",marginLeft:2}}>✓ {fmtDate(value)}</span>
        )}
      </div>
    </div>
  );
}

// ── CatPicker ────────────────────────────────────────────────────────
function CatPicker({ value, subcategory, onChange, onSubChange, categories, subcategories, onManage }){
  const subs = value && subcategories ? subcategories[value] || [] : [];
  return (
    <div>
      <div style={{fontSize:11,fontWeight:500,color:"var(--col-text-sec)",textTransform:"uppercase",letterSpacing:"0.06em",marginBottom:5}}>Kategorie</div>
      <div style={{display:"flex",gap:4,flexWrap:"wrap"}}>
        {categories.map(cat => {
          const cc = getCatColor(categories, cat);
          const sel = value === cat;
          return (
            <button key={cat}
              onClick={() => { const next = sel ? null : cat; onChange(next); if (onSubChange) onSubChange(null); }}
              style={{
                padding:"2px 9px", borderRadius:20, fontSize:12, fontWeight:500,
                border: sel ? `2px solid ${cc.col}` : "1px solid var(--col-border)",
                background: sel ? cc.bg : "transparent",
                color: sel ? cc.col : "var(--col-text-sec)"
              }}>{cat}</button>
          );
        })}
        <button onClick={onManage}
          style={{padding:"2px 9px",borderRadius:20,fontSize:12,border:"1px solid var(--col-border)",color:"var(--col-text-sec)"}}>+ Verwalten</button>
      </div>
      {subs.length > 0 && (
        <div style={{display:"flex",gap:3,flexWrap:"wrap",marginTop:5,paddingLeft:6,borderLeft:"2px solid var(--col-border)"}}>
          <span style={{fontSize:10,color:"var(--col-text-sec)",alignSelf:"center",marginRight:2}}>↳</span>
          {subs.map(sub => {
            const sel = subcategory === sub;
            return (
              <button key={sub}
                onClick={() => { if (onSubChange) onSubChange(sel ? null : sub); }}
                style={{
                  padding:"2px 8px", borderRadius:20, fontSize:11,
                  border: sel ? "2px solid var(--col-accent)" : "1px solid var(--col-border)",
                  background: sel ? "var(--col-accent)" : "transparent",
                  color: sel ? "var(--col-bg)" : "var(--col-text-sec)"
                }}>{sub}</button>
            );
          })}
        </div>
      )}
    </div>
  );
}

// ── CatManager ───────────────────────────────────────────────────────
function CatManager({ categories, subcategories, categoryIcons, onChange, onSubChange, onIconChange, onClose }){
  const [input, setInput] = useState("");
  const [expanded, setExpanded] = useState(null);
  const [subInput, setSubInput] = useState("");
  const [dupErr, setDupErr] = useState(false);
  const add = () => {
    const val = input.trim();
    if (!val) return;
    if (categories.map(c=>c.toLowerCase()).includes(val.toLowerCase())) {
      setDupErr(true);
      setTimeout(() => setDupErr(false), 2000);
      return;
    }
    onChange([...categories, val]);
    setInput("");
    setDupErr(false);
  };
  function addSub(cat){
    if (!subInput.trim()) return;
    const cur = subcategories[cat] || [];
    if (!cur.includes(subInput.trim())) onSubChange(cat, [...cur, subInput.trim()]);
    setSubInput("");
  }
  function removeSub(cat, sub){
    onSubChange(cat, (subcategories[cat] || []).filter(s => s !== sub));
  }
  return (
    <div style={{position:"fixed",inset:0,background:"rgba(38,34,32,0.5)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:999}} onClick={onClose}>
      <div style={{background:"var(--col-bg)",borderRadius:12,padding:"1.25rem",width:300,boxShadow:"0 10px 40px rgba(38,34,32,0.2)",maxHeight:"80vh",overflowY:"auto"}} onClick={e => e.stopPropagation()}>
        <div style={{fontSize:15,fontWeight:600,color:"var(--col-accent)",marginBottom:10}}>Kategorien & Unterkategorien</div>
        {categories.map(cat => {
          const cc = getCatColor(categories, cat);
          const subs = subcategories[cat] || [];
          const open = expanded === cat;
          return (
            <div key={cat} style={{marginBottom:6}}>
              <div style={{display:"flex",alignItems:"center",gap:8}}>
                {categoryIcons?.[cat] && (
                  <img src={`kategorie-icons/${categoryIcons[cat]}.svg`} alt="" style={{width:16,height:16,flexShrink:0}}/>
                )}
                <span style={{flex:1,fontSize:13,padding:"2px 9px",borderRadius:20,background:cc.bg,color:cc.col,fontWeight:500}}>{cat}</span>
                <button onClick={() => { setExpanded(e => e === cat ? null : cat); setSubInput(""); }}
                  style={{background:"none",border:"none",color:"var(--col-text-sec)",fontSize:12,padding:"2px 4px"}}
                  title="Unterkategorien">
                  {open ? "▲" : "▼"}{" "}
                  {subs.length > 0 && (
                    <span style={{fontSize:10,background:"var(--col-border)",borderRadius:10,padding:"0 4px"}}>{subs.length}</span>
                  )}
                </button>
                <button onClick={() => { if(!confirm(`Kategorie "${cat}" wirklich löschen?`)) return; onChange(categories.filter(c => c !== cat)); if (expanded === cat) setExpanded(null); }}
                  style={{background:"none",border:"none",color:"var(--col-text-sec)",fontSize:16}}>×</button>
              </div>
              {open && (
                <div style={{paddingLeft:10,borderLeft:"2px solid var(--col-border)",marginLeft:8,marginTop:4}}>
                  <div style={{display:"flex",flexWrap:"wrap",gap:5,marginBottom:8}}>
                    {CATEGORY_ICONS.map(icon => {
                      const sel = categoryIcons?.[cat] === icon;
                      return (
                        <button key={icon} title={icon} onClick={() => onIconChange(cat, sel ? null : icon)}
                          style={{width:28,height:28,padding:4,borderRadius:6,display:"flex",alignItems:"center",justifyContent:"center",
                            border: sel ? "2px solid var(--col-accent)" : "1px solid var(--col-border)",
                            background: sel ? cc.bg : "transparent"}}>
                          <img src={`kategorie-icons/${icon}.svg`} alt={icon} style={{width:16,height:16}}/>
                        </button>
                      );
                    })}
                  </div>
                  {subs.map(sub => (
                    <div key={sub} style={{display:"flex",alignItems:"center",gap:6,marginBottom:4}}>
                      <span style={{width:5,height:5,borderRadius:"50%",background:"var(--col-border)",flexShrink:0}}/>
                      <span style={{flex:1,fontSize:12,color:"var(--col-text)"}}>{sub}</span>
                      <button onClick={() => removeSub(cat, sub)}
                        style={{background:"none",border:"none",color:"var(--col-text-sec)",fontSize:13}}>×</button>
                    </div>
                  ))}
                  <div style={{display:"flex",gap:5,marginTop:4}}>
                    <input placeholder="Unterkategorie hinzufügen…" value={subInput}
                      onChange={e => setSubInput(e.target.value)}
                      onKeyDown={e => e.key === "Enter" && addSub(cat)}
                      style={{flex:1,fontSize:12}}/>
                    <button onClick={() => addSub(cat)}
                      style={{padding:"4px 8px",fontSize:11,borderRadius:6,background:"var(--col-accent)",color:"var(--col-bg)"}}>+</button>
                  </div>
                </div>
              )}
            </div>
          );
        })}
        <div style={{display:"flex",gap:6,marginTop:10}}>
          <input placeholder="Neue Kategorie…" value={input}
            onChange={e=>{setInput(e.target.value);setDupErr(false);}}
            onKeyDown={e => e.key === "Enter" && add()}
            style={{flex:1,fontSize:13,borderColor:dupErr?"#b91c1c":undefined}}/>
          <button onClick={add}
            style={{padding:"5px 10px",fontSize:12,borderRadius:6,background:"var(--col-accent)",color:"var(--col-bg)"}}>+ Add</button>
        </div>
        {dupErr&&<div style={{fontSize:11,color:"#b91c1c",marginTop:4}}>Kategorie existiert bereits.</div>}
        <button onClick={onClose}
          style={{marginTop:10,width:"100%",padding:"7px",fontSize:13,borderRadius:6,border:"1px solid var(--col-border)",color:"var(--col-text)"}}>Schliessen</button>
      </div>
    </div>
  );
}

// ── RecurringPicker ──────────────────────────────────────────────────
function RecurringPicker({ value, onChange, plannedDay }){
  const cur = value || { freq: null, days: [], endDate: null };
  const set = patch => onChange(patch.freq === null ? null : { ...cur, ...patch });
  const dayNames = ["Mo","Di","Mi","Do","Fr","Sa","So"];
  // Wochentag automatisch aus plannedDay ableiten (1=Mo … 7=So)
  const autoDay = (plannedDay && plannedDay !== "someday")
    ? ((new Date(plannedDay + "T12:00:00").getDay()) || 7)
    : null;
  const autoLabel = autoDay ? dayNames[autoDay - 1] : null;
  return (
    <div>
      <div style={{fontSize:11,fontWeight:500,color:"var(--col-text-sec)",textTransform:"uppercase",letterSpacing:"0.06em",marginBottom:5}}>Wiederholen</div>
      <div style={{display:"flex",gap:4,marginBottom:cur.freq?8:0}}>
        {[null,"daily","weekly"].map((t, i) => (
          <button key={i}
            onClick={() => {
              if(t==="weekly"&&autoDay) onChange({...cur,freq:"weekly",days:[autoDay]});
              else set({freq:t,days:cur.days,endDate:cur.endDate});
            }}
            style={{
              padding:"3px 10px", borderRadius:20, fontSize:12,
              border: cur.freq === t ? "2px solid var(--col-accent)" : "1px solid var(--col-border)",
              background: cur.freq === t ? "var(--col-accent)" : "transparent",
              color: cur.freq === t ? "var(--col-bg)" : "var(--col-text-sec)"
            }}>{["Nie","Täglich","Wöchentlich"][i]}</button>
        ))}
      </div>
      {cur.freq === "weekly" && autoLabel && (
        <div style={{fontSize:11,color:"var(--col-text-sec)",marginBottom:6,paddingLeft:2}}>
          Jeden <strong style={{color:"var(--col-text)"}}>{autoLabel}</strong>
        </div>
      )}
      {cur.freq === "weekly" && !autoLabel && (
        <div style={{display:"flex",gap:3,marginBottom:6}}>
          {dayNames.map((d, i) => {
            const idx = i + 1;
            const sel = cur.days.includes(idx);
            return (
              <button key={i}
                onClick={() => set({ days: sel ? cur.days.filter(x => x !== idx) : [...cur.days, idx] })}
                style={{
                  width:30, height:30, borderRadius:"50%", fontSize:11,
                  border: sel ? "2px solid var(--col-accent)" : "1px solid var(--col-border)",
                  background: sel ? "var(--col-accent)" : "transparent",
                  color: sel ? "var(--col-bg)" : "var(--col-text-sec)"
                }}>{d}</button>
            );
          })}
        </div>
      )}
      {cur.freq && (
        <div style={{display:"flex",flexDirection:"column",gap:6}}>
          <div style={{display:"flex",alignItems:"center",gap:6}}>
            <span style={{fontSize:11,color:"var(--col-text-sec)",minWidth:64}}>Reihe bis:</span>
            <input type="date" value={cur.endDate || ""} min={todayISO()}
              onChange={e => set({ endDate: e.target.value || null })}
              style={{fontSize:12,padding:"3px 6px"}}/>
            {cur.endDate && (
              <button onClick={() => set({ endDate: null })}
                style={{background:"none",border:"none",color:"var(--col-text-sec)",fontSize:14}}>×</button>
            )}
          </div>
          <div style={{display:"flex",alignItems:"center",gap:6}}>
            <span style={{fontSize:11,color:"var(--col-text-sec)",minWidth:64}}>Deadline +</span>
            <input type="number" min="0" max="14"
              value={cur.deadlineDays != null ? cur.deadlineDays : ""}
              placeholder="—"
              onChange={e => set({ deadlineDays: e.target.value !== "" ? parseInt(e.target.value) : null })}
              style={{fontSize:12,padding:"3px 6px",width:48}}/>
            <span style={{fontSize:11,color:"var(--col-text-sec)"}}>Tage</span>
            {cur.deadlineDays != null && (
              <button onClick={() => set({ deadlineDays: null })}
                style={{background:"none",border:"none",color:"var(--col-text-sec)",fontSize:14}}>×</button>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { Spinner, DatePicker, CatPicker, CatManager, RecurringPicker });

})();
