"use client";

/**
 * ConfigPanel 프리미티브 (시안 panel-input-new 의 CP* 포팅)
 * - inline style 위주 (시안의 토큰 활용 패턴 보존)
 * - v5 토큰만 사용. 라이트/다크 모두 자동 대응
 */
import React from "react";
import { createPortal } from "react-dom";
import { CP_ICONS } from "./icons";

const CP_FONT = "var(--v5-font-sans)";
const CP_MONO = "var(--v5-font-mono)";

// ── Section ──────────────────────────────────────────────
export function CPSection({
  title,
  desc,
  tone = "default",
  children,
  style,
}: {
  title: React.ReactNode;
  desc?: React.ReactNode;
  tone?: "default" | "solid";
  children?: React.ReactNode;
  style?: React.CSSProperties;
}) {
  return (
    <div
      style={{
        marginBottom: 8,
        marginTop: 2,
        ...style,
      }}
    >
      {tone === "solid" ? (
        <div
          style={{
            display: "flex",
            alignItems: "baseline",
            flexWrap: "wrap",
            gap: "4px 8px",
            padding: "6px 10px",
            background: "rgba(var(--v5-primary-rgb), 0.05)",
            border: "1px solid var(--cp-border)",
            borderRadius: 8,
            marginBottom: 10,
          }}
        >
          <span style={{ fontSize: 11, fontWeight: 700, letterSpacing: "0.04em", color: "var(--cp-text)", whiteSpace: "nowrap" }}>
            {title}
          </span>
          {desc && <span style={{ fontSize: 11, color: "var(--cp-text-muted)", minWidth: 0 }}>{desc}</span>}
        </div>
      ) : (
        <div
          style={{
            display: "flex",
            alignItems: "baseline",
            flexWrap: "wrap",
            gap: "2px 8px",
            padding: "0 0 4px",
            marginBottom: 6,
            backgroundImage:
              "linear-gradient(to right, rgba(var(--v5-primary-rgb), 0.55), transparent 75%)",
            backgroundSize: "100% 1px",
            backgroundPosition: "bottom left",
            backgroundRepeat: "no-repeat",
          }}
        >
          <span
            style={{
              fontSize: 12,
              fontWeight: 700,
              letterSpacing: "-0.01em",
              color: "var(--cp-text)",
              whiteSpace: "nowrap",
            }}
          >
            {title}
          </span>
          {desc && (
            <span
              style={{
                fontSize: 10.5,
                color: "var(--cp-text-muted)",
                letterSpacing: 0,
                minWidth: 0,
                lineHeight: 1.4,
              }}
            >
              · {desc}
            </span>
          )}
        </div>
      )}
      <div>{children}</div>
    </div>
  );
}

// ── Row (label 좌, control 우) ───────────────────────────
export function CPRow({
  label,
  help,
  required,
  advanced,
  children,
  align = "center",
}: {
  label: React.ReactNode;
  help?: React.ReactNode;
  required?: boolean;
  advanced?: boolean;
  children?: React.ReactNode;
  align?: "center" | "top";
}) {
  return (
    <div
      style={{
        display: "grid",
        gridTemplateColumns: "minmax(60px, 80px) minmax(0, 1fr)",
        gap: 8,
        alignItems: align === "top" ? "flex-start" : "center",
        padding: "5px 0",
        minHeight: 28,
      }}
    >
      <div
        style={{
          fontSize: 11.5,
          fontWeight: 600,
          color: "var(--cp-text-sec)",
          lineHeight: 1.3,
          paddingTop: align === "top" ? 6 : 0,
          display: "flex",
          alignItems: "center",
          gap: 3,
          flexWrap: "wrap",
          wordBreak: "keep-all",
        }}
      >
        <span>{label}</span>
        {required && <span style={{ color: "var(--v5-red)", fontWeight: 700 }}>*</span>}
        {advanced && (
          <span
            style={{
              fontSize: 9,
              fontWeight: 700,
              letterSpacing: "0.08em",
              color: "var(--cp-text-muted)",
              textTransform: "uppercase",
              padding: "1px 4px",
              border: "1px solid var(--cp-border)",
              borderRadius: 3,
            }}
          >
            PRO
          </span>
        )}
      </div>
      <div style={{ minWidth: 0 }}>
        {children}
        {help && (
          <div style={{ fontSize: 10.5, color: "var(--cp-text-muted)", marginTop: 4, lineHeight: 1.4 }}>{help}</div>
        )}
      </div>
    </div>
  );
}

