const { useState, useEffect, useRef, useMemo } = React;

const EXAMPLE_RANT = `你每次都這樣，講過幾百次了你都當耳邊風。\n禮拜三明明說好要陪我去看我媽，你竟然又跑去加班，加班加班加班，你心裡到底有沒有我？\n上次也是，紀念日那天你還在跟同事打那個破遊戲到半夜兩點，我自己一個人吃便當吃到哭。\n我跟你說的事情你聽過幾次？我說我最近壓力大、我說我膝蓋不舒服、我說想搬家，你回我什麼？「喔。」「嗯。」「再說。」\n我真的不知道我們在一起的意義是什麼，是不是分開比較輕鬆，反正我講什麼你都覺得我在鬧。\n你連我今天穿什麼顏色的衣服都不記得，更不要說我心情怎麼樣。\n我是不是要去找別人才會被看見？`;

// fallback (used if Claude API unavailable)
const FALLBACK = {
  weather: "雷陣雨",
  core_emotion: "其實我很害怕被丟下，也覺得我的付出沒被看見。",
  core_desire: "渴望一個沒有手機、放下加班、單純把注意力放在我身上的半小時。",
  action_invitation: "今晚一起喝杯熱可可，不聊嚴肅話題，只是並肩坐著。"
};

const SAMPLE_ID = "x7k2qr";

// ---------- screens ----------

function Sender({ onTransform, onJumpToShare }) {
  const [text, setText] = useState("");
  const [shake, setShake] = useState(false);
  const taRef = useRef(null);

  const fillExample = () => {
    setText("");
    setShake(true);
    setTimeout(() => setShake(false), 420);
    // typewriter
    let i = 0;
    const tick = () => {
      i += 6;
      setText(EXAMPLE_RANT.slice(0, i));
      if (i < EXAMPLE_RANT.length) setTimeout(tick, 12);
    };
    tick();
  };

  const canSend = text.trim().length > 8;

  return (
    <>
      <span className="label">step 01 — 發送方 / sender</span>
      <h1 className="title">把氣話丟進來，<br/>它會幫你翻譯成擁抱。</h1>
      <p className="subtitle">EmoTree 是一棵會吸收情緒的樹。你寫多兇都沒關係——它只會把核心需求遞給對方。</p>

      <div className="scene">
        <div className="sun" />
        <div className="cloud c1" />
        <div className="cloud c2" />
        {Array.from({length: 14}).map((_, i) => (
          <div key={i} className="rain" style={{
            left: `${(i*23 + 4) % 96}%`,
            top: `-${20 + (i%5)*8}px`,
            animationDelay: `${(i % 6) * 0.16}s`
          }} />
        ))}
        <div className="ground" />
        <div className="tree-wrap">
          <EmoTree intensity={Math.min(1, text.length / 220)} />
        </div>
      </div>

      <div className={"ta-wrap " + (shake ? "shake" : "")}>
        <textarea
          ref={taRef}
          value={text}
          onChange={(e) => setText(e.target.value)}
          placeholder="把你現在想對伴侶說的氣話、千字小論文直接丟進來。別怕，這裡 100% 匿名且安全。"
        />
        <div className="ta-example">
          <button className="pbtn small ghost" onClick={fillExample}>⚡ 3秒看範例</button>
        </div>
        <div className="ta-meta">{text.length} 字 · 匿名加密</div>
      </div>

      <div style={{display:"flex", gap:10, marginTop:18}}>
        <button
          className="pbtn primary"
          style={{flex:1, fontSize:16, padding:"14px 16px"}}
          disabled={!canSend}
          onClick={() => onTransform(text)}
        >
          🌱 轉化為破冰密碼
        </button>
      </div>

      <div className="foot">↓ 寫越多，樹越亮 · 它只給對方看翻譯後的版本</div>
    </>
  );
}

