/* ============================================================
   api.jsx — AI / LLM layer  (window.AI)
   ------------------------------------------------------------
   Every AI feature in the app routes through this single file.
   All calls go to the LLM via our own /api/ai proxy (Gemini Flash),
   authenticated with the user's access key (x-app-key).
   Each function builds a prompt, asks for strict JSON, and
   parses it. Nothing else in the app talks to the model.
   ============================================================ */

// Hosted mode: AI runs through our own /api/ai proxy (Gemini Flash).
const HAS_LLM = true;

function _authKey() {
  return (typeof window !== "undefined" && window.Auth && window.Auth.getKey()) || null;
}

/* ---- low-level: ask the model and parse a JSON object ---- */
async function askJSON(prompt) {
  const key = _authKey();
  if (!key) return mock(prompt);              // not logged in -> offline/preview fallback
  let res;
  try {
    res = await fetch("/api/ai", {
      method: "POST",
      headers: { "Content-Type": "application/json", "x-app-key": key },
      body: JSON.stringify({ prompt }),
    });
  } catch (e) {
    return mock(prompt);                      // network error -> graceful fallback
  }
  if (res.status === 401) {
    if (window.Auth) window.Auth.clear();
    throw new Error("인증이 만료되었어요. 새로고침 후 접속 키를 다시 입력해 주세요.");
  }
  if (res.status === 429) throw new Error("AI 요청이 잠시 많아요. 잠시 후 다시 시도해 주세요.");
  if (!res.ok) throw new Error("AI 요청 실패 (" + res.status + ")");
  const data = await res.json();
  return parseJSON(data.text);
}

function parseJSON(raw) {
  if (!raw) throw new Error("빈 응답");
  let s = String(raw).trim();
  // strip ```json fences if present
  s = s.replace(/^```(?:json)?/i, "").replace(/```$/, "").trim();
  const a = s.indexOf("{"), b = s.lastIndexOf("}");
  if (a !== -1 && b !== -1) s = s.slice(a, b + 1);
  return JSON.parse(s);
}

/* ============================================================
   1. 표현 메타데이터 자동 채우기
   입력: 영어 표현 + 한글 뜻
   출력: 예문 2~3개, 사용 상황/뉘앙스, 격식 태그, 주제 태그
   ============================================================ */
async function enrichExpression({ expression, meaning, kind = "expression" }) {
  const term = kind === "word" ? "word" : "expression";
  const prompt = `You are an English tutor for a Korean software developer preparing to study abroad.
For the English ${term} below, return ONLY a JSON object — no prose, no markdown.

${term === "word" ? "Word" : "Expression"}: "${expression}"
Korean meaning: "${meaning || "(not given — infer it)"}"

JSON shape:
{
  "meaning": "<natural Korean meaning, short — keep the user's if given>",
  "examples": ["<3 natural English sentences that USE the ${term} in a developer/study-abroad context>"],
  "situation": "<1-2 sentences in Korean: when & how to use it, nuance>",
  "formality": "formal" | "neutral" | "casual",
  "tags": ["<2-3 short Korean topic tags, e.g. 업무, 이메일, 일상>"]
}`;
  const r = await askJSON(prompt);
  return {
    meaning: (r.meaning || meaning || "").trim(),
    examples: (r.examples || []).slice(0, 3),
    situation: (r.situation || "").trim(),
    formality: ["formal", "neutral", "casual"].includes(r.formality) ? r.formality : "neutral",
    tags: (r.tags || []).slice(0, 3),
  };
}

/* ============================================================
   2. 응용 예문 생성 (학습 모드 1단계)
   기존 예문과 다른, 새 상황의 예문을 1개 생성
   ============================================================ */
async function freshExample({ expression, meaning, avoid = [], kind = "expression" }) {
  const term = kind === "word" ? "word" : "expression";
  const prompt = `Write ONE fresh, natural English example sentence using the ${term} "${expression}" (meaning: ${meaning}).
Make it different from these already-seen sentences: ${JSON.stringify(avoid)}.
Context: everyday work / study-abroad life. Return ONLY JSON:
{ "sentence": "<the sentence>", "gloss": "<short Korean translation of the sentence>" }`;
  const r = await askJSON(prompt);
  return { sentence: (r.sentence || "").trim(), gloss: (r.gloss || "").trim() };
}

