// ==========================================================================
// Components / Inputs 家族 — thumbnails + detail pages
// ==========================================================================
const { Demo: __Demo_ip, DocCard: __DocCard_ip, Spinner: __Spinner_ip } = window;
const Demo = __Demo_ip, DocCard = __DocCard_ip, Spinner = __Spinner_ip;

// ---------- 小型輔助 ----------
const Bar = ({ w = 60, h = 6, c = "var(--blue-500)", op = 1, r = 3 }) =>
  <div style={{ width: w, height: h, background: c, opacity: op, borderRadius: r }} />;

// ---------- Thumbnails (家族 overview 用) ----------
const T_Autocomplete = () => (
  <div style={{ width: 170 }}>
    <div style={{ display: "flex", alignItems: "center", gap: 4, padding: "6px 10px", border: "1px solid var(--blue-500)", borderRadius: 4, background: "#fff", boxShadow: "0 0 0 3px rgba(36,146,255,.15)", height: 28 }}>
      <span style={{ fontSize: 11, color: "var(--n-800)" }}>Design</span>
      <span style={{ fontSize: 11, color: "var(--n-400)" }}>system</span>
    </div>
    <div style={{ marginTop: 4, height: 24, background: "var(--blue-500)", borderRadius: 4 }} />
  </div>
);
const T_Button = () => (
  <div style={{ display: "flex", flexDirection: "column", gap: 8, alignItems: "flex-start" }}>
    <button style={{ padding: "6px 18px", background: "var(--blue-500)", color: "#fff", border: "none", borderRadius: 4, fontSize: 12 }}>Button</button>
    <button style={{ padding: "6px 18px", background: "#fff", color: "var(--blue-500)", border: "1.5px solid var(--blue-500)", borderRadius: 4, fontSize: 12 }}>Outlined</button>
  </div>
);
const T_ButtonGroup = () => (
  <div style={{ display: "inline-flex", border: "1.5px solid var(--blue-500)", borderRadius: 4, overflow: "hidden" }}>
    {["Day", "Week", "Month"].map((t, i) =>
      <div key={t} style={{ padding: "5px 12px", fontSize: 11, background: i === 0 ? "var(--blue-500)" : "#fff", color: i === 0 ? "#fff" : "var(--blue-500)", borderRight: i < 2 ? "1px solid var(--blue-500)" : "none" }}>{t}</div>
    )}
  </div>
);
const T_Checkbox = () => (
  <div style={{ width: 36, height: 36, background: "var(--blue-500)", borderRadius: 6, display: "flex", alignItems: "center", justifyContent: "center" }}>
    <Icon name="check" size={22} color="#fff" />
  </div>
);
const T_FAB = () => (
  <div style={{ width: 50, height: 50, borderRadius: "50%", background: "var(--blue-500)", display: "flex", alignItems: "center", justifyContent: "center", boxShadow: "0 6px 16px rgba(36,146,255,.4)" }}>
    <Icon name="plus" size={22} color="#fff" />
  </div>
);
const T_NumberField = () => (
  <div style={{ display: "inline-flex", border: "1px solid var(--n-300)", borderRadius: 4, overflow: "hidden", height: 30 }}>
    <div style={{ padding: "0 16px", background: "#fff", display: "flex", alignItems: "center", fontSize: 13, color: "var(--n-900)", borderRight: "1px solid var(--n-300)" }}>6</div>
    <div style={{ padding: "0 10px", background: "#fff", display: "flex", alignItems: "center", fontSize: 13, color: "var(--blue-500)", borderRight: "1px solid var(--n-300)" }}>−</div>
    <div style={{ padding: "0 10px", background: "#fff", display: "flex", alignItems: "center", fontSize: 13, color: "var(--blue-500)" }}>+</div>
  </div>
);
const T_RadioGroup = () => (
  <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
    {[true, false, false].map((s, i) =>
      <div key={i} style={{ display: "flex", alignItems: "center", gap: 6 }}>
        <span style={{ width: 14, height: 14, borderRadius: "50%", border: `1.5px solid ${s ? "var(--blue-500)" : "var(--n-300)"}`, display: "flex", alignItems: "center", justifyContent: "center" }}>
          {s && <span style={{ width: 6, height: 6, borderRadius: "50%", background: "var(--blue-500)" }} />}
        </span>
        <Bar w={50} h={4} c="var(--n-200)" />
      </div>
    )}
  </div>
);
const T_Select = () => (
  <div style={{ width: 160 }}>
    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "5px 10px", border: "1px solid var(--blue-500)", borderRadius: 4, background: "#fff", fontSize: 11, height: 28 }}>
      <span>Item</span><Icon name="chev" size={10} color="var(--blue-500)" />
    </div>
    <div style={{ marginTop: 4, padding: "6px 10px", background: "var(--blue-500)", borderRadius: 4, height: 30 }} />
  </div>
);
const T_Rating = () => (
  <div style={{ display: "flex", gap: 3 }}>
    {[1, 1, 0, 0, 0].map((s, i) =>
      <svg key={i} width="20" height="20" viewBox="0 0 24 24" fill={s ? "var(--blue-500)" : "none"} stroke="var(--blue-500)" strokeWidth="2">
        <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
      </svg>
    )}
  </div>
);
const T_Slider = () => (
  <div style={{ width: 170, height: 6, background: "var(--n-200)", borderRadius: 999, position: "relative" }}>
    <div style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: "60%", background: "var(--blue-500)", borderRadius: 999 }} />
    <div style={{ position: "absolute", left: "calc(60% - 8px)", top: "50%", transform: "translateY(-50%)", width: 16, height: 16, borderRadius: "50%", background: "var(--blue-500)", border: "2px solid #fff", boxShadow: "0 1px 3px rgba(0,0,0,.2)" }} />
  </div>
);
const T_Switch = () => (
  <div style={{ width: 50, height: 26, borderRadius: 999, background: "var(--blue-500)", position: "relative" }}>
    <span style={{ position: "absolute", top: 3, right: 3, width: 20, height: 20, borderRadius: "50%", background: "#fff", boxShadow: "0 1px 3px rgba(0,0,0,.2)" }} />
  </div>
);
const T_TextField = () => (
  <div style={{ width: 170, padding: "6px 10px", border: "1px solid var(--blue-500)", borderRadius: 4, background: "#fff", height: 32, display: "flex", flexDirection: "column", justifyContent: "center" }}>
    <div style={{ fontSize: 9, color: "var(--blue-500)", fontWeight: 500 }}>Design System</div>
    <Bar w={120} h={4} c="var(--blue-500)" r={2} />
  </div>
);
const T_Transfer = () => (
  <div style={{ display: "flex", gap: 8 }}>
    {[0, 1].map(c =>
      <div key={c} style={{ width: 64, padding: 6, background: "#fff", border: "1px solid var(--n-300)", borderRadius: 4, display: "flex", flexDirection: "column", gap: 4 }}>
        <Bar w="100%" h={3} c={c === 0 ? "var(--blue-500)" : "var(--n-300)"} />
        <Bar w="100%" h={3} c="var(--n-300)" />
        <Bar w="100%" h={3} c="var(--n-300)" />
      </div>
    )}
  </div>
);
const T_Toggle = () => (
  <div style={{ display: "flex", border: "1.5px solid var(--blue-500)", borderRadius: 4, overflow: "hidden" }}>
    {[0, 1, 2].map(i =>
      <div key={i} style={{ padding: "4px 10px", background: i === 0 ? "var(--blue-500)" : "#fff", borderRight: i < 2 ? "1px solid var(--blue-500)" : "none" }}>
        <Bar w={20} h={4} c={i === 0 ? "#fff" : "var(--blue-500)"} />
      </div>
    )}
  </div>
);
const T_Upload = () => (
  <div style={{ display: "inline-flex", alignItems: "center", gap: 6, padding: "6px 16px", border: "1.5px solid var(--blue-500)", borderRadius: 4, color: "var(--blue-500)" }}>
    <Icon name="upload" size={14} />
    <span style={{ fontSize: 12, fontWeight: 500 }}>Upload</span>
  </div>
);
const T_Cascader = () => (
  <div style={{ display: "flex", gap: 4 }}>
    {[0, 1, 2].map(c =>
      <div key={c} style={{ width: 52, background: "#fff", border: "1px solid var(--n-300)", borderRadius: 4, padding: 4, display: "flex", flexDirection: "column", gap: 3 }}>
        <Bar w={c === 0 ? 32 : 24} h={3} c={c === 0 ? "var(--blue-500)" : "var(--n-300)"} />
        <Bar w={c === 1 ? 32 : 18} h={3} c={c === 1 ? "var(--blue-500)" : "var(--n-300)"} />
        <Bar w={20} h={3} c="var(--n-300)" />
      </div>
    )}
  </div>
);
const T_ColorPicker = () => (
  <div style={{ width: 100, height: 70, background: "linear-gradient(135deg,#bae0ff,#69b1ff,#2492ff)", borderRadius: 6, position: "relative", border: "1px solid var(--n-300)" }}>
    <div style={{ position: "absolute", top: 12, left: 16, width: 16, height: 16, border: "2px solid #fff", borderRadius: "50%", boxShadow: "0 0 0 1px rgba(0,0,0,.2)" }} />
    <div style={{ position: "absolute", bottom: 0, left: 0, right: 0, height: 8, background: "linear-gradient(to right,#ff5f5b,#faad14,#1fa101,#2492ff,#a855f7,#e8178a,#ff5f5b)" }} />
  </div>
);
const T_DatePicker = () => (
  <div style={{ width: 140, padding: 8, background: "#fff", border: "1px solid var(--n-300)", borderRadius: 4 }}>
    <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 4, fontSize: 9, color: "var(--n-700)" }}>
      <span>‹</span><span>04月</span><span>›</span>
    </div>
    <div style={{ display: "grid", gridTemplateColumns: "repeat(7,1fr)", gap: 2 }}>
      {Array.from({ length: 14 }).map((_, i) =>
        <div key={i} style={{ height: 12, background: i === 5 ? "var(--blue-500)" : "transparent", borderRadius: 2 }} />
      )}
    </div>
  </div>
);
const T_Camera = () => (
  <div style={{ width: 90, height: 60, background: "#fff", border: "1.5px solid var(--blue-500)", borderRadius: 6, position: "relative" }}>
    <div style={{ position: "absolute", top: -6, left: 14, width: 14, height: 6, background: "#fff", border: "1.5px solid var(--blue-500)", borderBottom: "none", borderRadius: "4px 4px 0 0" }} />
    <div style={{ position: "absolute", inset: "30% 25% 20%", borderRadius: "50%", border: "2px solid var(--blue-500)" }} />
    <div style={{ position: "absolute", bottom: 8, right: 8, width: 12, height: 12, borderRadius: "50%", background: "var(--blue-500)" }} />
  </div>
);