// label 위 / control 아래
export function CPStacked({
  label,
  help,
  required,
  advanced,
  children,
}: {
  label: React.ReactNode;
  help?: React.ReactNode;
  required?: boolean;
  advanced?: boolean;
  children?: React.ReactNode;
}) {
  return (
    <div style={{ padding: "4px 0", marginBottom: 6 }}>
      <div
        style={{
          fontSize: 11,
          fontWeight: 600,
          color: "var(--cp-text-sec)",
          marginBottom: 5,
          display: "flex",
          alignItems: "center",
          gap: 4,
        }}
      >
        <span>{label}</span>
        {required && <span style={{ color: "var(--v5-red)" }}>*</span>}
        {advanced && (
          <span
            style={{
              fontSize: 9,
              fontWeight: 700,
              letterSpacing: "0.08em",
              color: "var(--cp-text-muted)",
              textTransform: "uppercase",
              padding: "1px 4px",
              border: "1px solid var(--cp-border)",
              borderRadius: 3,
              marginLeft: "auto",
            }}
          >
            PRO
          </span>
        )}
      </div>
      {children}
      {help && <div style={{ fontSize: 10.5, color: "var(--cp-text-muted)", marginTop: 4, lineHeight: 1.4 }}>{help}</div>}
    </div>
  );
}

// ── Inputs ──────────────────────────────────────────────
const inputBaseStyle: React.CSSProperties = {
  width: "100%",
  boxSizing: "border-box",
  height: 28,
  padding: "0 8px",
  fontSize: 12,
  fontFamily: CP_FONT,
  background: "var(--cp-surface)",
  border: "1px solid var(--cp-border)",
  borderRadius: 6,
  color: "var(--cp-text)",
  outline: "none",
  transition: "border-color .15s, box-shadow .15s",
};

type CPTextProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "prefix"> & {
  value?: string | number;
  onChange?: (value: string) => void;
  placeholder?: string;
  mono?: boolean;
  suffix?: React.ReactNode;
  prefix?: React.ReactNode;
};

export function CPText({ value, onChange, placeholder, mono, suffix, prefix, ...rest }: CPTextProps) {
  const [focus, setFocus] = React.useState(false);
  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        border: focus ? "1px solid var(--v5-primary)" : "1px solid var(--cp-border)",
        borderRadius: 6,
        boxShadow: focus ? "0 0 0 3px rgba(var(--v5-primary-rgb),0.12)" : "none",
        background: "var(--cp-surface)",
        height: 28,
        transition: "border-color .15s, box-shadow .15s",
        overflow: "hidden",
      }}
    >
      {prefix && (
        <div
          style={{
            padding: "0 8px",
            fontSize: 11,
            color: "var(--cp-text-muted)",
            borderRight: "1px solid var(--cp-border-subtle)",
            height: "100%",
            display: "flex",
            alignItems: "center",
          }}
        >
          {prefix}
        </div>
      )}
      <input
        {...rest}
        value={value ?? ""}
        onChange={(e) => onChange && onChange(e.target.value)}
        placeholder={placeholder}
        onFocus={(e) => {
          setFocus(true);
          rest.onFocus?.(e);
        }}
        onBlur={(e) => {
          setFocus(false);
          rest.onBlur?.(e);
        }}
        style={{
          flex: 1,
          minWidth: 0,
          border: "none",
          outline: "none",
          background: "transparent",
          height: "100%",
          padding: "0 8px",
          fontSize: 12,
          fontFamily: mono ? CP_MONO : CP_FONT,
          color: "var(--cp-text)",
        }}
      />
      {suffix && (
        <div
          style={{
            padding: "0 8px",
            fontSize: 11,
            color: "var(--cp-text-muted)",
            borderLeft: "1px solid var(--cp-border-subtle)",
            height: "100%",
            display: "flex",
            alignItems: "center",
          }}
        >
          {suffix}
        </div>
      )}
    </div>
  );
}

