/* ============================================================
   views.jsx — Dashboard, Expressions (CRUD), Summary
   ============================================================ */
const { useState: uS, useEffect: uE, useMemo: uM } = React;

const _UI = () => window.UI;

/* ---------- Expression card ---------- */
function ExprCard({ expr, onEdit, onDelete }) {
  const { FormalityBadge, Tag, IconButton, Icon, relDay } = window.UI;
  return (
    <div className="card card-hover col" style={{ gap: 12 }}>
      <div className="row between" style={{ alignItems: "flex-start" }}>
        <div className="grow">
          <div className="eng" style={{ marginBottom: 3 }}>{expr.expression}</div>
          <div className="muted" style={{ fontSize: 14 }}>{expr.meaning}</div>
        </div>
        <div className="row" style={{ gap: 0, marginRight: -6 }}>
          <IconButton name="edit" size={16} onClick={() => onEdit(expr)} aria-label="수정" />
          <IconButton name="trash" size={16} danger onClick={() => onDelete(expr)} aria-label="삭제" />
        </div>
      </div>
      {expr.examples && expr.examples[0] && (
        <div style={{ fontSize: 13.5, color: "var(--ink-2)", background: "var(--surface-2)", borderRadius: "var(--r-sm)", padding: "9px 11px", lineHeight: 1.5 }}>
          “{expr.examples[0]}”
        </div>
      )}
      <div className="row between wrap" style={{ gap: 8 }}>
        <div className="row wrap" style={{ gap: 6 }}>
          {expr.kind === "word" && <span className="badge" style={{ background: "var(--accent-soft)", color: "var(--accent-ink)" }}>단어</span>}
          <FormalityBadge value={expr.formality} />
          {(expr.tags || []).map((t) => <Tag key={t}>{t}</Tag>)}
        </div>
        <div className="faint row" style={{ gap: 5, fontSize: 12 }}>
          <Icon name="clock" size={13} /> {relDay(expr.nextReviewAt)} 복습
        </div>
      </div>
    </div>
  );
}