// ==========================================================================
// Detail Cards
// ==========================================================================

// 共用：欄位 label
const FieldLabel = ({ children }) => (
  <label style={{ display: "block", fontSize: 13, fontWeight: 500, color: "var(--n-700)", marginBottom: 6 }}>{children}</label>
);

const DocInputs = () => (
  <>
    {/* ---------- Autocomplete ---------- */}
    <DocCard id="c-inputs-autocomplete" en="Autocomplete" intro="輸入時提供建議清單的搜尋框，適用於從大量選項中快速找到項目。">
      <Demo title="基本用法">
        <AutocompleteDemo options={["Design system", "Design tokens", "Design review", "Documentation", "Developer guide"]} />
      </Demo>
      <Demo title="多選 (Multi-select)">
        <div style={{ width: 320, padding: "6px 10px", border: "1.5px solid var(--blue-500)", borderRadius: 6, background: "#fff", display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", minHeight: 36, boxShadow: "0 0 0 3px rgba(36,146,255,.15)" }}>
          <span style={{ padding: "2px 8px", background: "var(--blue-50)", color: "var(--blue-700)", borderRadius: 999, fontSize: 12 }}>Design <Icon name="x" size={10} style={{ marginLeft: 4, cursor: "pointer" }} /></span>
          <span style={{ padding: "2px 8px", background: "var(--blue-50)", color: "var(--blue-700)", borderRadius: 999, fontSize: 12 }}>System <Icon name="x" size={10} style={{ marginLeft: 4, cursor: "pointer" }} /></span>
          <input placeholder="繼續輸入…" style={{ border: "none", outline: "none", fontSize: 13, flex: 1, minWidth: 80 }} />
        </div>
      </Demo>
    </DocCard>

    {/* ---------- Button ---------- */}
    <DocCard id="c-inputs-button" en="Button">
      {React.createElement(window.ButtonSpec || (() => null))}
    </DocCard>

    {/* ---------- Button Group ---------- */}
    <DocCard id="c-inputs-button-group" en="Button Group" intro="一組相關按鈕並列，常用於切換時間範圍、檢視模式等並列動作。">
      <Demo title="基本用法">
        <SegmentedDemo options={["日", "週", "月", "年"]} />
      </Demo>
      <Demo title="含圖示">
        <SegmentedDemo options={[{ icon: "list" }, { icon: "grid" }]} />
      </Demo>
    </DocCard>

    {/* ---------- Checkbox ---------- */}
    <DocCard id="c-inputs-checkbox" en="Checkbox" intro="核取按鈕，用於多選或開關狀態。indeterminate 狀態用於子項目部分選取時。">
      <Demo title="基本用法">
        <Checkbox label="同意條款" defaultChecked />
        <Checkbox label="訂閱電子報" />
        <Checkbox label="部分選取" indeterminate />
        <Checkbox label="禁用" disabled />
      </Demo>
      <Demo title="群組多選">
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          <Checkbox label="全選" indeterminate />
          <div style={{ paddingLeft: 24, display: "flex", flexDirection: "column", gap: 8 }}>
            <Checkbox label="蘋果" defaultChecked />
            <Checkbox label="香蕉" />
            <Checkbox label="橘子" defaultChecked />
          </div>
        </div>
      </Demo>
    </DocCard>

    {/* ---------- FAB ---------- */}
    <DocCard id="c-inputs-fab" en="Floating Action Button" intro="浮動操作按鈕通常固定在畫面右下角，代表頁面的主要動作（例：新增、撰寫、編輯）。">
      <Demo title="基本用法">
        <FabBtn icon="plus" />
        <FabBtn icon="edit" variant="toner" />
        <FabBtn icon="mail" />
      </Demo>
      <Demo title="延伸版 (Extended FAB)">
        <button style={{ display: "inline-flex", alignItems: "center", gap: 8, padding: "12px 20px", background: "var(--blue-500)", color: "#fff", border: "none", borderRadius: 28, fontSize: 14, fontWeight: 500, boxShadow: "0 6px 16px rgba(36,146,255,.35)", cursor: "pointer" }}>
          <Icon name="plus" size={18} />新增專案
        </button>
      </Demo>
    </DocCard>

    {/* ---------- Number Field ---------- */}
    <DocCard id="c-inputs-number" en="Number Field" intro="數值輸入框，附 +/- 按鈕，可用於數量、份數等場景。">
      <Demo title="基本用法">
        <NumberFieldDemo defaultValue={1} />
        <NumberFieldDemo defaultValue={6} />
        <NumberFieldDemo defaultValue={99} />
      </Demo>
    </DocCard>

    {/* ---------- Radio Group ---------- */}
    <DocCard id="c-inputs-radio" en="Radio Group" intro="從多個選項中只能選一個時使用，建議選項數量 2–5 個為佳。">
      <Demo title="水平排列">
        <RadioGroup options={["月繳", "年繳", "一次付清"]} defaultIndex={1} />
      </Demo>
      <Demo title="垂直排列">
        <RadioGroup options={["寄送到家", "超商取貨", "自取門市", "親自取件"]} defaultIndex={0} vertical />
      </Demo>
      <Demo title="卡片型 Radio">
        <RadioCardDemo />
      </Demo>
    </DocCard>

    {/* ---------- Select ---------- */}
    <DocCard id="c-inputs-select" en="Select" intro="下拉選擇框，從預先定義的選項中擇一。選項數量超過 7 個建議使用 Autocomplete。">
      <Demo title="基本用法">
        <Select options={["北部", "中部", "南部", "東部"]} defaultIndex={0} width={180} />
      </Demo>
      <Demo title="尺寸">
        <Select options={["Small", "Medium", "Large"]} defaultIndex={0} width={140} />
        <Select options={["Light", "Dark", "System"]} defaultIndex={1} width={140} />
      </Demo>
    </DocCard>

    {/* ---------- Rating ---------- */}
    <DocCard id="c-inputs-rating" en="Rating" intro="評分元件，hover 預覽 + click 設定，常用於評論與滿意度。">
      <Demo title="基本用法">
        <Rate defaultValue={4} />
        <Rate defaultValue={3} />
        <Rate defaultValue={0} />
      </Demo>
      <Demo title="只讀">
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <Rate defaultValue={5} />
            <span style={{ fontSize: 13, color: "var(--n-700)" }}>4.8 / 5.0 (1,284 評價)</span>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <Rate defaultValue={3} />
            <span style={{ fontSize: 13, color: "var(--n-700)" }}>3.2 / 5.0 (642 評價)</span>
          </div>
        </div>
      </Demo>
    </DocCard>

    {/* ---------- Slider ---------- */}
    <DocCard id="c-inputs-slider" en="Slider" intro="滑桿，用於連續數值選擇（音量、亮度、價格範圍等）。">
      <Demo title="基本用法">
        <div style={{ width: 480, display: "flex", flexDirection: "column", gap: 24 }}>
          <Slider defaultValue={40} />
          <Slider defaultValue={75} />
        </div>
      </Demo>
      <Demo title="含刻度 / 標籤">
        <div style={{ width: 480 }}>
          <Slider defaultValue={50} />
          <div style={{ display: "flex", justifyContent: "space-between", marginTop: 4, fontSize: 11, color: "var(--n-500)" }}>
            <span>0%</span><span>25%</span><span>50%</span><span>75%</span><span>100%</span>
          </div>
        </div>
      </Demo>
    </DocCard>

    {/* ---------- Switch ---------- */}
    <DocCard id="c-inputs-switch" en="Switch" intro="即時生效的開關，常用於設定頁。狀態變化會立刻套用，不需另外按儲存。">
      <Demo title="基本用法">
        <Switch defaultOn />
        <Switch />
        <Switch defaultOn size="sm" />
        <Switch size="sm" />
      </Demo>
      <Demo title="禁用">
        <Switch defaultOn disabled />
        <Switch disabled />
      </Demo>
      <Demo title="含標籤">
        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          <SwitchRow title="自動儲存" desc="編輯時每 30 秒自動儲存草稿" defaultOn />
          <SwitchRow title="深色模式" desc="切換為黑色背景與淺色文字" />
          <SwitchRow title="通知" desc="開啟桌面通知與聲音提醒" defaultOn />
        </div>
      </Demo>
    </DocCard>

    {/* ---------- Text Field ---------- */}
    <DocCard id="c-inputs-textfield" en="Text Field">
      {React.createElement(window.TextFieldSpec || (() => null))}
    </DocCard>

    {/* ---------- Transfer List ---------- */}
    <DocCard id="c-inputs-transfer" en="Transfer List" intro="雙列選擇器，左欄是備選、右欄是已選，用於管理使用者群組、權限分配等。">
      <Demo title="基本用法"><TransferDemo /></Demo>
    </DocCard>

    {/* ---------- Toggle Button ---------- */}
    <DocCard id="c-inputs-toggle" en="Toggle Button" intro="切換按鈕，可單選或多選，類似 Segmented Control。常見用法：對齊方向、字型粗細、檢視模式。">
      <Demo title="單選">
        <SegmentedDemo options={[{ icon: "list" }, { icon: "grid" }]} />
      </Demo>
      <Demo title="多選 (文字工具)">
        <ToggleMultiDemo />
      </Demo>
    </DocCard>

    {/* ---------- Upload ---------- */}
    <DocCard id="c-inputs-upload" en="Upload" intro="檔案上傳，支援拖拉與點擊選擇，上傳中顯示進度。">
      <Demo title="按鈕觸發">
        <B kind="outline" icon="upload">選擇檔案</B>
        <span className="ds-cap">支援 PNG / JPG / PDF，單檔最大 10MB</span>
      </Demo>
      <Demo title="拖拉區域"><UploadDropDemo /></Demo>
    </DocCard>

    {/* ---------- Cascader ---------- */}
    <DocCard id="c-inputs-cascader" en="Cascader" intro="級聯選擇器，用於多層級分類資料（例：地區選擇、產品分類）。">
      <Demo title="基本用法"><CascaderDemo /></Demo>
    </DocCard>

    {/* ---------- ColorPicker ---------- */}
    <DocCard id="c-inputs-colorpicker" en="ColorPicker" intro="顏色選擇器，支援色票快選、HSV 漸層選擇與 HEX 輸入。">
      <Demo title="基本用法"><ColorPickerDemo /></Demo>
      <Demo title="快選色票"><ColorSwatchesDemo /></Demo>
    </DocCard>

    {/* ---------- DatePicker / TimePicker ---------- */}
    <DocCard id="c-inputs-datepicker" en="DatePicker / TimePicker" intro="日期 / 時間選擇器，建議搭配 Input 樣式呈現，並提供清除與「今天」快捷鍵。">
      <Demo title="日期選擇器">
        <DatePickerInline />
      </Demo>
      <Demo title="日期 + 時間">
        <div style={{ display: "flex", gap: 12 }}>
          <DateInput value="2026 / 04 / 15" />
          <TimeInput value="14:30" />
        </div>
      </Demo>
    </DocCard>

    {/* ---------- Camera ---------- */}
    <DocCard id="c-inputs-camera" en="Camera" intro="相機元件，用於拍照、條碼掃描、QR Code 掃描等場景，通常嵌入 Modal 中。">
      <Demo title="相機介面範例">
        <div style={{ width: 320, height: 220, background: "#000", borderRadius: 12, position: "relative", overflow: "hidden" }}>
          <div style={{ position: "absolute", inset: "20% 25%", border: "2px dashed rgba(255,255,255,.6)", borderRadius: 8 }} />
          <div style={{ position: "absolute", top: 12, left: 12, padding: "4px 10px", background: "rgba(0,0,0,.6)", color: "#fff", borderRadius: 999, fontSize: 11, display: "flex", alignItems: "center", gap: 6 }}>
            <span style={{ width: 6, height: 6, borderRadius: "50%", background: "var(--error)" }} />REC
          </div>
          <div style={{ position: "absolute", bottom: 16, left: "50%", transform: "translateX(-50%)", width: 56, height: 56, borderRadius: "50%", background: "#fff", border: "4px solid rgba(255,255,255,.4)", cursor: "pointer" }} />
        </div>
      </Demo>
    </DocCard>
  </>
);

// ---------- 小型 demo 元件 ----------
function tfStyle() {
  return { width: "100%", height: 36, padding: "0 12px", border: "1px solid var(--n-300)", borderRadius: 6, fontSize: 14, outline: "none", background: "#fff" };
}

const AutocompleteDemo = ({ options }) => {
  const [v, setV] = React.useState("Design");
  const filtered = options.filter(o => o.toLowerCase().includes(v.toLowerCase()));
  const [open, setOpen] = React.useState(false);
  return (
    <div style={{ width: 320, position: "relative" }}>
      <input value={v} onChange={(e) => { setV(e.target.value); setOpen(true); }}
        onFocus={() => setOpen(true)} onBlur={() => setTimeout(() => setOpen(false), 150)}
        placeholder="輸入關鍵字…" style={{ ...tfStyle(), borderColor: "var(--blue-500)" }} />
      {open && filtered.length > 0 && (
        <div className="ds-menu" style={{ position: "absolute", top: "calc(100% + 4px)", left: 0, right: 0, zIndex: 5, maxHeight: 200, overflowY: "auto" }}>
          {filtered.map(o => (
            <div key={o} className="ds-menu__item" onMouseDown={() => { setV(o); setOpen(false); }}>{o}</div>
          ))}
        </div>
      )}
    </div>
  );
};

const ButtonLoadingDemo = () => {
  const [loading, setLoading] = React.useState(false);
  return (
    <B kind="filled" onClick={() => { setLoading(true); setTimeout(() => setLoading(false), 1600); }} disabled={loading}>
      {loading ? <><Spinner size={14} /> 處理中…</> : "點我載入"}
    </B>
  );
};

const SegmentedDemo = ({ options, defaultIndex = 0 }) => {
  const [idx, setIdx] = React.useState(defaultIndex);
  return (
    <div style={{ display: "inline-flex", border: "1px solid var(--blue-500)", borderRadius: 6, overflow: "hidden" }}>
      {options.map((o, i) => (
        <div key={i} onClick={() => setIdx(i)} style={{
          padding: "8px 16px", fontSize: 13, fontWeight: 500, cursor: "pointer",
          background: i === idx ? "var(--blue-500)" : "#fff",
          color: i === idx ? "#fff" : "var(--blue-500)",
          borderRight: i < options.length - 1 ? "1px solid var(--blue-500)" : "none",
          display: "inline-flex", alignItems: "center", gap: 6,
          transition: "all var(--dur-fast) var(--ease)",
        }}>
          {typeof o === "object" && o.icon ? <Icon name={o.icon} size={14} /> : null}
          {typeof o === "string" ? o : o.label}
        </div>
      ))}
    </div>
  );
};

const FabBtn = ({ icon, variant = "filled" }) => {
  const bg = variant === "toner" ? "var(--blue-50)" : "var(--blue-500)";
  const color = variant === "toner" ? "var(--blue-600)" : "#fff";
  const shadow = variant === "toner" ? "0 4px 12px rgba(0,0,0,.08)" : "0 8px 20px rgba(36,146,255,.4)";
  return (
    <button style={{ width: 56, height: 56, borderRadius: 16, background: bg, color, border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", boxShadow: shadow }}>
      <Icon name={icon} size={22} />
    </button>
  );
};

const NumberFieldDemo = ({ defaultValue = 1, min = 0, max = 999 }) => {
  const [v, setV] = React.useState(defaultValue);
  const btn = { width: 32, height: 32, border: "none", background: "transparent", color: "var(--blue-500)", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 16 };
  return (
    <div style={{ display: "inline-flex", border: "1px solid var(--n-300)", borderRadius: 6, overflow: "hidden", background: "#fff" }}>
      <button style={btn} onClick={() => setV(Math.max(min, v - 1))} disabled={v <= min}>−</button>
      <input value={v} onChange={(e) => setV(Math.max(min, Math.min(max, +e.target.value || 0)))} style={{ width: 56, border: "none", borderLeft: "1px solid var(--n-200)", borderRight: "1px solid var(--n-200)", textAlign: "center", fontSize: 14, outline: "none" }} />
      <button style={btn} onClick={() => setV(Math.min(max, v + 1))} disabled={v >= max}>+</button>
    </div>
  );
};

const RadioCardDemo = () => {
  const [idx, setIdx] = React.useState(1);
  const opts = [
    { t: "標準版", p: "$10/月", d: "適合個人使用" },
    { t: "進階版", p: "$25/月", d: "適合小型團隊" },
    { t: "企業版", p: "$80/月", d: "客製化與專屬支援" },
  ];
  return (
    <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 12, maxWidth: 580 }}>
      {opts.map((o, i) => (
        <div key={i} onClick={() => setIdx(i)} style={{
          padding: 16, background: "#fff", cursor: "pointer",
          border: `1.5px solid ${i === idx ? "var(--blue-500)" : "var(--n-200)"}`,
          borderRadius: 8, position: "relative",
          boxShadow: i === idx ? "0 0 0 3px rgba(36,146,255,.15)" : "none",
          transition: "all var(--dur-fast) var(--ease)",
        }}>
          <span style={{ position: "absolute", top: 12, right: 12, width: 16, height: 16, borderRadius: "50%", border: `1.5px solid ${i === idx ? "var(--blue-500)" : "var(--n-300)"}`, display: "flex", alignItems: "center", justifyContent: "center" }}>
            {i === idx && <span style={{ width: 7, height: 7, borderRadius: "50%", background: "var(--blue-500)" }} />}
          </span>
          <div style={{ fontSize: 14, fontWeight: 600 }}>{o.t}</div>
          <div style={{ fontSize: 16, fontWeight: 700, color: "var(--blue-500)", marginTop: 4 }}>{o.p}</div>
          <div style={{ fontSize: 12, color: "var(--n-600)", marginTop: 4 }}>{o.d}</div>
        </div>
      ))}
    </div>
  );
};

const SwitchRow = ({ title, desc, defaultOn }) => (
  <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, padding: "10px 14px", border: "1px solid var(--n-200)", borderRadius: 8, minWidth: 320 }}>
    <div>
      <div style={{ fontSize: 14, fontWeight: 500 }}>{title}</div>
      <div className="ds-cap">{desc}</div>
    </div>
    <Switch defaultOn={defaultOn} />
  </div>
);