/* ============================================================
   3. 작문 평가 (학습 모드 3단계)
   사용자 문장을 받아 문법 / 자연스러움 / 더 나은 표현 으로 평가
   ============================================================ */
async function evaluateWriting({ expression, meaning, sentence, kind = "expression" }) {
  const term = kind === "word" ? "word" : "expression";
  const prompt = `An English learner (Korean, software developer) is practicing the ${term} "${expression}" (meaning: ${meaning}).
They wrote this sentence:
"""${sentence}"""

Evaluate it. Be encouraging but honest. Return ONLY JSON:
{
  "usedExpression": <true if they actually used the target ${term}>,
  "grammar": "<1-2 sentences in Korean about grammatical correctness; name the issue if any>",
  "grammarOk": <true|false>,
  "naturalness": "<1-2 sentences in Korean: does it sound natural to a native speaker?>",
  "score": <integer 0-100 overall>,
  "suggestion": "<one improved, natural English rewrite that uses the ${term} well>",
  "suggestionWhy": "<short Korean note on what the rewrite improves>"
}`;
  const r = await askJSON(prompt);
  return {
    usedExpression: r.usedExpression !== false,
    grammar: (r.grammar || "").trim(),
    grammarOk: !!r.grammarOk,
    naturalness: (r.naturalness || "").trim(),
    score: Math.max(0, Math.min(100, Number(r.score) || 0)),
    suggestion: (r.suggestion || "").trim(),
    suggestionWhy: (r.suggestionWhy || "").trim(),
  };
}

/* ============================================================
   4. 주제별 요약 (정리 뷰)
   모은 표현들을 주제별로 묶고 한 줄 코멘트
   ============================================================ */
async function summarizeByTopic(expressions) {
  const compact = expressions.map((e) => ({ expression: e.expression, meaning: e.meaning }));
  const prompt = `Here are English expressions a learner has collected. Group them into 3-5 themes.
Return ONLY JSON:
{ "groups": [ { "theme": "<Korean theme name>", "items": ["<expression>", ...], "note": "<1 Korean sentence about this theme>" } ] }

Expressions: ${JSON.stringify(compact)}`;
  const r = await askJSON(prompt);
  return (r.groups || []).map((g) => ({
    theme: (g.theme || "").trim(),
    items: g.items || [],
    note: (g.note || "").trim(),
  }));
}

/* ============================================================
   Offline / preview fallback — so the prototype is usable
   even when window.claude is unavailable. Clearly marked.
   ============================================================ */
function mock(prompt) {
  const wait = (v) => new Promise((res) => setTimeout(() => res(v), 650));
  if (prompt.includes('"groups"')) {
    return wait({ groups: [
      { theme: "업무·협업", items: ["get the ball rolling", "on the same page", "circle back"], note: "회의와 팀 커뮤니케이션에서 자주 쓰는 표현들이에요." },
      { theme: "학습·기술", items: ["a steep learning curve"], note: "새로운 기술을 익히는 상황을 설명할 때 유용해요." },
      { theme: "정중한 요청", items: ["I'd appreciate it if you could..."], note: "이메일에서 격식 있게 부탁할 때 쓰는 표현이에요." },
    ]});
  }
  if (prompt.includes('"usedExpression"')) {
    return wait({
      usedExpression: true, grammar: "문법적으로 큰 문제는 없어요. 시제도 자연스럽습니다.", grammarOk: true,
      naturalness: "전반적으로 자연스럽지만, 조금 더 구어체로 다듬으면 좋아요.", score: 82,
      suggestion: "(미리보기) 실제 환경에서는 AI가 더 자연스러운 문장을 제안합니다.",
      suggestionWhy: "프리뷰 모드라 예시 응답이에요.",
    });
  }
  if (prompt.includes('"sentence"')) {
    return wait({ sentence: "(미리보기) Let's get the ball rolling on the new feature.", gloss: "(미리보기) 새 기능 작업을 시작하자." });
  }
  return wait({
    meaning: "(미리보기) 자동 채움은 실제 환경에서 동작합니다.",
    examples: ["(preview) Example sentence one.", "(preview) Example sentence two.", "(preview) Example sentence three."],
    situation: "프리뷰 모드입니다. 실제 환경에서는 AI가 상황과 뉘앙스를 채워줘요.",
    formality: "neutral", tags: ["미리보기"],
  });
}

window.AI = { enrichExpression, freshExample, evaluateWriting, summarizeByTopic, HAS_LLM };
