/* ===== Shared UI components ===== */

function Avatar({ member, size = 32, ring = false }) {
  if (!member) return null;
  return (
    <div
      className="avatar"
      title={`${member.nick} · ${member.role}`}
      style={{
        width: size, height: size, background: member.color,
        fontSize: size * 0.42,
        boxShadow: ring ? "0 0 0 2.5px var(--surface), 0 0 0 4px " + member.color + "33" : "none",
      }}
    >
      {member.av}
    </div>
  );
}

function StatusBadge({ status }) {
  const s = STATUS_MAP[status];
  return (
    <span className="badge" style={{ background: s.soft, color: s.color }}>
      <span className="dot" style={{ background: s.color }}></span>
      {s.label}
    </span>
  );
}

function PriorityBadge({ priority, mini = false }) {
  const p = PRIORITY_MAP[priority];
  if (mini) {
    return (
      <span className="badge" style={{ background: p.soft, color: p.color, padding: "3px 8px", fontSize: 11.5 }}>
        <span className="dot" style={{ background: p.color }}></span>
        {p.th}
      </span>
    );
  }
  return (
    <span className="badge" style={{ background: p.soft, color: p.color }}>
      <span className="dot" style={{ background: p.color }}></span>
      {p.label} · {p.th}
    </span>
  );
}

function ProgressBar({ value, color = "var(--primary)", height = 8 }) {
  return (
    <div className="bar" style={{ height }}>
      <i style={{ width: Math.max(0, Math.min(100, value)) + "%", background: color }}></i>
    </div>
  );
}

// thin deadline chip used on cards / rows
function DeadlineChip({ dateStr, done }) {
  const info = deadlineInfo(dateStr);
  if (done) {
    return (
      <span style={chipStyle("#e2f7f0", "var(--done)")}>
        <CalIcon /> {fmtDate(dateStr)}
      </span>
    );
  }
  const tones = {
    over:  ["var(--high-soft)", "var(--high)"],
    today: ["var(--review-soft)", "#d2890f"],
    soon:  ["var(--review-soft)", "#d2890f"],
    ok:    ["var(--surface-soft)", "var(--ink-2)"],
  };
  const [bg, fg] = tones[info.tone];
  const urgent = info.tone === "over" || info.tone === "today";
  return (
    <span style={chipStyle(bg, fg)}>
      {urgent ? <AlertIcon /> : <CalIcon />} {info.label}
    </span>
  );
}
function chipStyle(bg, fg) {
  return {
    display: "inline-flex", alignItems: "center", gap: 5,
    background: bg, color: fg, fontSize: 12, fontWeight: 600,
    padding: "4px 9px", borderRadius: 8,
  };
}

