/* 共通 UI コンポーネント */
const { useState, useEffect, useRef } = React;
const Icons = window.SV_Icons;

// アバターのトーン（顔写真プレースホルダ＝姓の頭文字）
const TONES = {
  a: { bg: "#DCEFEC", fg: "#1E7385" },
  b: { bg: "#E7ECF3", fg: "#3A6184" },
  c: { bg: "#F2EADF", fg: "#9A6E2E" },
  d: { bg: "#E3EFE6", fg: "#3E7E5C" },
  e: { bg: "#ECE7F0", fg: "#6B5A86" },
  f: { bg: "#EFE7E5", fg: "#8E5A4E" },
};

function Avatar({ s, size = 44, ring = false }) {
  const t = TONES[s.tone] || TONES.a;
  return (
    <div style={{
      width: size, height: size, borderRadius: "50%", flexShrink: 0,
      background: t.bg, color: t.fg, display: "grid", placeItems: "center",
      fontFamily: "var(--disp)", fontWeight: 700, fontSize: size * 0.42,
      boxShadow: ring ? `0 0 0 3px #fff, 0 0 0 4.5px ${t.fg}33` : "none",
      letterSpacing: ".02em",
    }}>{s.initial}</div>
  );
}

// おすすめ度 ★（3段階・0.5刻み対応）
function Stars({ value, size = 16, showLabel = false }) {
  const full = Math.floor(value);
  const half = value - full >= 0.5;
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 3, color: "var(--star)" }}>
      {[0, 1, 2].map((i) => (
        <span key={i} style={{ display: "inline-flex" }}>
          {i < full ? <Icons.star size={size} filled /> : i === full && half ? <Icons.starHalf size={size} /> : <Icons.star size={size} filled={false} />}
        </span>
      ))}
      {showLabel && <span style={{ fontSize: 12.5, color: "var(--ink-2)", marginLeft: 4 }}>おすすめ度</span>}
    </span>
  );
}

// 適合バッジ
const FIT_STYLE = {
  "適合": { c: "var(--fit)", bg: "var(--fit-bg)", icon: "checkCircle" },
  "ほぼ適合": { c: "var(--fit)", bg: "var(--fit-bg)", icon: "checkCircle" },
  "要相談": { c: "var(--consult)", bg: "var(--consult-bg)", icon: "consult" },
  "不適合": { c: "var(--miss)", bg: "var(--miss-bg)", icon: "miss" },
};
function FitBadge({ value, size = "md" }) {
  const st = FIT_STYLE[value] || FIT_STYLE["要相談"];
  const Icon = Icons[st.icon];
  const small = size === "sm";
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: small ? 4 : 5,
      color: st.c, background: st.bg, borderRadius: 999,
      padding: small ? "3px 9px 3px 7px" : "5px 12px 5px 9px",
      fontSize: small ? 12 : 13, fontWeight: 700, whiteSpace: "nowrap",
    }}>
      <Icon size={small ? 13 : 15} /> {value}
    </span>
  );
}

// タイプコードチップ
function TypeChip({ code, label }) {
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 7, background: "var(--brand-50)", border: "1px solid var(--brand-100)", borderRadius: 999, padding: "4px 11px 4px 9px", color: "var(--brand-700)", fontSize: 12.5, fontWeight: 600 }}>
      <span className="num" style={{ fontWeight: 700, letterSpacing: ".08em", fontSize: 12 }}>{code}</span>
      {label && <span style={{ color: "var(--ink-2)", fontWeight: 500, fontSize: 11.5 }}>{label}</span>}
    </span>
  );
}

// 汎用ピル/タグ
function Pill({ children, color = "var(--ink-2)", bg = "var(--surface-3)", icon: Icon, sw }) {
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 5, color, background: bg, borderRadius: 999, padding: "4px 10px", fontSize: 12, fontWeight: 600, whiteSpace: "nowrap" }}>
      {Icon && <Icon size={13} />}{children}
    </span>
  );
}

// 活性度ドット
function Activity({ level, text }) {
  const map = { high: "#3E9B6E", mid: "var(--star)", low: "var(--ink-3)" };
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 12, color: "var(--ink-2)" }}>
      <span style={{ width: 7, height: 7, borderRadius: "50%", background: map[level], boxShadow: level === "high" ? `0 0 0 3px ${map[level]}22` : "none" }} />
      {text}
    </span>
  );
}