const TransferDemo = () => {
  const all = ["Alice 林", "Bob 陳", "Cathy 王", "David 李", "Eve 張", "Frank 黃"];
  const [right, setRight] = React.useState(["Bob 陳", "David 李"]);
  const left = all.filter(a => !right.includes(a));
  const [selL, setSelL] = React.useState(new Set());
  const [selR, setSelR] = React.useState(new Set());
  const Col = ({ title, items, sel, setSel }) => (
    <div style={{ width: 180, background: "#fff", border: "1px solid var(--n-200)", borderRadius: 6 }}>
      <div style={{ padding: "8px 12px", borderBottom: "1px solid var(--n-200)", fontSize: 13, color: "var(--n-700)", background: "var(--n-50)" }}>{title} ({items.length})</div>
      <div style={{ padding: 4, minHeight: 160, display: "flex", flexDirection: "column", gap: 0 }}>
        {items.map(it => (
          <div key={it} onClick={() => { const n = new Set(sel); n.has(it) ? n.delete(it) : n.add(it); setSel(n); }} style={{ padding: "6px 10px", cursor: "pointer", borderRadius: 4, display: "flex", alignItems: "center", gap: 6, background: sel.has(it) ? "var(--blue-50)" : "transparent", fontSize: 13 }}>
            <span style={{ width: 14, height: 14, borderRadius: 3, border: `1.5px solid ${sel.has(it) ? "var(--blue-500)" : "var(--n-300)"}`, background: sel.has(it) ? "var(--blue-500)" : "#fff", display: "flex", alignItems: "center", justifyContent: "center" }}>
              {sel.has(it) && <Icon name="check" size={10} color="#fff" />}
            </span>
            {it}
          </div>
        ))}
      </div>
    </div>
  );
  const moveR = () => { setRight([...right, ...left.filter(l => selL.has(l))]); setSelL(new Set()); };
  const moveL = () => { setRight(right.filter(r => !selR.has(r))); setSelR(new Set()); };
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
      <Col title="未選成員" items={left} sel={selL} setSel={setSelL} />
      <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
        <button onClick={moveR} disabled={selL.size === 0} style={{ width: 32, height: 28, border: `1px solid ${selL.size ? "var(--blue-500)" : "var(--n-300)"}`, background: selL.size ? "var(--blue-500)" : "#fff", color: selL.size ? "#fff" : "var(--n-400)", borderRadius: 4, cursor: selL.size ? "pointer" : "default", display: "flex", alignItems: "center", justifyContent: "center" }}>
          <Icon name="chevR" size={14} />
        </button>
        <button onClick={moveL} disabled={selR.size === 0} style={{ width: 32, height: 28, border: `1px solid ${selR.size ? "var(--blue-500)" : "var(--n-300)"}`, background: selR.size ? "var(--blue-500)" : "#fff", color: selR.size ? "#fff" : "var(--n-400)", borderRadius: 4, cursor: selR.size ? "pointer" : "default", display: "flex", alignItems: "center", justifyContent: "center" }}>
          <Icon name="chevL" size={14} />
        </button>
      </div>
      <Col title="已選成員" items={right} sel={selR} setSel={setSelR} />
    </div>
  );
};