/* ===== Member picker: type-to-search combobox ===== */
function MemberPicker({ value, onChange, members, onManage, disabled, placeholder = "พิมพ์ชื่อหรือเลือกจากรายการ", allowClear = false }) {
  const { useState: useS, useRef: useR, useEffect: useE } = React;
  const current = members.find(m => m.id === value);
  const [open, setOpen] = useS(false);
  const [query, setQuery] = useS("");
  const wrapRef = useR(null);

  useE(() => {
    if (!open) return;
    const onDoc = (e) => { if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);

  const q = query.trim().toLowerCase();
  const filtered = q
    ? members.filter(m => (m.nick + " " + m.name + " " + m.role).toLowerCase().includes(q))
    : members;

  const pick = (m) => { onChange(m.id); setOpen(false); setQuery(""); };

  const displayText = open
    ? query
    : (current ? `${current.nick} — ${current.name}` : "");

  return (
    <div ref={wrapRef} style={mpStyles.wrap}>
      <div style={{ ...mpStyles.field, opacity: disabled ? .6 : 1, pointerEvents: disabled ? "none" : "auto" }}
        onClick={() => { if (!open) { setOpen(true); setQuery(""); } }}>
        {current && !open && <Avatar member={current} size={24} />}
        <input
          value={displayText}
          onChange={(e) => { setQuery(e.target.value); setOpen(true); }}
          onFocus={() => setOpen(true)}
          placeholder={placeholder}
          style={mpStyles.input}
          disabled={disabled}
        />
        {allowClear && current && !open && (
          <button onClick={(e) => { e.stopPropagation(); onChange(null); }} style={mpStyles.clear} title="ล้าง">
            <CloseIcon />
          </button>
        )}
        <span style={mpStyles.caret}><ChevronDown /></span>
      </div>
      {open && (
        <div className="scroll" style={mpStyles.menu}>
          {filtered.map(m => {
            const sel = m.id === value;
            return (
              <button key={m.id} onClick={() => pick(m)}
                style={{ ...mpStyles.option, background: sel ? "var(--primary-soft)" : "transparent" }}
                onMouseEnter={(e) => { if (!sel) e.currentTarget.style.background = "var(--surface-soft)"; }}
                onMouseLeave={(e) => { if (!sel) e.currentTarget.style.background = "transparent"; }}>
                <Avatar member={m} size={28} />
                <div style={{ minWidth: 0, textAlign: "left", flex: 1 }}>
                  <div style={{ fontSize: 14, fontWeight: 600, color: "var(--ink)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                    {m.nick} <span style={{ color: "var(--ink-3)", fontWeight: 500 }}>· {m.name}</span>
                  </div>
                  <div style={{ fontSize: 11.5, color: "var(--ink-3)" }}>{m.role}</div>
                </div>
                {sel && <span style={{ fontSize: 11, fontWeight: 700, color: "var(--primary)" }}>✓</span>}
              </button>
            );
          })}
          {filtered.length === 0 && (
            <div style={mpStyles.empty}>
              ไม่พบสมาชิกที่ตรงกับ “{query}”
              {onManage && (
                <div style={{ marginTop: 8 }}>
                  <button className="btn btn-soft" style={{ padding: "7px 12px", fontSize: 12.5 }}
                    onClick={() => { setOpen(false); onManage(query); }}>
                    <PlusIcon /> เพิ่มสมาชิกใหม่
                  </button>
                </div>
              )}
            </div>
          )}
          {onManage && filtered.length > 0 && (
            <button onClick={() => { setOpen(false); onManage(); }} style={mpStyles.manageRow}>
              <UsersIcon /> จัดการรายชื่อทีม…
            </button>
          )}
        </div>
      )}
    </div>
  );
}

const mpStyles = {
  wrap: { position: "relative", width: "100%" },
  field: {
    display: "flex", alignItems: "center", gap: 8,
    border: "1.5px solid var(--line)", borderRadius: 11, padding: "7px 10px 7px 12px",
    background: "var(--surface)", cursor: "text", minHeight: 44,
  },
  input: {
    flex: 1, minWidth: 0, border: 0, outline: 0, background: "transparent",
    fontSize: 14.5, color: "var(--ink)", padding: "4px 0",
  },
  caret: { color: "var(--ink-3)", display: "flex", flex: "none" },
  clear: {
    width: 24, height: 24, border: 0, borderRadius: 6, background: "transparent",
    color: "var(--ink-3)", display: "grid", placeItems: "center", flex: "none",
  },
  menu: {
    position: "absolute", top: "calc(100% + 6px)", left: 0, right: 0, zIndex: 50,
    background: "var(--surface)", borderRadius: 13, boxShadow: "var(--shadow-lg)",
    border: "1px solid var(--line-soft)", padding: 6, maxHeight: 280, overflowY: "auto",
  },
  option: {
    width: "100%", display: "flex", alignItems: "center", gap: 10,
    border: 0, padding: "8px 9px", borderRadius: 9, cursor: "pointer", transition: ".1s",
    textAlign: "left",
  },
  empty: { padding: "16px 12px", fontSize: 13, color: "var(--ink-3)", textAlign: "center" },
  manageRow: {
    width: "100%", display: "flex", alignItems: "center", gap: 8, justifyContent: "center",
    border: 0, padding: "10px", borderRadius: 9, cursor: "pointer",
    fontSize: 12.5, fontWeight: 600, color: "var(--primary)", background: "transparent",
    borderTop: "1px solid var(--line-soft)", marginTop: 4,
  },
};

/* ===== tiny inline icons ===== */
function CalIcon() {
  return (
    <svg width="13" height="13" viewBox="0 0 24 24" fill="none">
      <rect x="3" y="5" width="18" height="16" rx="3" stroke="currentColor" strokeWidth="2"/>
      <path d="M3 9h18M8 3v4M16 3v4" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
    </svg>
  );
}
function AlertIcon() {
  return (
    <svg width="13" height="13" viewBox="0 0 24 24" fill="none">
      <path d="M12 3l9 16H3l9-16z" stroke="currentColor" strokeWidth="2" strokeLinejoin="round"/>
      <path d="M12 10v4M12 17v.5" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
    </svg>
  );
}
function PlusIcon() {
  return (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
      <path d="M12 5v14M5 12h14" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round"/>
    </svg>
  );
}
function CloseIcon() {
  return (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
      <path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
    </svg>
  );
}
function GridIcon() {
  return (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
      <rect x="3" y="3" width="7" height="7" rx="1.6" fill="currentColor"/>
      <rect x="14" y="3" width="7" height="7" rx="1.6" fill="currentColor" opacity=".5"/>
      <rect x="3" y="14" width="7" height="7" rx="1.6" fill="currentColor" opacity=".5"/>
      <rect x="14" y="14" width="7" height="7" rx="1.6" fill="currentColor"/>
    </svg>
  );
}
function BoardIcon() {
  return (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
      <rect x="3" y="4" width="5" height="16" rx="1.6" fill="currentColor"/>
      <rect x="10" y="4" width="5" height="11" rx="1.6" fill="currentColor" opacity=".55"/>
      <rect x="17" y="4" width="4" height="14" rx="1.6" fill="currentColor" opacity=".55"/>
    </svg>
  );
}
function PencilIcon({ size = 13 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
      <path d="M4 20h4l10-10-4-4L4 16v4z" stroke="currentColor" strokeWidth="2" strokeLinejoin="round"/>
      <path d="M14 6l4 4" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
    </svg>
  );
}
function UsersIcon() {
  return (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
      <circle cx="9" cy="8" r="3.4" stroke="currentColor" strokeWidth="1.8"/>
      <path d="M3 19c0-3 2.7-5.2 6-5.2S15 16 15 19" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
      <circle cx="17" cy="9" r="2.6" stroke="currentColor" strokeWidth="1.8"/>
      <path d="M15.5 14.2c.5-.1 1-.2 1.6-.2 2.7 0 4.5 1.6 4.5 3.8" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
    </svg>
  );
}
function TrashIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
      <path d="M5 7h14M10 7V5a1 1 0 011-1h2a1 1 0 011 1v2M7 7l1 12a2 2 0 002 2h4a2 2 0 002-2l1-12" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}
function SearchIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
      <circle cx="11" cy="11" r="6" stroke="currentColor" strokeWidth="1.8"/>
      <path d="M16 16l4 4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
    </svg>
  );
}
function ChevronDown() {
  return (
    <svg width="12" height="12" viewBox="0 0 12 8" fill="none">
      <path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}
function ReportIcon() {
  return (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
      <rect x="4" y="3" width="16" height="18" rx="2.4" stroke="currentColor" strokeWidth="2"/>
      <path d="M8 8h8M8 12h8M8 16h5" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
    </svg>
  );
}

Object.assign(window, {
  Avatar, StatusBadge, PriorityBadge, ProgressBar, DeadlineChip, MemberPicker,
  CalIcon, AlertIcon, PlusIcon, PencilIcon, UsersIcon, TrashIcon, SearchIcon, ChevronDown, CloseIcon, GridIcon, BoardIcon, ReportIcon,
});
