/* ============================================================
   万物剧场 · 问卷 — 题型组件 + 图标
   ============================================================ */
const { useState, useRef, useEffect } = React;

/* ---------- 线性小图标（简单几何，符合品牌线性字性） ---------- */
const Icon = {
  check: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M5 13l4 4L19 7"/></svg>,
  arrowR: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M5 12h14M13 6l6 6-6 6"/></svg>,
  arrowL: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M19 12H5M11 6l-6 6 6 6"/></svg>,
  up: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M6 15l6-6 6 6"/></svg>,
  down: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M6 9l6 6 6-6"/></svg>,
  grip: (p) => <svg viewBox="0 0 24 24" fill="currentColor" {...p}><circle cx="9" cy="6" r="1.6"/><circle cx="15" cy="6" r="1.6"/><circle cx="9" cy="12" r="1.6"/><circle cx="15" cy="12" r="1.6"/><circle cx="9" cy="18" r="1.6"/><circle cx="15" cy="18" r="1.6"/></svg>,
  ticket: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 8a2 2 0 012-2h14a2 2 0 012 2 2 2 0 000 4 2 2 0 000 4 2 2 0 01-2 2H5a2 2 0 01-2-2 2 2 0 000-4 2 2 0 000-4z"/><path d="M14 6v12" strokeDasharray="2 3"/></svg>,
  star: (p) => <svg viewBox="0 0 24 24" fill="currentColor" {...p}><path d="M12 3l2.5 5.5L20 9.3l-4 4 1 5.7-5-2.8-5 2.8 1-5.7-4-4 5.5-.8z"/></svg>,
  sun: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" {...p}><circle cx="12" cy="12" r="4.5"/><path d="M12 2v2M12 20v2M4 12H2M22 12h-2M5 5l1.4 1.4M17.6 17.6L19 19M19 5l-1.4 1.4M6.4 17.6L5 19"/></svg>,
  moon: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M20 14.5A8 8 0 119.5 4a6.3 6.3 0 0010.5 10.5z"/></svg>,
  refresh: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 12a9 9 0 0115.5-6.3M21 4v5h-5M21 12a9 9 0 01-15.5 6.3M3 20v-5h5"/></svg>,
  download: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 3v12M7 11l5 5 5-5M4 21h16"/></svg>,
  share: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="6" cy="12" r="2.6"/><circle cx="18" cy="6" r="2.6"/><circle cx="18" cy="18" r="2.6"/><path d="M8.3 10.8l7.4-3.6M8.3 13.2l7.4 3.6"/></svg>,
};

/* ---------- 统一面脸（品牌：墨黑双眼 + 松垮小嘴） ---------- */
function Face({ mood = "smile" }) {
  const mouth = {
    smile: "M40 60 Q50 70 60 60",
    calm: "M41 62 Q50 66 59 62",
    o: null,
  }[mood];
  return (
    <svg viewBox="0 0 100 100" aria-hidden="true">
      <ellipse cx="38" cy="48" rx="5.2" ry="7.4" fill="#1F2A2E"/>
      <ellipse cx="62" cy="48" rx="5.2" ry="7.4" fill="#1F2A2E"/>
      {mood === "o"
        ? <circle cx="50" cy="63" r="4" fill="#1F2A2E"/>
        : <path d={mouth} fill="none" stroke="#1F2A2E" strokeWidth="3.4" strokeLinecap="round"/>}
    </svg>
  );
}

/* ============================================================
   单选
   ============================================================ */
function SingleChoice({ q, value, onChange, justPicked }) {
  return (
    <div className="opts">
      {q.options.map((o, i) => (
        <button key={o.id}
          className={"opt" + (value === o.id ? " on" : "") + (justPicked === o.id ? " pop" : "")}
          onClick={() => onChange(o.id)}>
          <span className="mark"><span className="dot"></span></span>
          <span className="label">{o.label}</span>
          <span className="key">{String.fromCharCode(65 + i)}</span>
        </button>
      ))}
    </div>
  );
}

/* ============================================================
   多选
   ============================================================ */
function MultiChoice({ q, value, onChange }) {
  const arr = Array.isArray(value) ? value : [];
  const max = q.max || q.options.length;
  const toggle = (id) => {
    if (arr.includes(id)) onChange(arr.filter((x) => x !== id));
    else if (arr.length < max) onChange([...arr, id]);
  };
  return (
    <div className="opts">
      {q.options.map((o, i) => {
        const on = arr.includes(o.id);
        const full = !on && arr.length >= max;
        return (
          <button key={o.id}
            className={"opt multi" + (on ? " on" : "")}
            style={full ? { opacity: .5 } : null}
            onClick={() => toggle(o.id)}>
            <span className="mark">{Icon.check({ style: on ? { opacity: 1, transform: "scale(1)" } : {} })}</span>
            <span className="label">{o.label}</span>
            <span className="key">{String.fromCharCode(65 + i)}</span>
          </button>
        );
      })}
    </div>
  );
}