type CPSelectOption = { value: string; label: React.ReactNode; disabled?: boolean };

type CPSelectProps = Omit<React.SelectHTMLAttributes<HTMLSelectElement>, "value" | "onChange"> & {
  value?: string;
  onChange?: (value: string) => void;
  children?: React.ReactNode;
  options?: CPSelectOption[];
  placeholder?: string;
  /** 검색 박스 노출. 명시 안 하면 옵션 ≥ 12 일 때 자동 */
  searchable?: boolean;
  /** 옵션 정렬 (label≠value 우선 + ko collator). 명시 안 하면 옵션 ≥ 8 일 때 자동 */
  sortable?: boolean;
};

// children 으로 들어온 <option> 엘리먼트들을 옵션 배열로 평탄화
function parseOptionChildren(children: React.ReactNode): CPSelectOption[] {
  const out: CPSelectOption[] = [];
  React.Children.forEach(children, (child) => {
    if (!React.isValidElement(child)) return;
    const el = child as React.ReactElement<{
      value?: string | number;
      children?: React.ReactNode;
      disabled?: boolean;
    }>;
    if (el.type === "option") {
      out.push({
        value: String(el.props.value ?? ""),
        label: el.props.children ?? String(el.props.value ?? ""),
        disabled: el.props.disabled,
      });
    } else if (el.type === "optgroup") {
      // optgroup 안의 option 들을 재귀로 평탄화 (label 은 무시)
      out.push(...parseOptionChildren(el.props.children));
    }
  });
  return out;
}