const ToggleMultiDemo = () => {
  const [sel, setSel] = React.useState(new Set(["B"]));
  const tools = [{ k: "B", t: <b>B</b> }, { k: "I", t: <i>I</i> }, { k: "U", t: <u>U</u> }, { k: "S", t: <s>S</s> }];
  return (
    <div style={{ display: "inline-flex", border: "1px solid var(--blue-500)", borderRadius: 6, overflow: "hidden" }}>
      {tools.map((tool, i) => (
        <div key={tool.k} onClick={() => { const n = new Set(sel); n.has(tool.k) ? n.delete(tool.k) : n.add(tool.k); setSel(n); }} style={{ padding: "6px 14px", cursor: "pointer", background: sel.has(tool.k) ? "var(--blue-500)" : "#fff", color: sel.has(tool.k) ? "#fff" : "var(--blue-500)", borderRight: i < tools.length - 1 ? "1px solid var(--blue-500)" : "none", fontSize: 14 }}>{tool.t}</div>
      ))}
    </div>
  );
};

const UploadDropDemo = () => {
  const [hover, setHover] = React.useState(false);
  return (
    <div onDragEnter={() => setHover(true)} onDragLeave={() => setHover(false)} onDragOver={(e) => e.preventDefault()} onDrop={(e) => { e.preventDefault(); setHover(false); }} style={{
      width: "100%", maxWidth: 480,
      border: `2px dashed ${hover ? "var(--blue-500)" : "var(--n-300)"}`,
      background: hover ? "var(--blue-50)" : "var(--n-50)",
      borderRadius: 8, padding: 28, textAlign: "center", cursor: "pointer",
      transition: "all var(--dur-fast) var(--ease)",
    }}>
      <Icon name="upload" size={32} color={hover ? "var(--blue-500)" : "var(--n-500)"} />
      <div style={{ marginTop: 8, fontSize: 14 }}>拖曳檔案到這裡 或 <span style={{ color: "var(--blue-500)" }}>點擊選擇檔案</span></div>
      <div className="ds-cap" style={{ marginTop: 4 }}>支援 PNG / JPG / PDF / DOCX，單檔最大 10MB</div>
    </div>
  );
};