function Loading({ rawText, onDone }) {
  const [progress, setProgress] = useState(0);
  const [flying, setFlying] = useState([]);
  const [stage, setStage] = useState("傾聽中…");

  useEffect(() => {
    // pull a few words from the text and fly them up
    const tokens = rawText
      .split(/[\s，。！？、,.\n]+/)
      .filter(w => w.length >= 2 && w.length <= 6)
      .slice(0, 14);
    let i = 0;
    const id = setInterval(() => {
      if (i >= tokens.length) { clearInterval(id); return; }
      const w = tokens[i];
      const dx = (Math.random() - 0.5) * 160;
      const dy = -160 - Math.random() * 30;
      setFlying(arr => [...arr, { id: Date.now() + i, w, dx, dy, x: 20 + Math.random()*300 }]);
      i++;
    }, 180);
    return () => clearInterval(id);
  }, [rawText]);

  useEffect(() => {
    const stages = [
      [0,    "傾聽中…"],
      [25,   "過濾攻擊性字眼…"],
      [50,   "拆解底層情緒…"],
      [75,   "翻譯為非暴力語言…"],
      [95,   "封裝成破冰密碼…"]
    ];
    let p = 0;
    const id = setInterval(() => {
      p += 3 + Math.random()*4;
      if (p >= 100) { p = 100; clearInterval(id); setTimeout(onDone, 600); }
      setProgress(p);
      for (const [t,label] of stages) if (p >= t) setStage(label);
    }, 180);
    return () => clearInterval(id);
  }, [onDone]);

  return (
    <>
      <span className="label">step 02 — 翻譯中 / decoding</span>
      <h1 className="title">EmoTree 正在<br/>消化你的小論文…</h1>
      <p className="subtitle">攻擊性字眼正在被根部過濾，只剩下你真正想說的那一句。</p>

      <div className="scene" style={{background:"linear-gradient(180deg,#3d4f6b 0%,#5a6e8c 60%,#a7895a 100%)"}}>
        {Array.from({length: 22}).map((_, i) => (
          <div key={i} className="rain" style={{
            left: `${(i*19 + 4) % 96}%`,
            top: `-${20 + (i%5)*8}px`,
            animationDelay: `${(i % 6) * 0.13}s`,
            background: "#86a5c2"
          }} />
        ))}
        <div className="ground" />
        <div className="tree-wrap">
          <EmoTree intensity={Math.min(1, 0.3 + progress/120)} />
        </div>
        <div className="glow-ring" style={{opacity: 0.4 + progress/200}} />
        {flying.map(f => (
          <span key={f.id} className="word-fly" style={{
            left: f.x, bottom: 30,
            "--dx": `${f.dx}px`, "--dy": `${f.dy}px`
          }}>
            {f.w}
          </span>
        ))}
      </div>

      <div className="panel">
        <div style={{display:"flex", justifyContent:"space-between", marginBottom:8, fontFamily:'"DotGothic16",monospace', fontSize:13}}>
          <span>{stage}</span>
          <span>{Math.floor(progress)}%</span>
        </div>
        <div className="loading-bar"><div style={{width: `${progress}%`}}/></div>
        <div className="mono" style={{marginTop:10, fontSize:14, color:"var(--ink-soft)"}}>
          &gt; model: gpt-4o · pipeline: nvc-decoder.v1
        </div>
      </div>
    </>
  );
}