export function CPSelect({
  value,
  onChange,
  children,
  options,
  placeholder,
  disabled,
  searchable,
  sortable,
  ...rest
}: CPSelectProps) {
  const opts: CPSelectOption[] = options ?? parseOptionChildren(children);
  const [open, setOpen] = React.useState(false);
  const [query, setQuery] = React.useState("");
  const wrapRef = React.useRef<HTMLDivElement>(null);
  const popRef = React.useRef<HTMLDivElement>(null);
  const listRef = React.useRef<HTMLDivElement>(null);
  const searchInputRef = React.useRef<HTMLInputElement>(null);

  // popover 좌표 (Portal — overflow:hidden/auto 컨테이너 안에서 잘리지 않도록)
  const [popPos, setPopPos] = React.useState<{ top: number; left: number; width: number } | null>(null);
  React.useLayoutEffect(() => {
    if (!open || !wrapRef.current) {
      setPopPos(null);
      return;
    }
    const rect = wrapRef.current.getBoundingClientRect();
    setPopPos({ top: rect.bottom + 2, left: rect.left, width: rect.width });
  }, [open]);
  React.useEffect(() => {
    if (!open) return;
    // scroll/resize 시 popup 위치를 trigger 에 맞춰 재계산 (이전에는 무조건 close → dropdown 안 스크롤 불가능)
    // trigger 가 viewport 밖으로 나가면 그때만 close.
    const updatePos = () => {
      if (!wrapRef.current) return;
      const rect = wrapRef.current.getBoundingClientRect();
      if (rect.bottom < 0 || rect.top > window.innerHeight) {
        setOpen(false);
        return;
      }
      setPopPos({ top: rect.bottom + 2, left: rect.left, width: rect.width });
    };
    window.addEventListener("scroll", updatePos, true);
    window.addEventListener("resize", updatePos);
    return () => {
      window.removeEventListener("scroll", updatePos, true);
      window.removeEventListener("resize", updatePos);
    };
  }, [open]);

  // 첫 옵션이 빈값이면 placeholder 후보로 사용 (호환: <option value="">선택...</option>)
  const firstEmpty = opts.find((o) => o.value === "");
  const placeholderText =
    placeholder ??
    (typeof firstEmpty?.label === "string" ? firstEmpty.label : "선택");
  const realOpts = opts.filter((o) => o.value !== "");

  // 자동 결정 — 명시 prop 우선, 없으면 옵션 수 기반
  const useSearch = searchable ?? realOpts.length >= 12;
  const useSort = sortable ?? realOpts.length >= 8;

  const collator = React.useMemo(() => new Intl.Collator("ko"), []);

  // 정렬: label !== value 우선 → ko collator (영어/한글 발음순)
  const sortedOpts = React.useMemo(() => {
    if (!useSort) return realOpts;
    return [...realOpts].sort((a, b) => {
      const aText = typeof a.label === "string" ? a.label : a.value;
      const bText = typeof b.label === "string" ? b.label : b.value;
      const aLabeled = aText !== a.value;
      const bLabeled = bText !== b.value;
      if (aLabeled && !bLabeled) return -1;
      if (!aLabeled && bLabeled) return 1;
      return collator.compare(aText, bText);
    });
  }, [realOpts, useSort, collator]);

  // 검색 필터
  const visibleOpts = React.useMemo(() => {
    if (!query) return sortedOpts;
    const q = query.toLowerCase();
    return sortedOpts.filter((o) => {
      const text = typeof o.label === "string" ? o.label : o.value;
      return text.toLowerCase().includes(q);
    });
  }, [sortedOpts, query]);

  const current = realOpts.find((o) => o.value === value);
  const showPlaceholder = !current;

  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e: MouseEvent) => {
      const t = e.target as Node;
      if (
        wrapRef.current && !wrapRef.current.contains(t) &&
        popRef.current && !popRef.current.contains(t)
      ) {
        setOpen(false);
      }
    };
    const onEsc = (e: KeyboardEvent) => {
      if (e.key === "Escape") {
        if (query) setQuery("");
        else setOpen(false);
      }
    };
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("keydown", onEsc);
    return () => {
      document.removeEventListener("mousedown", onDoc);
      document.removeEventListener("keydown", onEsc);
    };
  }, [open, query]);

  // 열릴 때 active 항목으로 스크롤 + 검색 input 포커스
  React.useEffect(() => {
    if (!open) {
      setQuery("");
      return;
    }
    if (useSearch && searchInputRef.current) {
      searchInputRef.current.focus();
    }
    if (listRef.current) {
      const active = listRef.current.querySelector('[data-active="true"]') as HTMLElement | null;
      if (active) active.scrollIntoView({ block: "nearest" });
    }
  }, [open, useSearch]);

  return (
    <div ref={wrapRef} style={{ position: "relative", width: "100%" }}>
      <button
        type="button"
        disabled={disabled}
        onClick={() => !disabled && setOpen((v) => !v)}
        data-state={open ? "open" : "closed"}
        className="cp-select-trigger"
        {...(rest as any)}
        style={{
          ...inputBaseStyle,
          display: "flex",
          alignItems: "center",
          textAlign: "left",
          paddingRight: 24,
          cursor: disabled ? "not-allowed" : "pointer",
          color: showPlaceholder ? "var(--cp-text-muted)" : "var(--cp-text)",
          backgroundImage:
            "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10' fill='none' stroke='%239998ad' stroke-width='1.6' stroke-linecap='round'><path d='M2 3.5l3 3 3-3'/></svg>\")",
          backgroundRepeat: "no-repeat",
          backgroundPosition: "right 8px center",
          opacity: disabled ? 0.5 : 1,
          fontFamily: CP_FONT,
        }}
      >
        <span
          style={{
            flex: 1,
            minWidth: 0,
            overflow: "hidden",
            textOverflow: "ellipsis",
            whiteSpace: "nowrap",
          }}
        >
          {showPlaceholder ? placeholderText : current?.label}
        </span>
      </button>
      {open && popPos && typeof document !== "undefined" && createPortal(
        <div
          ref={popRef}
          style={{
            position: "fixed",
            top: popPos.top,
            left: popPos.left,
            width: popPos.width,
            zIndex: 9999,
            background: "var(--cp-surface)",
            border: "1px solid var(--cp-border)",
            borderRadius: 4,
            boxShadow: "0 8px 22px rgba(0,0,0,0.18)",
            padding: 4,
            color: "var(--cp-text)",
            animation: "cp-pop 0.14s var(--v5-ease-enter)",
          }}
        >
          {useSearch && (
            <div className="cp-select-search">
              <input
                ref={searchInputRef}
                type="text"
                className="cp-select-search-input"
                placeholder="검색..."
                value={query}
                onChange={(e) => setQuery(e.target.value)}
              />
            </div>
          )}
          <div
            ref={listRef}
            style={{
              maxHeight: useSearch ? 240 : 280,
              overflowY: "auto",
              display: "flex",
              flexDirection: "column",
            }}
          >
            {/* placeholder (값 = '') 가 children 으로 들어왔으면 첫 항목으로 노출, 클릭 시 onChange("") */}
            {firstEmpty && !query && (
              <>
                <CPSelectItem
                  option={firstEmpty}
                  active={!current}
                  index={0}
                  placeholder
                  onPick={(v) => {
                    onChange?.(v);
                    setOpen(false);
                  }}
                />
                {visibleOpts.length > 0 && (
                  <div
                    aria-hidden="true"
                    style={{
                      height: 1,
                      margin: "2px 4px 4px",
                      background: "var(--cp-border-subtle)",
                      flex: "0 0 auto",
                    }}
                  />
                )}
              </>
            )}
            {visibleOpts.map((o, i) => (
              <CPSelectItem
                key={o.value}
                option={o}
                active={o.value === value}
                index={i + (firstEmpty && !query ? 1 : 0)}
                onPick={(v) => {
                  onChange?.(v);
                  setOpen(false);
                }}
              />
            ))}
            {visibleOpts.length === 0 && (
              <div
                style={{
                  padding: "8px",
                  fontSize: 11,
                  color: "var(--cp-text-muted)",
                  textAlign: "center",
                }}
              >
                {query ? `"${query}" 결과 없음` : "옵션이 없습니다"}
              </div>
            )}
          </div>
        </div>,
        document.body
      )}
    </div>
  );
}