const CascaderDemo = () => {
  const data = {
    "北部": { "台北市": ["大安區", "信義區", "中正區"], "新北市": ["板橋區", "三重區", "中和區"] },
    "中部": { "台中市": ["北區", "西區", "南區"], "彰化縣": ["彰化市", "員林市"] },
    "南部": { "高雄市": ["前金區", "三民區", "鼓山區"], "台南市": ["中西區", "東區"] },
  };
  const [a, setA] = React.useState("北部");
  const [b, setB] = React.useState("台北市");
  const [c, setC] = React.useState(null);
  const ColList = ({ items, sel, onClick }) => (
    <div style={{ width: 110, background: "#fff", borderRight: "1px solid var(--n-200)", padding: 6 }}>
      {items.map(x => (
        <div key={x} onClick={() => onClick(x)} style={{ padding: "6px 10px", cursor: "pointer", fontSize: 13, borderRadius: 4, background: x === sel ? "var(--blue-50)" : "transparent", color: x === sel ? "var(--blue-600)" : "var(--n-800)", fontWeight: x === sel ? 500 : 400 }}>{x}</div>
      ))}
    </div>
  );
  return (
    <div style={{ display: "inline-flex", border: "1px solid var(--n-300)", borderRadius: 6, overflow: "hidden", background: "#fff" }}>
      <ColList items={Object.keys(data)} sel={a} onClick={(x) => { setA(x); setB(null); setC(null); }} />
      {a && <ColList items={Object.keys(data[a])} sel={b} onClick={(x) => { setB(x); setC(null); }} />}
      {a && b && <ColList items={data[a][b]} sel={c} onClick={setC} />}
    </div>
  );
};