/* ---------- Add / edit form (modal) ---------- */
function ExpressionForm({ initial, onSave, onClose }) {
  const { Button, Field, Icon, AiPill, FormalityBadge, Tag, Spinner } = window.UI;
  const editing = !!(initial && initial.id);
  const [kind, setKind] = uS(initial?.kind || "expression");
  const [expression, setExpression] = uS(initial?.expression || "");
  const [meaning, setMeaning] = uS(initial?.meaning || "");
  const [meta, setMeta] = uS({
    examples: initial?.examples || [],
    situation: initial?.situation || "",
    formality: initial?.formality || "neutral",
    tags: initial?.tags || [],
  });
  const [loading, setLoading] = uS(false);
  const [err, setErr] = uS("");
  const [filled, setFilled] = uS(editing && (initial?.examples?.length > 0));

  async function autofill() {
    if (!expression.trim()) { setErr("영어 표현을 먼저 입력해 주세요."); return; }
    setLoading(true); setErr("");
    try {
      const r = await window.AI.enrichExpression({ expression: expression.trim(), meaning: meaning.trim(), kind });
      setMeaning(r.meaning || meaning);
      setMeta({ examples: r.examples, situation: r.situation, formality: r.formality, tags: r.tags });
      setFilled(true);
    } catch (e) { setErr("자동 채우기에 실패했어요. 다시 시도해 주세요."); }
    finally { setLoading(false); }
  }

  function save() {
    if (!expression.trim()) { setErr("영어 표현을 입력해 주세요."); return; }
    onSave({
      ...(initial || {}),
      kind,
      expression: expression.trim(),
      meaning: meaning.trim(),
      examples: meta.examples,
      situation: meta.situation,
      formality: meta.formality,
      tags: meta.tags,
    });
  }

  const FB = ["formal", "neutral", "casual"];
  const FL = { formal: "격식", neutral: "중립", casual: "캐주얼" };

  return (
    <window.UI.Modal
      title={editing ? "표현 수정" : "표현 추가"}
      onClose={onClose}
      foot={<>
        <Button variant="quiet" onClick={onClose}>취소</Button>
        <Button variant="primary" icon="check" onClick={save}>{editing ? "저장" : "추가"}</Button>
      </>}
    >
      <div className="col" style={{ gap: 16 }}>
        <div className="seg" style={{ alignSelf: "flex-start" }}>
          <button className={kind === "expression" ? "on" : ""} onClick={() => setKind("expression")}>표현</button>
          <button className={kind === "word" ? "on" : ""} onClick={() => setKind("word")}>단어</button>
        </div>
        <Field label={kind === "word" ? "영어 단어" : "영어 표현"}>
          <input className="input" autoFocus placeholder={kind === "word" ? "예: bandwidth" : "예: get the ball rolling"} value={expression}
            onChange={(e) => setExpression(e.target.value)} />
        </Field>
        <Field label="한글 뜻">
          <input className="input" placeholder="예: 일을 시작하다" value={meaning} onChange={(e) => setMeaning(e.target.value)} />
        </Field>

        {/* AI autofill */}
        <div style={{ border: "1px dashed var(--line)", borderRadius: "var(--r-md)", padding: 14, background: filled ? "var(--surface)" : "var(--accent-soft)" }}>
          {!filled ? (
            <div className="col" style={{ gap: 10 }}>
              <div className="row" style={{ gap: 8 }}>
                <AiPill>자동 채우기</AiPill>
                <span className="muted" style={{ fontSize: 13.5 }}>예문 · 상황 · 격식 태그를 AI가 채워줘요</span>
              </div>
              <Button variant="primary" size="sm" icon="sparkles" busy={loading} onClick={autofill} style={{ alignSelf: "flex-start" }}>
                AI로 채우기
              </Button>
            </div>
          ) : (
            <div className="col" style={{ gap: 12 }}>
              <div className="row between">
                <div className="row" style={{ gap: 8 }}><AiPill>자동 채움 완료</AiPill></div>
                <Button variant="quiet" size="sm" icon="repeat" busy={loading} onClick={autofill}>다시 채우기</Button>
              </div>
              {/* formality picker */}
              <div className="col" style={{ gap: 6 }}>
                <div className="label">격식</div>
                <div className="row" style={{ gap: 7 }}>
                  {FB.map((f) => (
                    <button key={f} className={"chip" + (meta.formality === f ? " on" : "")} onClick={() => setMeta({ ...meta, formality: f })}>{FL[f]}</button>
                  ))}
                </div>
              </div>
              {meta.tags?.length > 0 && (
                <div className="col" style={{ gap: 6 }}>
                  <div className="label">태그</div>
                  <div className="row wrap" style={{ gap: 6 }}>{meta.tags.map((t) => <Tag key={t}>{t}</Tag>)}</div>
                </div>
              )}
              {meta.situation && (
                <div className="col" style={{ gap: 5 }}>
                  <div className="label">사용 상황</div>
                  <div className="muted" style={{ fontSize: 14, lineHeight: 1.55 }}>{meta.situation}</div>
                </div>
              )}
              {meta.examples?.length > 0 && (
                <div className="col" style={{ gap: 6 }}>
                  <div className="label">예문</div>
                  <div className="col" style={{ gap: 6 }}>
                    {meta.examples.map((ex, i) => (
                      <div key={i} style={{ fontSize: 14, background: "var(--surface-2)", borderRadius: "var(--r-sm)", padding: "8px 11px", lineHeight: 1.5 }}>{ex}</div>
                    ))}
                  </div>
                </div>
              )}
            </div>
          )}
        </div>
        {err && <div style={{ color: "var(--bad)", fontSize: 13.5 }}>{err}</div>}
        {!window.AI.HAS_LLM && <div className="faint" style={{ fontSize: 12 }}>※ 미리보기 모드: 실제 환경에서는 AI가 진짜 응답을 채워줍니다.</div>}
      </div>
    </window.UI.Modal>
  );
}