function Share({ id, decoded, onPreview, onBack }) {
  const [copied, setCopied] = useState(false);
  const url = `emotree.app/card/${id}`;

  return (
    <>
      <span className="label">step 03 — 已生成 / ready</span>
      <h1 className="title">你的破冰密碼<br/>已經包好了。</h1>
      <p className="subtitle">把這個連結傳給 ta。對方只會看到 EmoTree 的翻譯版本，看不到你寫的原文。</p>

      <div className="scene" style={{height: 180, background:"linear-gradient(180deg,#fce5b8,#f3c98a)"}}>
        <div className="sun" />
        <div className="ground" />
        <div className="tree-wrap">
          <EmoTree intensity={0.95} />
        </div>
        <div className="glow-ring" style={{opacity: 0.9, bottom: 60}} />
      </div>

      <div className="panel" style={{marginBottom:14}}>
        <div style={{display:"flex", alignItems:"center", justifyContent:"space-between"}}>
          <span style={{fontFamily:'"DotGothic16",monospace', fontSize:13}}>🔗 對方專屬連結</span>
          <span className="mono" style={{fontSize:13, color:"var(--ink-soft)"}}>24h 後自動凋謝</span>
        </div>
        <div className="url-box">
          <div className="url">https://{url}</div>
          <button className="copy" onClick={() => {
            navigator.clipboard?.writeText(`https://${url}`).catch(()=>{});
            setCopied(true);
            setTimeout(() => setCopied(false), 1600);
          }}>{copied ? "已複製" : "複製"}</button>
        </div>
        <div className="share-row">
          <button className="pbtn small">📱 LINE</button>
          <button className="pbtn small">💬 訊息</button>
          <button className="pbtn small">🔗 分享</button>
        </div>
      </div>

      <div className="panel" style={{background:"var(--bg-1)"}}>
        <div style={{fontFamily:'"DotGothic16",monospace', fontSize:12, color:"var(--orange-deep)", marginBottom:8}}>
          ▸ 預覽：對方會看到的卡片
        </div>
        <div style={{fontSize:14, lineHeight:1.6, color:"var(--ink)"}}>
          天氣：<b>{decoded.weather}</b><br/>
          核心情緒：<i>{decoded.core_emotion}</i>
        </div>
        <button className="pbtn primary" style={{marginTop:12, width:"100%"}} onClick={onPreview}>
          👀 預覽伴侶會看到的畫面
        </button>
      </div>

      <div style={{display:"flex", gap:10, marginTop:14}}>
        <button className="pbtn" style={{flex:1}} onClick={onBack}>← 重寫</button>
      </div>
    </>
  );
}

function Receiver({ decoded, onReply, replied }) {
  return (
    <>
      <span className="label">step 04 — 接收方 / partner</span>
      <h1 className="title">你的另一半<br/>寄了一張氣象卡 ☂︎</h1>
      <p className="subtitle">不是抱怨、也不是長篇大論。只是一份ta真正想說的話。</p>

      <div className="wcard">
        <div className="header">
          <span>EMOTREE · 關係氣象預報</span>
          <span className="stamp">DECODED</span>
        </div>
        <div className="weather-vis">
          <WeatherVis kind={decoded.weather} />
          <div className="weather-icon-box"><WeatherIcon kind={decoded.weather} /></div>
          <div className="weather-label">今日天氣：{decoded.weather}</div>
        </div>
        <div className="body">
          <div className="field">
            <div className="ftitle">底層真實情緒</div>
            <div className="ftext big">「{decoded.core_emotion}」</div>
          </div>
          <div className="field">
            <div className="ftitle">內在核心渴望</div>
            <div className="ftext">{decoded.core_desire}</div>
          </div>
          <div className="field" style={{marginBottom:6}}>
            <div className="ftitle">ta 的低壓力邀請</div>
            <div className="ftext">{decoded.action_invitation}</div>
          </div>
        </div>
        <div className="replies">
          <ReplyButton
            ico="☔"
            label="那我幫你撐把傘"
            sub="I'll be your umbrella tonight"
            sent={replied === "umbrella"}
            onClick={() => onReply("umbrella")}
          />
          <ReplyButton
            ico="☕"
            label="今晚一起喝杯熱可可"
            sub="hot cocoa, no phones"
            sent={replied === "cocoa"}
            onClick={() => onReply("cocoa")}
          />
          <ReplyButton
            ico="💬"
            label="我知道了，我們文字聊聊"
            sub="let's text it through, slowly"
            sent={replied === "text"}
            onClick={() => onReply("text")}
          />
        </div>
      </div>

      <div className="foot">EmoTree 不保留原文 · 只傳遞被翻譯後的需求</div>
    </>
  );
}

function ReplyButton({ ico, label, sub, sent, onClick }) {
  return (
    <button className={"reply-btn " + (sent ? "sent" : "")} onClick={onClick} disabled={sent}>
      <span className="ico">{ico}</span>
      <span>
        <div className="lbl">{sent ? "✓ 已送出 · 對方會看到" : label}</div>
        <div className="sub">{sub}</div>
      </span>
    </button>
  );
}