const ColorPickerDemo = () => {
  const [hex, setHex] = React.useState("#2492ff");
  const presets = ["#2492ff", "#1fa101", "#faad14", "#e43131", "#a855f7", "#e8178a", "#262626", "#fff"];
  return (
    <div style={{ display: "flex", gap: 16, alignItems: "center" }}>
      <div style={{ width: 56, height: 56, borderRadius: 8, background: hex, border: "1px solid var(--n-200)", boxShadow: "var(--shadow-1)" }} />
      <div>
        <div style={{ fontFamily: "var(--ff-mono)", fontSize: 14, color: "var(--n-800)" }}>{hex.toUpperCase()}</div>
        <div style={{ display: "flex", gap: 4, marginTop: 8 }}>
          {presets.map(c => (
            <div key={c} onClick={() => setHex(c)} style={{ width: 22, height: 22, borderRadius: 4, background: c, border: c === hex ? "2px solid var(--n-900)" : "1px solid var(--n-200)", cursor: "pointer" }} />
          ))}
        </div>
      </div>
    </div>
  );
};

const ColorSwatchesDemo = () => {
  const groups = [
    { name: "Blue", colors: ["#f0f7ff", "#bae0ff", "#69b1ff", "#2492ff", "#1d75cc", "#165699"] },
    { name: "Green", colors: ["#f0faf5", "#bbf7d0", "#4ade80", "#1fa101", "#16823a", "#0f5e2a"] },
    { name: "Red", colors: ["#fff1f0", "#ffc4c2", "#ff5f5b", "#e43131", "#b81f1f", "#871414"] },
  ];
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
      {groups.map(g => (
        <div key={g.name} style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <span style={{ width: 50, fontSize: 12, color: "var(--n-700)" }}>{g.name}</span>
          {g.colors.map(c => <div key={c} style={{ width: 24, height: 24, borderRadius: 4, background: c, border: "1px solid rgba(0,0,0,.05)", cursor: "pointer" }} />)}
        </div>
      ))}
    </div>
  );
};

