(() => {
  const { useState, useEffect, useRef } = React;
  const { Icon } = window.HiraIcons;
  const { CONTENT_OPTIONS } = window.HiraConstants;
  const HiraValidation = window.HiraValidation;
  const normalizeContentValue = HiraValidation.normalizeContentValue;
  const normalizeTag = HiraValidation.normalizeTag;

// ── TagPicker ─────────────────────────────────────────────────────────────────
function TagPicker({ selectedTags, onChange, allTags, T }) {
  const [open, setOpen] = useState(false);
  const [addingNew, setAddingNew] = useState(false);
  const [newTagInput, setNewTagInput] = useState("");
  const [tagSearch, setTagSearch] = useState("");
  const ref = useRef(null);

  useEffect(() => {
    const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, []);

  const toggle = (tag) => {
    if (selectedTags.includes(tag)) onChange(selectedTags.filter((t) => t !== tag));
    else onChange([...selectedTags, tag]);
  };

  const addNew = () => {
    const tag = normalizeTag(newTagInput);
    if (tag && !selectedTags.includes(tag)) onChange([...selectedTags, tag]);
    setNewTagInput("");
    setAddingNew(false);
  };

  return (
    <div ref={ref} className="relative mb-3">
      {/* Display area */}
      <div
        className={`flex flex-wrap gap-1.5 border rounded-lg px-3 py-2 cursor-pointer min-h-[42px] items-center ${T.inputBg}`}
        onClick={() => setOpen((v) => !v)}
      >
        {selectedTags.length === 0 && (
          <span className="text-sm opacity-40 flex items-center gap-1.5"><Icon.Tag />Pilih atau tambah tag...</span>
        )}
        {selectedTags.map((tag) => (
          <span key={tag} className="text-xs bg-amber-400/20 text-amber-400 rounded-full px-2.5 py-0.5 flex items-center gap-1 shrink-0">
            #{tag}
            <button
              onClick={(e) => { e.stopPropagation(); toggle(tag); }}
              className="hover:text-rose-400 leading-none text-base font-bold"
            >×</button>
          </span>
        ))}
        <Icon.ChevronDown className={`ml-auto shrink-0 opacity-40 transition-transform ${open ? "rotate-180" : ""}`} />
      </div>

      {/* Dropdown */}
      {open && (
        <div className={`absolute z-30 mt-1 w-full rounded-xl border shadow-xl overflow-hidden drop-enter ${T.dropdownBg}`}>
          {/* Tambah tag baru */}
          <div className={`px-3 py-2.5 border-b ${T.panel}`}>
            {addingNew ? (
              <div className="flex gap-2">
                <input
                  autoFocus
                  value={newTagInput}
                  onChange={(e) => setNewTagInput(e.target.value)}
                  onKeyDown={(e) => { if (e.key === "Enter") addNew(); if (e.key === "Escape") setAddingNew(false); }}
                  placeholder="Nama tag baru..."
                  className={`flex-1 text-xs px-2 py-1.5 rounded-lg border ${T.inputBg}`}
                />
                <button onClick={addNew} className="text-xs bg-amber-400 text-[#0a0c16] px-3 py-1.5 rounded-lg font-medium">Selesai</button>
                <button onClick={() => setAddingNew(false)} className={`text-xs px-2 py-1.5 rounded-lg border ${T.chipInactive}`}>Batal</button>
              </div>
            ) : (
              <button onClick={() => setAddingNew(true)} className="text-xs text-amber-400 font-medium flex items-center gap-1.5">
                <span className="text-base font-bold leading-none">+</span> Tambahkan tag baru
              </button>
            )}
          </div>

          {/* Search tag */}
          <div className={`px-3 py-2 border-b ${T.panel}`}>
            <div className={`flex items-center gap-2 border rounded-lg px-2.5 py-1.5 ${T.inputBg}`}>
              <Icon.Search className={`shrink-0 ${T.faint}`} />
              <input
                value={tagSearch}
                onChange={(e) => setTagSearch(e.target.value)}
                placeholder="Cari tag..."
                className="flex-1 bg-transparent outline-none text-xs"
              />
              {tagSearch && (
                <button onClick={() => setTagSearch("")} className={T.faint}>
                  <Icon.X />
                </button>
              )}
            </div>
          </div>

          {/* Daftar tag */}
          <div className="max-h-44 overflow-y-auto overscroll-contain">
            {allTags.length === 0 && (
              <p className={`text-xs ${T.sub} px-3 py-3 text-center`}>Belum ada tag tersimpan.</p>
            )}
            {(() => {
              const filtered = tagSearch.trim()
                ? allTags.filter(({ tag }) => tag.toLowerCase().includes(tagSearch.trim().toLowerCase()))
                : allTags;
              if (filtered.length === 0) return (
                <p className={`text-xs ${T.sub} px-3 py-3 text-center`}>Tag "{tagSearch}" tidak ditemukan.</p>
              );
              return filtered.map(({ tag, count }) => {
                const selected = selectedTags.includes(tag);
                return (
                  <button
                    key={tag}
                    onClick={() => toggle(tag)}
                    className={`w-full text-left px-3 py-2.5 text-sm flex items-center justify-between ${T.hoverSoft} ${selected ? "text-amber-400" : ""}`}
                  >
                    <span className="flex items-center gap-2">
                      {selected && <Icon.Check className="text-amber-400 shrink-0" />}
                      {!selected && <span className="w-3.5 shrink-0" />}
                      #{tag}
                    </span>
                    <span className={`text-xs ${selected ? "text-amber-400/70" : T.faint}`}>({count})</span>
                  </button>
                );
              });
            })()}
          </div>
        </div>
      )}
    </div>
  );
}

// ── ContentPicker ─────────────────────────────────────────────────────────────
// Content memakai pilihan tetap agar konsisten dengan filter Content, tidak bercampur
// dengan tag bebas yang dapat dibuat pengguna.
function ContentPicker({ selectedContent = [], onChange, T }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  const selected = [...new Set(selectedContent.map(normalizeContentValue).filter(Boolean))];

  useEffect(() => {
    const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, []);

  const labelFor = (value) => CONTENT_OPTIONS.find((option) => option.id === value)?.label || value;
  const toggle = (value) => {
    if (selected.includes(value)) onChange(selected.filter((item) => item !== value));
    else onChange([...selected, value]);
  };

  return (
    <div ref={ref} className="relative mb-3">
      <div
        className={`flex flex-wrap gap-1.5 border rounded-lg px-3 py-2 cursor-pointer min-h-[42px] items-center ${T.inputBg}`}
        onClick={() => setOpen((value) => !value)}
      >
        {selected.length === 0 && (
          <span className="text-sm opacity-40 flex items-center gap-1.5"><Icon.Filter />Pilih Content...</span>
        )}
        {selected.map((value) => (
          <span key={value} className="text-xs bg-sky-400/15 text-sky-400 rounded-full px-2.5 py-0.5 flex items-center gap-1 shrink-0">
            {labelFor(value)}
            <button
              onClick={(e) => { e.stopPropagation(); toggle(value); }}
              className="hover:text-rose-400 leading-none text-base font-bold"
              aria-label={`Hapus Content ${labelFor(value)}`}
            >×</button>
          </span>
        ))}
        <Icon.ChevronDown className={`ml-auto shrink-0 opacity-40 transition-transform ${open ? "rotate-180" : ""}`} />
      </div>

      {open && (
        <div className={`absolute z-30 mt-1 w-full rounded-xl border shadow-xl overflow-hidden drop-enter ${T.dropdownBg}`}>
          <p className={`px-3 py-2.5 border-b text-xs ${T.sub} ${T.panel}`}>
            Pilih satu atau beberapa Content.
          </p>
          <div className="max-h-52 overflow-y-auto overscroll-contain">
            {CONTENT_OPTIONS.map((option) => {
              const isSelected = selected.includes(option.id);
              return (
                <button
                  key={option.id}
                  onClick={() => toggle(option.id)}
                  className={`w-full text-left px-3 py-2.5 text-sm flex items-center justify-between ${T.hoverSoft} ${isSelected ? "text-sky-400" : ""}`}
                >
                  <span className="flex items-center gap-2">
                    {isSelected && <Icon.Check className="text-sky-400 shrink-0" />}
                    {!isSelected && <span className="w-3.5 shrink-0" />}
                    {option.label}
                  </span>
                </button>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}

// ── LibraryPicker ─────────────────────────────────────────────────────────────
function LibraryPicker({ value, newLibName, onSelect, onCreateNew, onClearNew, libraries, T, placeholder, hideNone }) {
  const [open, setOpen] = useState(false);
  const [search, setSearch] = useState("");
  const [creating, setCreating] = useState(false);
  const [nameInput, setNameInput] = useState("");
  const ref = useRef(null);

  useEffect(() => {
    const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) { setOpen(false); setCreating(false); } };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, []);

  const confirmCreate = () => {
    const validation = HiraValidation.validateLibraryName(nameInput);
    if (!validation.valid) return;
    onCreateNew(validation.value);
    setNameInput("");
    setCreating(false);
    setOpen(false);
  };

  const filtered = search.trim()
    ? libraries.filter(l => l.name.toLowerCase().includes(search.trim().toLowerCase()))
    : libraries;

  const selectedLib = libraries.find(l => l.id === value);
  const displayLabel = newLibName ? `${newLibName} (baru)` : selectedLib ? selectedLib.name : null;

  return (
    <div ref={ref} className="relative mb-4">
      <div onClick={() => setOpen(v => !v)}
        className={`flex items-center justify-between border rounded-lg px-3 py-2.5 cursor-pointer ${T.inputBg}`}>
        <span className={`text-sm truncate ${displayLabel ? "" : "opacity-40"}`}>
          {displayLabel || placeholder || "Tanpa koleksi (universal)"}
        </span>
        <div className="flex items-center gap-2 shrink-0 ml-2">
          {(value || newLibName) && !hideNone && (
            <button onClick={(e) => { e.stopPropagation(); onSelect(""); if (newLibName) onClearNew(); }}
              className={`${T.sub} hover:text-rose-400 transition-colors`}><Icon.X /></button>
          )}
          <Icon.ChevronDown className={`transition-transform duration-200 ${open ? "rotate-180" : ""} ${T.sub}`} />
        </div>
      </div>

      {open && (
        <div className={`absolute z-30 mt-1 w-full rounded-xl border shadow-xl overflow-hidden drop-enter ${T.dropdownBg}`}>
          {/* Tambah baru */}
          <div className={`px-3 py-2.5 border-b ${T.panel}`}>
            {creating ? (
              <div className="flex gap-2">
                <input autoFocus value={nameInput} onChange={e => setNameInput(e.target.value)}
                  onKeyDown={e => { if (e.key === "Enter") confirmCreate(); if (e.key === "Escape") setCreating(false); }}
                  placeholder="Nama koleksi baru..." className={`flex-1 text-xs px-2 py-1.5 rounded-lg border ${T.inputBg}`} />
                <button onClick={confirmCreate} className="text-xs bg-amber-400 text-[#0a0c16] px-3 py-1.5 rounded-lg font-medium">Selesai</button>
                <button onClick={() => setCreating(false)} className={`text-xs px-2 py-1.5 rounded-lg border ${T.chipInactive}`}>Batal</button>
              </div>
            ) : (
              <button onClick={() => setCreating(true)} className="text-xs text-amber-400 font-medium flex items-center gap-1.5">
                <span className="text-base font-bold leading-none">+</span> Koleksi baru
              </button>
            )}
          </div>
          {/* Search */}
          <div className={`px-3 py-2 border-b ${T.panel}`}>
            <div className={`flex items-center gap-2 border rounded-lg px-2.5 py-1.5 ${T.inputBg}`}>
              <Icon.Search className={`shrink-0 ${T.faint}`} />
              <input value={search} onChange={e => setSearch(e.target.value)}
                placeholder="Cari koleksi..." className="flex-1 bg-transparent outline-none text-xs" />
              {search && <button onClick={() => setSearch("")} className={T.faint}><Icon.X /></button>}
            </div>
          </div>
          {/* List */}
          <div className="max-h-44 overflow-y-auto overscroll-contain">
            {!hideNone && (
              <button onClick={() => { onSelect(""); if (newLibName) onClearNew(); setOpen(false); }}
                className={`w-full text-left px-3 py-2.5 text-sm flex items-center gap-2 ${T.hoverSoft} ${!value && !newLibName ? "text-amber-400" : ""}`}>
                {(!value && !newLibName) ? <Icon.Check className="text-amber-400 shrink-0" /> : <span className="w-3.5 shrink-0" />}
                Tanpa koleksi
              </button>
            )}
            {filtered.length === 0 && search.trim() && (
              <p className={`text-xs ${T.sub} px-3 py-3 text-center`}>"{search}" tidak ditemukan.</p>
            )}
            {filtered.map(l => {
              const isSel = !hideNone && value === l.id;
              return (
                <button key={l.id} onClick={() => { onSelect(l.id); setOpen(false); setSearch(""); }}
                  className={`w-full text-left px-3 py-2.5 text-sm flex items-center gap-2 ${T.hoverSoft} ${isSel ? "text-amber-400" : ""}`}>
                  {isSel ? <Icon.Check className="text-amber-400 shrink-0" /> : <span className="w-3.5 shrink-0" />}
                  {l.name}
                </button>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}


  window.HiraPickers = { TagPicker, ContentPicker, LibraryPicker };
})();