/* ---------- Dashboard ---------- */
function Dashboard({ list, onStartReview, onAdd, goExpressions }) {
  const { Button, Icon, AiPill, FormalityBadge, Tag, agoDay } = window.UI;
  const Store = window.Store;
  const due = Store.dueList(list);
  const totalReviews = list.reduce((s, e) => s + (e.reviewCount || 0), 0);
  const recent = [...list].sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0)).slice(0, 4);
  const dateStr = new Date().toLocaleDateString("ko-KR", { month: "long", day: "numeric", weekday: "long" });

  return (
    <div>
      <div className="page-head">
        <div className="faint" style={{ fontSize: 13, marginBottom: 6 }}>{dateStr}</div>
        <h1 className="h-xl">오늘도 한 걸음 더.</h1>
      </div>

      {/* hero review CTA */}
      <div className="card" style={{ padding: 0, overflow: "hidden", marginBottom: 22 }}>
        <div className="row between wrap" style={{ gap: 18, padding: 24 }}>
          <div className="col" style={{ gap: 6, flex: "1 1 300px", minWidth: 0 }}>
            <div className="row" style={{ gap: 8 }}>
              <Icon name="flame" size={16} style={{ color: "var(--accent)", flex: "none" }} />
              <span className="label" style={{ color: "var(--accent-ink)", whiteSpace: "nowrap" }}>오늘의 복습</span>
            </div>
            <div className="h-lg" style={{ marginTop: 2 }}>
              {due.length > 0 ? <>복습할 표현 <span style={{ color: "var(--accent)" }}>{due.length}개</span>가 기다려요</> : "오늘 복습을 모두 마쳤어요 🎉"}
            </div>
            <div className="muted" style={{ fontSize: 14 }}>
              {due.length > 0 ? "망각곡선에 맞춰 딱 필요한 표현만 골라뒀어요." : "내일 다시 만나거나, 새 표현을 추가해 보세요."}
            </div>
          </div>
          {due.length > 0
            ? <Button variant="primary" size="lg" iconRight="arrowRight" onClick={onStartReview}>오늘의 복습 시작</Button>
            : <Button variant="ghost" size="lg" icon="plus" onClick={onAdd}>표현 추가</Button>}
        </div>
      </div>

      {/* weekly study calendar */}
      <WeeklyCalendar />

      {/* stats */}
      <div className="stat-grid" style={{ marginBottom: 30 }}>
        <div className="stat">
          <div className="stat-n" style={{ color: due.length ? "var(--accent)" : "var(--ink-1)" }}>{due.length}</div>
          <div className="stat-l">오늘 복습할 표현</div>
        </div>
        <div className="stat">
          <div className="stat-n">{list.length}</div>
          <div className="stat-l">모은 표현 수</div>
        </div>
        <div className="stat">
          <div className="stat-n">{totalReviews}</div>
          <div className="stat-l">누적 복습 횟수</div>
        </div>
      </div>

      {/* recent */}
      <div className="row between" style={{ marginBottom: 14 }}>
        <div className="h-md" style={{ whiteSpace: "nowrap" }}>최근 추가한 표현</div>
        <Button variant="quiet" size="sm" iconRight="chevronRight" onClick={goExpressions}>전체 보기</Button>
      </div>
      {recent.length === 0 ? (
        <window.UI.EmptyState title="아직 표현이 없어요" sub="마음에 드는 영어 표현을 추가해 보세요." action={<Button variant="primary" icon="plus" onClick={onAdd}>첫 표현 추가</Button>} />
      ) : (
        <div className="col" style={{ gap: 10 }}>
          {recent.map((e) => (
            <div key={e.id} className="card card-hover row between" style={{ padding: "14px 16px", cursor: "pointer" }} onClick={goExpressions}>
              <div className="grow">
                <div className="row wrap" style={{ gap: 8, alignItems: "baseline" }}>
                  <span className="eng" style={{ fontSize: 16.5 }}>{e.expression}</span>
                  <span className="faint" style={{ fontSize: 13.5 }}>{e.meaning}</span>
                </div>
              </div>
              <div className="row" style={{ gap: 10 }}>
                <FormalityBadge value={e.formality} />
                <span className="faint" style={{ fontSize: 12.5, minWidth: 44, textAlign: "right" }}>{agoDay(e.createdAt)}</span>
              </div>
            </div>
          ))}
        </div>
      )}
      {/* theme / color samples */}
      <div className="card" style={{ marginTop: 30 }}>
        <div className="row between wrap" style={{ gap: 8, marginBottom: 4 }}>
          <div className="h-md">테마 색상</div>
          <span className="faint" style={{ fontSize: 13 }}>포인트 컴러 샘플</span>
        </div>
        <div className="muted" style={{ fontSize: 13.5, marginBottom: 14 }}>골라보세요 — 선택하면 앱 전체에 바로 적용돼요.</div>
        <ThemePicker variant="cards" />
      </div>
    </div>
  );
}
function ExpressionsView({ list, onSave, onDelete, openForm, formState, closeForm }) {
  const { Button, Icon, EmptyState } = window.UI;
  const Store = window.Store;
  const [q, setQ] = uS("");
  const [tag, setTag] = uS(null);
  const [sort, setSort] = uS("recent");
  const tags = Store.allTags(list);

  const shown = uM(() => {
    let r = list.filter((e) => {
      const hay = (e.expression + " " + e.meaning + " " + (e.tags || []).join(" ")).toLowerCase();
      return hay.includes(q.toLowerCase());
    });
    if (tag) r = r.filter((e) => (e.tags || []).includes(tag));
    const cmp = {
      recent: (a, b) => (b.createdAt || 0) - (a.createdAt || 0),
      alpha: (a, b) => a.expression.localeCompare(b.expression),
      due: (a, b) => (a.nextReviewAt || 0) - (b.nextReviewAt || 0),
    }[sort];
    return [...r].sort(cmp);
  }, [list, q, tag, sort]);

  return (
    <div>
      <div className="page-head row between wrap" style={{ gap: 12 }}>
        <div>
          <h1 className="h-xl">표현</h1>
          <div className="muted" style={{ fontSize: 14, marginTop: 2 }}>{list.length}개의 표현을 모았어요</div>
        </div>
        <Button variant="primary" icon="plus" onClick={() => openForm(null)}>표현 추가</Button>
      </div>

      {/* controls */}
      <div className="row wrap" style={{ gap: 10, marginBottom: 14 }}>
        <div className="search">
          <Icon name="search" size={16} style={{ color: "var(--ink-3)" }} />
          <input placeholder="표현 · 뜻 · 태그 검색" value={q} onChange={(e) => setQ(e.target.value)} />
        </div>
        <select className="select" value={sort} onChange={(e) => setSort(e.target.value)}>
          <option value="recent">최근 추가순</option>
          <option value="alpha">알파벳순</option>
          <option value="due">복습 임박순</option>
        </select>
      </div>

      {tags.length > 0 && (
        <div className="row wrap" style={{ gap: 7, marginBottom: 20 }}>
          <button className={"chip" + (tag === null ? " on" : "")} onClick={() => setTag(null)}>전체</button>
          {tags.map((t) => <button key={t} className={"chip" + (tag === t ? " on" : "")} onClick={() => setTag(tag === t ? null : t)}>{t}</button>)}
        </div>
      )}

      {shown.length === 0 ? (
        <EmptyState title={q || tag ? "조건에 맞는 표현이 없어요" : "아직 표현이 없어요"} sub={q || tag ? "검색어나 필터를 바꿔보세요." : "마음에 드는 표현을 추가해 시작하세요."}
          action={!q && !tag && <Button variant="primary" icon="plus" onClick={() => openForm(null)}>표현 추가</Button>} />
      ) : (
        <div className="expr-grid">
          {shown.map((e) => <ExprCard key={e.id} expr={e} onEdit={openForm} onDelete={onDelete} />)}
        </div>
      )}

      {formState.open && (
        <ExpressionForm initial={formState.expr} onClose={closeForm} onSave={(data) => { onSave(data); closeForm(); }} />
      )}
    </div>
  );
}