/* ============================================================
   量表 / 滑条
   ============================================================ */
function ScaleQ({ q, value, onChange }) {
  const steps = [];
  for (let v = q.min; v <= q.max; v++) steps.push(v);
  return (
    <div className="scale">
      <div className="ladder">
        {steps.map((v) => {
          const on = value === v;
          const near = value != null && Math.abs(value - v) === 1;
          // 球的尺寸随两端渐变，制造「程度」体感
          const t = (v - q.min) / (q.max - q.min);
          const size = 26 + t * 16;
          return (
            <button key={v} className={"step" + (on ? " on" : "") + (near ? " near" : "")}
              onClick={() => onChange(v)}>
              <span className="dotwrap">
                <span className="ball" style={{ width: size, height: size }}></span>
              </span>
              <span className="n">{v}</span>
            </button>
          );
        })}
      </div>
      <div className="ends">
        <b>{q.minLabel}</b>
        <b>{q.maxLabel}</b>
      </div>
    </div>
  );
}

/* ============================================================
   图文卡片
   ============================================================ */
function ImageQ({ q, value, onChange, justPicked }) {
  return (
    <div className="cards">
      {q.options.map((o) => (
        <button key={o.id}
          className={"card-opt" + (value === o.id ? " on" : "") + (justPicked === o.id ? " pop" : "")}
          onClick={() => onChange(o.id)}>
          <span className="ph"><code>{o.note}</code></span>
          <span className="cap">
            <span className="mark">{Icon.check({ style: value === o.id ? { opacity: 1, transform: "scale(1)" } : {} })}</span>
            <b>{o.label}</b>
          </span>
        </button>
      ))}
    </div>
  );
}

/* ============================================================
   排序题（箭头为主，桌面端支持拖拽）
   ============================================================ */
function RankQ({ q, value, onChange }) {
  const order = Array.isArray(value) && value.length === q.items.length
    ? value : q.items.map((i) => i.id);
  const byId = Object.fromEntries(q.items.map((i) => [i.id, i]));
  const dragId = useRef(null);
  const [dragging, setDragging] = useState(null);

  const move = (idx, dir) => {
    const j = idx + dir;
    if (j < 0 || j >= order.length) return;
    const next = order.slice();
    [next[idx], next[j]] = [next[j], next[idx]];
    onChange(next);
  };
  const onDrop = (overId) => {
    const from = order.indexOf(dragId.current);
    const to = order.indexOf(overId);
    if (from < 0 || to < 0 || from === to) return;
    const next = order.slice();
    next.splice(to, 0, next.splice(from, 1)[0]);
    onChange(next);
  };

  return (
    <div className="rank">
      {order.map((id, idx) => (
        <div key={id}
          className={"rank-item" + (dragging === id ? " dragging" : "")}
          draggable
          onDragStart={() => { dragId.current = id; setDragging(id); }}
          onDragEnd={() => { dragId.current = null; setDragging(null); }}
          onDragOver={(e) => e.preventDefault()}
          onDrop={() => onDrop(id)}>
          <span className={"rk" + (idx > 1 ? " low" : "")}>{idx + 1}</span>
          <span className="txt">{byId[id].label}</span>
          <span className="arrows">
            <button disabled={idx === 0} onClick={() => move(idx, -1)} aria-label="上移">{Icon.up()}</button>
            <button disabled={idx === order.length - 1} onClick={() => move(idx, 1)} aria-label="下移">{Icon.down()}</button>
          </span>
          <span className="grip">{Icon.grip()}</span>
        </div>
      ))}
    </div>
  );
}

/* ============================================================
   简答
   ============================================================ */
function TextQ({ q, value, onChange }) {
  const chips = ["松弛", "热气腾腾", "有光", "刚刚好", "热闹", "安静"];
  return (
    <div className="textq">
      <textarea value={value || ""} placeholder={q.placeholder}
        maxLength={40}
        onChange={(e) => onChange(e.target.value)} />
      <div className="chips">
        {chips.map((c) => (
          <button key={c} onClick={() => onChange(c)}>{c}</button>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, {
  Icon, Face,
  SingleChoice, MultiChoice, ScaleQ, ImageQ, RankQ, TextQ,
});