function CPSelectItem({
  option,
  active,
  onPick,
  index,
  placeholder,
}: {
  option: CPSelectOption;
  active: boolean;
  onPick: (v: string) => void;
  index?: number;
  placeholder?: boolean;
}) {
  // stagger delay — index 가 너무 커지면 cap (대량 옵션 시 오래 끌림 방지)
  const delay = index != null ? Math.min(index, 18) * 12 : 0;
  return (
    <button
      type="button"
      disabled={option.disabled}
      data-active={active}
      data-placeholder={placeholder ? "true" : undefined}
      onClick={() => !option.disabled && onPick(option.value)}
      className="cp-select-item"
      style={{
        display: "block",
        width: "100%",
        flex: "0 0 auto",
        textAlign: "left",
        padding: placeholder ? "4px 8px 4px 6px" : "5px 8px 5px 6px",
        fontSize: placeholder ? 11 : 12,
        lineHeight: 1.5,
        minHeight: placeholder ? 22 : 26,
        fontFamily: CP_FONT,
        fontStyle: placeholder ? "italic" : "normal",
        fontWeight: placeholder ? 400 : active ? 700 : 500,
        background: active ? "rgba(var(--v5-primary-rgb), 0.10)" : "transparent",
        border: "none",
        borderLeft: active ? "2px solid rgb(var(--v5-primary-rgb))" : "2px solid transparent",
        borderRadius: 0,
        cursor: option.disabled ? "not-allowed" : "pointer",
        opacity: option.disabled ? 0.5 : placeholder ? 0.7 : 1,
        whiteSpace: "nowrap",
        overflow: "hidden",
        textOverflow: "ellipsis",
        transition: "background .12s, color .12s, opacity .12s",
        animationDelay: `${delay}ms`,
      }}
      onMouseEnter={(e) => {
        const btn = e.currentTarget as HTMLButtonElement;
        if (!active && !option.disabled) btn.style.background = "var(--cp-surface-hover)";
      }}
      onMouseLeave={(e) => {
        const btn = e.currentTarget as HTMLButtonElement;
        if (!active) btn.style.background = "transparent";
      }}
    >
      {option.label}
    </button>
  );
}