const DatePickerInline = () => {
  const [open, setOpen] = React.useState(true);
  const [d, setD] = React.useState(15);
  return (
    <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-start", gap: 8 }}>
      <DateInput value={`2026 / 04 / ${String(d).padStart(2, "0")}`} onClick={() => setOpen(!open)} />
      {open && (
        <div style={{ background: "#fff", border: "1px solid var(--n-200)", borderRadius: 8, boxShadow: "var(--shadow-3)", padding: 16, width: 280 }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
            <Icon name="chevL" size={16} color="var(--n-600)" />
            <div style={{ fontSize: 13, fontWeight: 600 }}>2026 年 4 月</div>
            <Icon name="chevR" size={16} color="var(--n-600)" />
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(7,1fr)", gap: 2, fontSize: 11, color: "var(--n-500)", textAlign: "center", marginBottom: 4 }}>
            {["日", "一", "二", "三", "四", "五", "六"].map(d => <div key={d}>{d}</div>)}
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(7,1fr)", gap: 2 }}>
            {Array.from({ length: 30 }, (_, i) => i + 1).map(n => (
              <div key={n} onClick={() => setD(n)} style={{ height: 30, display: "flex", alignItems: "center", justifyContent: "center", fontSize: 13, borderRadius: 4, cursor: "pointer", background: n === d ? "var(--blue-500)" : "transparent", color: n === d ? "#fff" : "var(--n-800)", fontWeight: n === d ? 600 : 400 }}>{n}</div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

const DateInput = ({ value, onClick }) => (
  <div onClick={onClick} style={{ height: 36, padding: "0 12px", border: "1px solid var(--n-300)", borderRadius: 6, display: "flex", alignItems: "center", gap: 8, cursor: "pointer", background: "#fff", width: 200, fontSize: 14 }}>
    <Icon name="cal" size={16} color="var(--n-500)" />
    <span>{value}</span>
  </div>
);

const TimeInput = ({ value }) => (
  <div style={{ height: 36, padding: "0 12px", border: "1px solid var(--n-300)", borderRadius: 6, display: "flex", alignItems: "center", gap: 8, cursor: "pointer", background: "#fff", width: 140, fontSize: 14 }}>
    <Icon name="cal" size={16} color="var(--n-500)" />
    <span>{value}</span>
  </div>
);

// 對外暴露
Object.assign(window, {
  Bar,
  T_Autocomplete, T_Button, T_ButtonGroup, T_Checkbox, T_FAB, T_NumberField,
  T_RadioGroup, T_Select, T_Rating, T_Slider, T_Switch, T_TextField,
  T_Transfer, T_Toggle, T_Upload, T_Cascader, T_ColorPicker, T_DatePicker, T_Camera,
  DocInputs, Demo, DocCard, CompGrid, FieldLabel, tfStyle,
});