/* ---------- Summary / organize view ---------- */
function SummaryView({ list }) {
  const { Button, Icon, AiPill, FormalityBadge, Tag, EmptyState, agoDay, Spinner } = window.UI;
  const Store = window.Store;
  const [mode, setMode] = uS("tag");          // tag | date
  const [groups, setGroups] = uS(null);       // AI topic summary
  const [loading, setLoading] = uS(false);
  const [err, setErr] = uS("");

  // group by tag
  const byTag = uM(() => {
    const m = {};
    list.forEach((e) => {
      const ts = (e.tags && e.tags.length) ? e.tags : ["태그 없음"];
      ts.forEach((t) => { (m[t] = m[t] || []).push(e); });
    });
    return Object.entries(m).sort((a, b) => b[1].length - a[1].length);
  }, [list]);

  // group by added-date bucket
  const byDate = uM(() => {
    const m = {};
    list.forEach((e) => {
      const d = agoDay(e.createdAt);
      const bucket = d === "오늘" || d === "어제" ? "최근" : d.includes("일") ? "이번 주" : d.includes("주") ? "이번 달" : "이전";
      (m[bucket] = m[bucket] || []).push(e);
    });
    const order = ["최근", "이번 주", "이번 달", "이전"];
    return order.filter((k) => m[k]).map((k) => [k, m[k]]);
  }, [list]);

  async function runSummary() {
    setLoading(true); setErr("");
    try { setGroups(await window.AI.summarizeByTopic(list)); }
    catch (e) { setErr("요약에 실패했어요. 다시 시도해 주세요."); }
    finally { setLoading(false); }
  }

  const grouped = mode === "tag" ? byTag : byDate;

  if (list.length === 0) {
    return <div><div className="page-head"><h1 className="h-xl">정리</h1></div>
      <EmptyState title="정리할 표현이 없어요" sub="표현을 추가하면 태그·날짜별로 모아 보여드려요." /></div>;
  }

  return (
    <div>
      <div className="page-head">
        <h1 className="h-xl">정리</h1>
        <div className="muted" style={{ fontSize: 14, marginTop: 2 }}>모은 표현을 묶어 보고, AI 요약으로 한눈에 정리해요</div>
      </div>

      {/* AI topic summary */}
      <div className="card" style={{ marginBottom: 26, background: "var(--accent-soft)", borderColor: "#d8e8df" }}>
        <div className="row between wrap" style={{ gap: 12 }}>
          <div className="col" style={{ gap: 4 }}>
            <div className="row" style={{ gap: 8 }}><AiPill>주제별 요약</AiPill></div>
            <div className="muted" style={{ fontSize: 14 }}>내가 모은 표현을 AI가 주제별로 묶어 정리해줘요.</div>
          </div>
          <Button variant="primary" icon="sparkles" busy={loading} onClick={runSummary}>{groups ? "다시 요약" : "AI 요약 생성"}</Button>
        </div>
        {err && <div style={{ color: "var(--bad)", fontSize: 13.5, marginTop: 12 }}>{err}</div>}
        {groups && (
          <div className="col rise" style={{ gap: 12, marginTop: 16 }}>
            {groups.map((g, i) => (
              <div key={i} className="card" style={{ padding: 16 }}>
                <div className="row between" style={{ marginBottom: 6 }}>
                  <div className="h-md">{g.theme}</div>
                  <span className="faint" style={{ fontSize: 12.5 }}>{g.items.length}개</span>
                </div>
                {g.note && <div className="muted" style={{ fontSize: 13.5, marginBottom: 10 }}>{g.note}</div>}
                <div className="row wrap" style={{ gap: 6 }}>
                  {g.items.map((it, j) => <span key={j} className="badge" style={{ background: "var(--surface-2)" }}>{it}</span>)}
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* group toggle */}
      <div className="row" style={{ gap: 7, marginBottom: 18 }}>
        <button className={"chip" + (mode === "tag" ? " on" : "")} onClick={() => setMode("tag")}>태그별</button>
        <button className={"chip" + (mode === "date" ? " on" : "")} onClick={() => setMode("date")}>추가 날짜별</button>
      </div>

      <div className="col" style={{ gap: 24 }}>
        {grouped.map(([key, items]) => (
          <div key={key}>
            <div className="row" style={{ gap: 8, marginBottom: 11 }}>
              <div className="h-md">{key}</div>
              <span className="faint" style={{ fontSize: 13 }}>{items.length}</span>
            </div>
            <div className="col" style={{ gap: 8 }}>
              {items.map((e) => (
                <div key={e.id + key} className="card row between" style={{ padding: "12px 15px" }}>
                  <div className="row wrap" style={{ gap: 9, alignItems: "baseline" }}>
                    <span className="eng" style={{ fontSize: 16 }}>{e.expression}</span>
                    <span className="faint" style={{ fontSize: 13.5 }}>{e.meaning}</span>
                  </div>
                  <FormalityBadge value={e.formality} />
                </div>
              ))}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Weekly study calendar ---------- */
function WeeklyCalendar() {
  const { Icon } = window.UI;
  const Store = window.Store;
  const [off, setOff] = uS(0);
  const act = Store.getActivity();
  const days = Store.weekDays(off);
  const todayKey = Store.dkey(Store.now());
  const total = days.reduce((s, d) => s + (act[d.key] || 0), 0);
  const labels = ["월", "화", "수", "목", "금", "토", "일"];
  const fmt = (d) => `${d.getMonth() + 1}.${d.getDate()}`;
  const weekLabel = off === 0 ? "이번 주" : off === -1 ? "지난 주" : `${fmt(days[0].date)}–${fmt(days[6].date)}`;
  const pctFor = (c) => (c <= 0 ? 0 : c <= 1 ? 28 : c <= 2 ? 46 : c <= 3 ? 64 : c <= 4 ? 82 : 100);

  return (
    <div className="card" style={{ marginBottom: 22 }}>
      <div className="row between" style={{ marginBottom: 16 }}>
        <div className="row" style={{ gap: 10 }}>
          <div className="h-md" style={{ whiteSpace: "nowrap" }}>주간 학습</div>
          <span className="faint" style={{ fontSize: 13, whiteSpace: "nowrap" }}>{weekLabel} · {total}개</span>
        </div>
        <div className="row" style={{ gap: 2 }}>
          <button className="icon-btn" onClick={() => setOff(off - 1)} aria-label="이전 주"><Icon name="chevronRight" size={18} style={{ transform: "rotate(180deg)" }} /></button>
          <button className="icon-btn" disabled={off >= 0} style={off >= 0 ? { opacity: .35, cursor: "default" } : null} onClick={() => off < 0 && setOff(off + 1)} aria-label="다음 주"><Icon name="chevronRight" size={18} /></button>
        </div>
      </div>
      <div className="wk-grid">
        {days.map((d, i) => {
          const c = act[d.key] || 0;
          const pct = pctFor(c);
          const isToday = d.key === todayKey;
          return (
            <div key={d.key} className="wk-col">
              <div className="wk-dow">{labels[i]}</div>
              <div className="wk-cell" style={{
                background: pct === 0 ? "var(--surface-2)" : `color-mix(in srgb, var(--accent) ${pct}%, #fff)`,
                color: c >= 3 ? "#fff" : "var(--ink-2)",
                outline: isToday ? "2px solid var(--accent)" : "none", outlineOffset: 2,
              }}>{c > 0 ? c : ""}</div>
              <div className="wk-date">{d.date.getDate()}</div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ---------- Theme / accent color picker ---------- */
function ThemePicker({ variant }) {
  const { Icon } = window.UI;
  const [cur, setCur] = uS(() => { try { return localStorage.getItem("cnh_theme_v1") || "pine"; } catch (e) { return "pine"; } });
  const apply = (id) => { window.applyTheme(id); setCur(id); };

  if (variant === "cards") {
    return (
      <div className="row wrap" style={{ gap: 10 }}>
        {window.THEMES.map((t) => (
          <button key={t.id} className="theme-card" onClick={() => apply(t.id)} aria-pressed={cur === t.id}
            style={{ borderColor: cur === t.id ? t.vars["--accent"] : "var(--line)" }}>
            <span className="theme-dot" style={{ background: t.vars["--accent"] }} />
            <span style={{ fontSize: 13.5, fontWeight: 600, color: cur === t.id ? "var(--ink-1)" : "var(--ink-2)" }}>{t.name}</span>
            {cur === t.id && <Icon name="check" size={14} style={{ color: t.vars["--accent"] }} />}
          </button>
        ))}
      </div>
    );
  }
  // compact dots (sidebar)
  return (
    <div className="row" style={{ gap: 8 }}>
      {window.THEMES.map((t) => (
        <button key={t.id} onClick={() => apply(t.id)} title={t.name} aria-label={t.name}
          style={{
            width: 20, height: 20, borderRadius: "50%", background: t.vars["--accent"], cursor: "pointer",
            border: "2px solid var(--surface)",
            boxShadow: cur === t.id ? `0 0 0 2px ${t.vars["--accent"]}` : "0 0 0 1px var(--line)",
          }} />
      ))}
    </div>
  );
}

/* ---------- Word composition practice (free) ---------- */
function WordPractice({ onSave }) {
  const { Button, Icon, AiPill, Spinner, FormalityBadge, Tag } = window.UI;
  const AI = window.AI;
  const [word, setWord] = uS("");
  const [hint, setHint] = uS(null);
  const [hintLoading, setHintLoading] = uS(false);
  const [draft, setDraft] = uS("");
  const [res, setRes] = uS(null);
  const [evalLoading, setEvalLoading] = uS(false);
  const [saved, setSaved] = uS(false);
  const [err, setErr] = uS("");

  function reset() { setWord(""); setHint(null); setDraft(""); setRes(null); setSaved(false); setErr(""); }

  async function getHint() {
    if (!word.trim()) { setErr("단어를 먼저 입력해 주세요."); return; }
    setHintLoading(true); setErr("");
    try { setHint(await AI.enrichExpression({ expression: word.trim(), meaning: "", kind: "word" })); }
    catch (e) { setErr("힌트를 불러오지 못했어요. 다시 시도해 주세요."); }
    finally { setHintLoading(false); }
  }

  async function runEval() {
    if (!word.trim() || !draft.trim()) return;
    setEvalLoading(true); setErr("");
    try {
      const r = await AI.evaluateWriting({ expression: word.trim(), meaning: hint?.meaning || "", sentence: draft.trim(), kind: "word" });
      setRes(r);
      window.Store.logStudy(1);
    } catch (e) { setErr("평가를 불러오지 못했어요. 다시 시도해 주세요."); }
    finally { setEvalLoading(false); }
  }

  function saveWord() {
    onSave({
      kind: "word",
      expression: word.trim(),
      meaning: hint?.meaning || "",
      examples: hint?.examples || (draft.trim() ? [draft.trim()] : []),
      situation: hint?.situation || "",
      formality: hint?.formality || "neutral",
      tags: hint?.tags || [],
    });
    setSaved(true);
  }

  return (
    <div style={{ maxWidth: 620 }}>
      <div className="card" style={{ marginBottom: 16 }}>
        <div className="row" style={{ gap: 10, alignItems: "flex-end" }}>
          <div className="field grow">
            <label>연습할 단어</label>
            <input className="input" placeholder="예: bandwidth, leverage, robust…" value={word}
              onChange={(e) => { setWord(e.target.value); setSaved(false); }}
              onKeyDown={(e) => { if (e.key === "Enter") getHint(); }} />
          </div>
          <Button variant="ghost" icon="sparkles" busy={hintLoading} onClick={getHint}>예문 힌트</Button>
        </div>

        {hint && (
          <div className="rise" style={{ marginTop: 14, background: "var(--surface-2)", borderRadius: "var(--r-md)", padding: "13px 15px" }}>
            <div className="row wrap" style={{ gap: 7, marginBottom: 8 }}>
              <span className="badge" style={{ background: "var(--accent-soft)", color: "var(--accent-ink)" }}>단어</span>
              <FormalityBadge value={hint.formality} />
              {(hint.tags || []).map((t) => <Tag key={t}>{t}</Tag>)}
            </div>
            {hint.meaning && <div style={{ fontSize: 15, fontWeight: 600, marginBottom: 6 }}>{hint.meaning}</div>}
            {hint.examples && hint.examples[0] && (
              <div className="col" style={{ gap: 5 }}>
                {hint.examples.slice(0, 2).map((ex, i) => (
                  <div key={i} style={{ fontSize: 14, color: "var(--ink-2)", lineHeight: 1.5 }}>· {ex}</div>
                ))}
              </div>
            )}
          </div>
        )}
      </div>

      <div className="card">
        <div className="field" style={{ marginBottom: res ? 18 : 12 }}>
          <label>이 단어로 직접 문장을 만들어 보세요</label>
          <textarea className="textarea" rows={3} placeholder={word ? `"${word}" 를 넣어 문장을 써보세요…` : "위에서 단어를 먼저 입력하세요"}
            value={draft} onChange={(e) => setDraft(e.target.value)} disabled={evalLoading} />
        </div>

        {res && (
          <div className="col rise" style={{ gap: 12, marginBottom: 18 }}>
            {!res.usedExpression && (
              <div className="eval" style={{ background: "var(--warn-soft)", borderColor: "#eadfca" }}>
                <div className="eval-h" style={{ color: "var(--warn)" }}><Icon name="x" size={14} /> 단어 미사용</div>
                <div style={{ marginTop: 6, fontSize: 14.5 }}>이 문장에는 그 단어가 들어있지 않아요. 단어를 넣어 다시 써볼까요?</div>
              </div>
            )}
            <div className="row" style={{ gap: 10, alignItems: "center" }}>
              <div className="label" style={{ color: "var(--ink-2)" }}>평가 점수</div>
              <div className="grow progress"><i style={{ width: `${res.score}%` }} /></div>
              <div style={{ fontWeight: 750, fontSize: 16, letterSpacing: "-.02em" }}>{res.score}</div>
            </div>
            <div className={"eval " + (res.grammarOk ? "g" : "n")}>
              <div className="eval-h"><Icon name="check" size={14} /> 문법 정확성</div>
              <div style={{ marginTop: 6, fontSize: 14.5, lineHeight: 1.55 }}>{res.grammar}</div>
            </div>
            <div className="eval n">
              <div className="eval-h"><Icon name="book" size={14} /> 자연스러움</div>
              <div style={{ marginTop: 6, fontSize: 14.5, lineHeight: 1.55 }}>{res.naturalness}</div>
            </div>
            <div className="eval s">
              <div className="eval-h"><Icon name="sparkles" size={14} /> 더 나은 표현</div>
              <div style={{ marginTop: 6, fontSize: 15.5, fontWeight: 550, lineHeight: 1.5 }}>{res.suggestion}</div>
              {res.suggestionWhy && <div className="faint" style={{ fontSize: 13.5, marginTop: 5 }}>{res.suggestionWhy}</div>}
            </div>
          </div>
        )}

        {err && <div style={{ color: "var(--bad)", fontSize: 13.5, marginBottom: 12 }}>{err}</div>}

        <div className="row wrap" style={{ gap: 10 }}>
          {!res ? (
            <Button variant="primary" icon="sparkles" busy={evalLoading} disabled={!word.trim() || !draft.trim()} onClick={runEval}>AI 평가 받기</Button>
          ) : (
            <>
              <Button variant="ghost" icon={saved ? "check" : "plus"} disabled={saved} onClick={saveWord}>{saved ? "노트에 저장됨" : "노트에 저장"}</Button>
              <Button variant="quiet" icon="repeat" onClick={reset}>다른 단어로</Button>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Dashboard, ExpressionsView, SummaryView, ExpressionForm, WeeklyCalendar, ThemePicker, WordPractice });