// ボタン
function Button({ children, variant = "primary", size = "md", icon: Icon, iconRight: IconR, onClick, full, disabled, style }) {
  const sizes = {
    sm: { padding: "7px 13px", fontSize: 13, gap: 6, r: 9 },
    md: { padding: "10px 17px", fontSize: 14, gap: 7, r: 11 },
    lg: { padding: "13px 22px", fontSize: 15, gap: 8, r: 12 },
  }[size];
  const variants = {
    primary: { background: "var(--brand-600)", color: "#fff", boxShadow: "0 1px 2px rgba(20,80,90,.18)", border: "1px solid var(--brand-700)" },
    dark: { background: "var(--brand-900)", color: "#fff", border: "1px solid var(--brand-900)" },
    ghost: { background: "#fff", color: "var(--brand-700)", border: "1px solid var(--border-strong)" },
    subtle: { background: "var(--brand-50)", color: "var(--brand-700)", border: "1px solid var(--brand-100)" },
    plain: { background: "transparent", color: "var(--ink-2)", border: "1px solid transparent" },
    danger: { background: "#fff", color: "var(--miss)", border: "1px solid #E7D2CE" },
  }[variant];
  const [hov, setHov] = useState(false);
  return (
    <button onClick={onClick} disabled={disabled} onMouseEnter={() => setHov(true)} onMouseLeave={() => setHov(false)}
      style={{
        display: "inline-flex", alignItems: "center", justifyContent: "center", gap: sizes.gap,
        padding: sizes.padding, fontSize: sizes.fontSize, fontWeight: 700, borderRadius: sizes.r,
        width: full ? "100%" : "auto", opacity: disabled ? 0.5 : 1,
        cursor: disabled ? "not-allowed" : "pointer",
        transition: "transform .12s, filter .15s, box-shadow .15s", ...variants,
        filter: hov && !disabled ? "brightness(1.04)" : "none",
        transform: hov && !disabled ? "translateY(-1px)" : "none",
        ...style,
      }}>
      {Icon && <Icon size={sizes.fontSize + 3} />}{children}{IconR && <IconR size={sizes.fontSize + 2} />}
    </button>
  );
}

// カード
function Card({ children, style, pad = 20, hover, onClick, className = "" }) {
  const [h, setH] = useState(false);
  return (
    <div className={className} onClick={onClick} onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        background: "var(--surface)", border: "1px solid var(--border)", borderRadius: "var(--r-lg)",
        padding: pad, boxShadow: hover && h ? "var(--shadow-md)" : "var(--shadow-sm)",
        transition: "box-shadow .2s, transform .2s, border-color .2s",
        transform: hover && h ? "translateY(-2px)" : "none",
        borderColor: hover && h ? "var(--border-strong)" : "var(--border)",
        cursor: onClick ? "pointer" : "default", ...style,
      }}>{children}</div>
  );
}

// セクション見出し
function SectionTitle({ kicker, title, desc, right, icon: Icon }) {
  return (
    <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 16, marginBottom: 16 }}>
      <div>
        {kicker && <div style={{ display: "flex", alignItems: "center", gap: 7, color: "var(--brand-600)", fontSize: 12.5, fontWeight: 700, letterSpacing: ".04em", marginBottom: 7 }}>{Icon && <Icon size={15} />}{kicker}</div>}
        {title && <h2 className="disp" style={{ fontSize: 21, fontWeight: 700, color: "var(--ink)", letterSpacing: ".01em" }}>{title}</h2>}
        {desc && <p style={{ fontSize: 13.5, color: "var(--ink-2)", marginTop: kicker && !title ? 0 : 6, lineHeight: 1.6 }}>{desc}</p>}
      </div>
      {right}
    </div>
  );
}

// 注記ノート
function Note({ children, icon: Icon = Icons.shield, tone = "neutral" }) {
  const tones = {
    neutral: { bg: "var(--surface-3)", c: "var(--ink-2)", ic: "var(--ink-3)" },
    brand: { bg: "var(--brand-50)", c: "var(--brand-800)", ic: "var(--brand-500)" },
    warn: { bg: "var(--consult-bg)", c: "#7A5A1C", ic: "var(--consult)" },
  }[tone];
  return (
    <div style={{ display: "flex", gap: 9, alignItems: "flex-start", background: tones.bg, borderRadius: "var(--r-md)", padding: "11px 13px", fontSize: 12.5, lineHeight: 1.65, color: tones.c }}>
      <span style={{ color: tones.ic, flexShrink: 0, marginTop: 1 }}><Icon size={16} /></span>
      <span>{children}</span>
    </div>
  );
}

// モーダル
function Modal({ open, onClose, children, width = 600 }) {
  useEffect(() => {
    if (!open) return;
    const h = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(18,40,45,.42)", backdropFilter: "blur(3px)", zIndex: 100, display: "grid", placeItems: "center", padding: 24, animation: "fadeIn .18s both" }}>
      <div onClick={(e) => e.stopPropagation()} style={{ background: "var(--surface)", borderRadius: "var(--r-xl)", width: "min(100%," + width + "px)", maxHeight: "90vh", overflow: "auto", boxShadow: "var(--shadow-lg)", animation: "scaleIn .22s cubic-bezier(.2,.7,.3,1) both" }}>
        {children}
      </div>
    </div>
  );
}

window.SV_UI = { Avatar, Stars, FitBadge, TypeChip, Pill, Activity, Button, Card, SectionTitle, Note, Modal, TONES };