type CPTextareaProps = Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "value" | "onChange"> & {
  value?: string;
  onChange?: (value: string) => void;
  rows?: number;
  mono?: boolean;
};

export function CPTextarea({ value, onChange, placeholder, rows = 3, mono, ...rest }: CPTextareaProps) {
  const [focus, setFocus] = React.useState(false);
  return (
    <textarea
      {...rest}
      value={value ?? ""}
      onChange={(e) => onChange && onChange(e.target.value)}
      placeholder={placeholder}
      rows={rows}
      onFocus={(e) => {
        setFocus(true);
        rest.onFocus?.(e);
      }}
      onBlur={(e) => {
        setFocus(false);
        rest.onBlur?.(e);
      }}
      style={{
        ...inputBaseStyle,
        height: "auto",
        minHeight: 28 * rows,
        padding: 8,
        resize: "vertical",
        lineHeight: 1.45,
        fontFamily: mono ? CP_MONO : CP_FONT,
        borderColor: focus ? "var(--v5-primary)" : "var(--cp-border)",
        boxShadow: focus ? "0 0 0 3px rgba(var(--v5-primary-rgb),0.12)" : "none",
      }}
    />
  );
}

export function CPSwitch({
  value,
  onChange,
  labels,
}: {
  value?: boolean;
  onChange?: (next: boolean) => void;
  labels?: [string, string];
}) {
  const v = !!value;
  return (
    <label style={{ display: "inline-flex", alignItems: "center", gap: 8, cursor: "pointer", userSelect: "none" }}>
      <div
        style={{
          width: 28,
          height: 16,
          borderRadius: 999,
          background: v ? "var(--v5-primary)" : "rgba(var(--v5-primary-rgb),0.15)",
          position: "relative",
          transition: "background .15s",
          boxShadow: v ? "0 0 8px rgba(var(--v5-primary-rgb),0.35)" : "none",
        }}
      >
        <div
          style={{
            width: 12,
            height: 12,
            borderRadius: 999,
            background: "#fff",
            position: "absolute",
            top: 2,
            left: v ? 14 : 2,
            transition: "left .18s var(--v5-ease-enter)",
            boxShadow: "0 1px 2px rgba(0,0,0,0.15)",
          }}
        />
      </div>
      {labels && <span style={{ fontSize: 11, color: "var(--cp-text-sec)" }}>{v ? labels[0] : labels[1]}</span>}
      <input
        type="checkbox"
        checked={v}
        onChange={(e) => onChange && onChange(e.target.checked)}
        style={{ position: "absolute", opacity: 0, pointerEvents: "none" }}
      />
    </label>
  );
}

export function CPNumber({
  value,
  onChange,
  placeholder,
  min,
  max,
  step,
  suffix,
}: {
  value?: number | "";
  onChange?: (next: number | undefined) => void;
  placeholder?: string;
  min?: number;
  max?: number;
  step?: number;
  suffix?: React.ReactNode;
}) {
  return (
    <CPText
      type="number"
      mono
      value={value as any}
      onChange={(v) => onChange && onChange(v === "" ? undefined : Number(v))}
      placeholder={placeholder}
      min={min}
      max={max}
      step={step}
      suffix={suffix}
    />
  );
}