function NotificationView({ replyKey, onAgain }) {
  const msg = {
    umbrella: { ico:"☔", line:"你的伴侶說「我幫你撐把傘」。", sub:"冰山開始融化了。" },
    cocoa:    { ico:"☕", line:"你的伴侶送了一杯熱可可給你。", sub:"今晚 8 點，廚房見。" },
    text:     { ico:"💬", line:"你的伴侶想跟你慢慢文字聊聊。", sub:"不急，慢慢來就好。" }
  }[replyKey] || { ico:"💛", line:"你的伴侶看到了。", sub:"" };

  return (
    <>
      <span className="label">step 05 — 即時通知 / sender receives</span>
      <h1 className="title">{msg.line}</h1>
      <p className="subtitle">{msg.sub}</p>

      <div className="scene" style={{background:"linear-gradient(180deg,#ffd9a5,#ffc078)"}}>
        <div className="sun" />
        <div className="ground" />
        <div className="tree-wrap">
          <EmoTree intensity={1} />
        </div>
        <div className="glow-ring" style={{opacity: 1, bottom: 60}} />
        {/* fruit dropping celebration */}
        {Array.from({length: 6}).map((_, i) => (
          <div key={i} style={{
            position:"absolute",
            width:8, height:8,
            background: i%2 ? "#e8a93b" : "#d96a3d",
            border:"2px solid #3a2615",
            left: `${20 + i*12}%`,
            top: `-10px`,
            animation: `rain 2.4s ease-in ${i*0.3}s infinite`
          }} />
        ))}
      </div>

      <div className="panel" style={{background:"var(--leaf-glow)", borderColor:"var(--leaf-deep)"}}>
        <div style={{display:"flex", alignItems:"center", gap:14}}>
          <div style={{width:46, height:46, background:"var(--cream)", border:"2.5px solid var(--ink)", display:"grid", placeItems:"center", fontSize:24}}>
            {msg.ico}
          </div>
          <div>
            <div style={{fontFamily:'"DotGothic16",monospace', fontSize:12, color:"var(--leaf-deep)"}}>EMOTREE · 對方剛剛回應你</div>
            <div style={{fontSize:15, fontWeight:700, marginTop:2}}>{msg.line}</div>
          </div>
        </div>
        <div style={{marginTop:14, fontSize:13, lineHeight:1.55, color:"var(--ink)"}}>
          樹苗結了一顆果實 🍊。你們已經連續用 EmoTree 化解 <b>3 次</b> 衝突，根系正在變深。
        </div>
      </div>

      <div style={{display:"grid", gridTemplateColumns:"1fr 1fr", gap:10, marginTop:14}}>
        <button className="pbtn">🌳 看我們的樹林</button>
        <button className="pbtn primary" onClick={onAgain}>📝 再寫一張</button>
      </div>

      <div className="foot">R1 — 你們的關係氣象台已建立 7 天</div>
    </>
  );
}

// ---------- main app ----------

function App() {
  // screen: sender | loading | share | receiver | notify
  const [screen, setScreen] = useState("sender");
  const [rawText, setRawText] = useState("");
  const [decoded, setDecoded] = useState(FALLBACK);
  const [replied, setReplied] = useState(null);
  const [toast, setToast] = useState(null);
  const [aiStatus, setAiStatus] = useState("idle"); // idle | ok | fallback

  // kick off transform
  const handleTransform = async (text) => {
    setRawText(text);
    setScreen("loading");
    setAiStatus("idle");
    try {
      const sys = `你是關係非暴力溝通專家。用戶會輸入一段充滿憤怒、指責、翻舊帳的伴侶吵架小論文。你的任務是將其過濾、解構，並嚴格輸出 JSON，絕對不能夾帶任何原始的攻擊性字眼。\n\n只輸出 JSON，不要加任何 markdown 標記或前後綴。結構：\n{\n  "weather": string,        // 情緒天氣，如 "雷陣雨"、"寒流暴風雪"、"陰天微雨"\n  "core_emotion": string,   // 底層真實情緒，第一人稱，溫和\n  "core_desire": string,    // 內在核心渴望，具體、軟性\n  "action_invitation": string // 具體且低壓力的邀請\n}`;
      const reply = await window.claude.complete({
        messages: [
          { role: "user", content: `${sys}\n\n用戶原文：\n${text}\n\n請輸出 JSON：` }
        ]
      });
      // try parse
      let parsed = null;
      const m = reply.match(/\{[\s\S]*\}/);
      if (m) { try { parsed = JSON.parse(m[0]); } catch(_) {} }
      if (parsed && parsed.weather && parsed.core_emotion) {
        setDecoded(parsed);
        setAiStatus("ok");
      } else {
        setAiStatus("fallback");
      }
    } catch (e) {
      setAiStatus("fallback");
    }
  };

  const handleLoaderDone = () => setScreen("share");

  const handleReply = (key) => {
    setReplied(key);
    // simulate webhook → sender notification
    setTimeout(() => {
      setToast({ key, ts: Date.now() });
      setTimeout(() => {
        setScreen("notify");
        setToast(null);
      }, 1800);
    }, 700);
  };

  const reset = () => {
    setScreen("sender");
    setRawText("");
    setReplied(null);
    setDecoded(FALLBACK);
  };

  // breadcrumb display
  const bc = {
    sender:   ["用戶端", "/"],
    loading:  ["AI 工作站", "/decoding"],
    share:    ["用戶端", "/card/" + SAMPLE_ID],
    receiver: ["伴侶端", "/card/" + SAMPLE_ID],
    notify:   ["用戶端", "/notify"]
  }[screen];

  return (
    <div className="app">
      <div className="topbar">
        <div className="brand">
          <div className="brand-dot"/>
          <span className="pixel">EmoTree</span>
        </div>
        <div className="pill pixel">{bc[1]}</div>
      </div>
      <div className="breadcrumb">
        ◤ <b>{bc[0]}</b> · 把吵架翻譯成擁抱
        {aiStatus === "ok" && screen !== "sender" && <span style={{marginLeft:8}}>· ✓ gpt-4o</span>}
        {aiStatus === "fallback" && screen !== "sender" && <span style={{marginLeft:8}}>· demo data</span>}
      </div>

      {screen === "sender"   && <Sender onTransform={handleTransform} />}
      {screen === "loading"  && <Loading rawText={rawText || EXAMPLE_RANT} onDone={handleLoaderDone} />}
      {screen === "share"    && <Share id={SAMPLE_ID} decoded={decoded} onPreview={() => setScreen("receiver")} onBack={reset} />}
      {screen === "receiver" && <Receiver decoded={decoded} onReply={handleReply} replied={replied} />}
      {screen === "notify"   && <NotificationView replyKey={replied} onAgain={reset} />}

      {toast && (
        <div className="toast-wrap">
          <div className="toast">
            <div className="ico-tile">{ {umbrella:"☔",cocoa:"☕",text:"💬"}[toast.key] }</div>
            <div style={{flex:1}}>
              <div className="ttl">即時通知 · 你的伴侶剛剛回應了</div>
              <div className="msg">{
                {umbrella:"那我幫你撐把傘 ☔",
                 cocoa:"今晚一起喝杯熱可可 ☕",
                 text:"我知道了，我們文字聊聊 💬"}[toast.key]
              }</div>
            </div>
          </div>
        </div>
      )}

      <DemoNav screen={screen} setScreen={(s) => {
        if (s === "loading") { setRawText(EXAMPLE_RANT); handleTransform(EXAMPLE_RANT); return; }
        if (s === "sender") { reset(); return; }
        setScreen(s);
      }} />
    </div>
  );
}

function DemoNav({ screen, setScreen }) {
  const items = [
    ["sender",   "1·發送"],
    ["loading",  "2·翻譯"],
    ["share",    "3·分享"],
    ["receiver", "4·接收"],
    ["notify",   "5·通知"]
  ];
  return (
    <div className="demo-nav">
      <div className="title">▸ DEMO 流程跳轉</div>
      <div className="row">
        {items.map(([k,l]) => (
          <button key={k} className={screen===k ? "active" : ""} onClick={() => setScreen(k)}>{l}</button>
        ))}
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