export function CPColor({ value, onChange }: { value?: string; onChange?: (next: string) => void }) {
  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        border: "1px solid var(--cp-border)",
        borderRadius: 6,
        background: "var(--cp-surface)",
        height: 28,
        overflow: "hidden",
      }}
    >
      <div
        style={{
          width: 26,
          height: "100%",
          background: value || "#ffffff",
          borderRight: "1px solid var(--cp-border-subtle)",
          position: "relative",
          cursor: "pointer",
        }}
      >
        <input
          type="color"
          value={value || "#6c5ce7"}
          onChange={(e) => onChange && onChange(e.target.value)}
          style={{ position: "absolute", inset: 0, opacity: 0, cursor: "pointer" }}
        />
      </div>
      <input
        value={value || ""}
        onChange={(e) => onChange && onChange(e.target.value)}
        placeholder="#6c5ce7"
        style={{
          flex: 1,
          border: "none",
          outline: "none",
          background: "transparent",
          height: "100%",
          padding: "0 8px",
          fontSize: 11.5,
          fontFamily: CP_MONO,
          color: "var(--cp-text)",
          textTransform: "uppercase",
        }}
      />
    </div>
  );
}

// 작은 enum 용 (size, align, variant 등) — 평면 toolbar 스타일 (외곽/내부 박스 없음)
type CPSegmentOption = string | { value: string; label: React.ReactNode };
export function CPSegment({
  value,
  onChange,
  options,
}: {
  value?: string;
  onChange?: (next: string) => void;
  options: CPSegmentOption[];
}) {
  return (
    <div
      style={{
        display: "inline-flex",
        alignItems: "center",
        flexWrap: "wrap",
        rowGap: 4,
        maxWidth: "100%",
      }}
    >
      {options.map((opt, i) => {
        const v = typeof opt === "string" ? opt : opt.value;
        const l = typeof opt === "string" ? opt : opt.label;
        const active = value === v;
        return (
          <React.Fragment key={v}>
            {i > 0 && (
              <span
                aria-hidden
                style={{
                  width: 1,
                  height: 12,
                  background: "var(--cp-border-subtle)",
                  margin: "0 6px",
                  flexShrink: 0,
                }}
              />
            )}
            <button
              type="button"
              onClick={() => onChange && onChange(v)}
              style={{
                border: "none",
                background: "transparent",
                color: active ? "var(--cp-text)" : "var(--cp-text-muted)",
                fontSize: 11.5,
                fontWeight: active ? 700 : 500,
                padding: "2px 4px",
                borderRadius: 0,
                cursor: "pointer",
                fontFamily: CP_FONT,
                whiteSpace: "nowrap",
                transition: "color .12s, font-weight .12s",
                letterSpacing: "-0.005em",
              }}
              onMouseEnter={(e) => {
                if (!active) (e.currentTarget as HTMLButtonElement).style.color = "var(--cp-text-sec)";
              }}
              onMouseLeave={(e) => {
                if (!active) (e.currentTarget as HTMLButtonElement).style.color = "var(--cp-text-muted)";
              }}
            >
              {l}
            </button>
          </React.Fragment>
        );
      })}
    </div>
  );
}

// 작은 아이콘 버튼
export function CPIconBtn({
  children,
  onClick,
  title,
  tone = "default",
  size = 24,
}: {
  children?: React.ReactNode;
  onClick?: React.MouseEventHandler<HTMLButtonElement>;
  title?: string;
  tone?: "default" | "primary" | "danger";
  size?: number;
}) {
  const tones = {
    default: { bg: "transparent", color: "var(--cp-text-sec)" },
    primary: { bg: "rgba(var(--v5-primary-rgb),0.08)", color: "var(--v5-primary)" },
    danger: { bg: "transparent", color: "var(--v5-red)" },
  } as const;
  const t = tones[tone];
  return (
    <button
      type="button"
      onClick={onClick}
      title={title}
      style={{
        width: size,
        height: size,
        border: "1px solid var(--cp-border)",
        background: t.bg,
        color: t.color,
        borderRadius: 5,
        cursor: "pointer",
        display: "inline-flex",
        alignItems: "center",
        justifyContent: "center",
        padding: 0,
        flexShrink: 0,
      }}
    >
      {children}
    </button>
  );
}

// re-export 편의용
export { CP_ICONS };
