/* Gridea site — assistent (kangelasosa küsimuskast + vestlusaken) */

const { useState: useStateCh, useEffect: useEffectCh, useRef: useRefCh } = React;

/* Chips do double duty: they seed the conversation AND they tell a visitor at a
   glance that this answers grid-rule questions, not just product questions. */
const CHAT_CHIPS = [
  'Mis on kasutusvõimsus?',
  'Miks Elektrilevi trahvib tippude eest?',
  'Kas Gridea sobib 12 mõõtepunktiga vallale?',
  'Mis vahe on VMA2 ja VMA5 tariifil?',
];

const CHAT_INTRO =
  'Küsi elektrivõrgu, tariifide või Gridea kohta — vastan eesti keeles.';

/* Hero ask-box. Owns no conversation state: it fires an event the panel picks up,
   so the hero and the floating launcher drive the same single chat. */
function HeroAsk() {
  const [text, setText] = useStateCh('');
  const ask = (q) => {
    const v = (q ?? text).trim();
    if (!v) return;
    window.dispatchEvent(new CustomEvent('gridea:ask', { detail: v }));
    setText('');
  };
  return (
    <div className="hero-ask" id="hero-ask">
      <form
        className="hero-ask-form"
        onSubmit={(e) => { e.preventDefault(); ask(); }}
      >
        <GIcon name="sparkles" size={17}/>
        <input
          type="text"
          value={text}
          onChange={(e) => setText(e.target.value)}
          placeholder="Küsi elektrivõrgu või tariifide kohta…"
          aria-label="Küsi Gridea assistendilt"
        />
        <button type="submit" aria-label="Küsi">
          <GIcon name="arrow-right" size={15}/>
        </button>
      </form>
      <div className="hero-ask-chips">
        {CHAT_CHIPS.map((c) => (
          <button key={c} type="button" onClick={() => ask(c)}>{c}</button>
        ))}
      </div>
    </div>
  );
}

function ChatWidget() {
  const [open, setOpen] = useStateCh(false);
  const [msgs, setMsgs] = useStateCh([]);      // {role, content}
  const [busy, setBusy] = useStateCh(false);
  const [err, setErr] = useStateCh('');
  const [text, setText] = useStateCh('');
  const [showLauncher, setShowLauncher] = useStateCh(true);
  const [honey, setHoney] = useStateCh('');
  const bodyRef = useRefCh(null);
  const inputRef = useRefCh(null);
  const msgsRef = useRefCh([]);
  msgsRef.current = msgs;

  const MAX_TURNS = 12;
  const atLimit = msgs.length >= MAX_TURNS;

  /* Hide the launcher while the hero ask-box is on screen — two entry points
     competing for attention in the same viewport reads as clutter. */
  useEffectCh(() => {
    const el = document.getElementById('hero-ask');
    if (!el || typeof IntersectionObserver === 'undefined') { setShowLauncher(true); return; }
    const io = new IntersectionObserver(
      ([entry]) => setShowLauncher(!entry.isIntersecting),
      { threshold: 0.25 }
    );
    io.observe(el);
    return () => io.disconnect();
  });

  useEffectCh(() => {
    if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
  }, [msgs, busy]);

  useEffectCh(() => {
    const onAsk = (e) => { setOpen(true); send(e.detail); };
    window.addEventListener('gridea:ask', onAsk);
    return () => window.removeEventListener('gridea:ask', onAsk);
  });

  useEffectCh(() => {
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  async function send(raw) {
    const q = (raw ?? '').trim();
    if (!q || busy) return;
    setErr('');
    setText('');

    const history = [...msgsRef.current, { role: 'user', content: q }];
    setMsgs(history);
    setBusy(true);

    try {
      const res = await fetch('/api/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ messages: history, website: honey }),
      });

      if (!res.ok) {
        const d = await res.json().catch(() => ({}));
        setErr(d.message || 'Midagi läks valesti. Proovi uuesti või kirjuta support@gridea.io.');
        return;
      }

      /* Append an empty assistant message, then grow it as bytes arrive. */
      setMsgs((m) => [...m, { role: 'assistant', content: '' }]);
      const reader = res.body.getReader();
      const dec = new TextDecoder();
      let acc = '';
      for (;;) {
        const { done, value } = await reader.read();
        if (done) break;
        acc += dec.decode(value, { stream: true });
        setMsgs((m) => {
          const next = m.slice();
          next[next.length - 1] = { role: 'assistant', content: acc };
          return next;
        });
      }
      if (!acc.trim()) {
        setErr('Vastust ei tulnud. Proovi uuesti või kirjuta support@gridea.io.');
        setMsgs((m) => m.slice(0, -1));
      }
    } catch (_) {
      setErr('Ühendus katkes. Kontrolli internetiühendust või kirjuta support@gridea.io.');
    } finally {
      setBusy(false);
      if (inputRef.current) inputRef.current.focus();
    }
  }

  return (
    <>
      {showLauncher && !open && (
        <button className="chat-launcher" onClick={() => setOpen(true)} aria-label="Ava Gridea assistent">
          <GIcon name="sparkles" size={18}/>
          <span>Küsi</span>
        </button>
      )}

      <div className={`chat-panel ${open ? 'open' : ''}`} hidden={!open} role="dialog" aria-label="Gridea assistent">
        <div className="chat-head">
          <div>
            <strong>Gridea assistent</strong>
            <span>Vastab elektrivõrgu ja platvormi kohta</span>
          </div>
          <button onClick={() => setOpen(false)} aria-label="Sulge">
            <GIcon name="plus" size={18} className="chat-x"/>
          </button>
        </div>

        <div className="chat-body" ref={bodyRef}>
          {msgs.length === 0 && (
            <>
              <div className="chat-intro">{CHAT_INTRO}</div>
              <div className="chat-chips">
                {CHAT_CHIPS.map((c) => (
                  <button key={c} type="button" onClick={() => send(c)}>{c}</button>
                ))}
              </div>
            </>
          )}
          {msgs.map((m, i) => (
            <div key={i} className={`chat-msg ${m.role}`}>
              {m.content || (busy && i === msgs.length - 1 ? '…' : '')}
            </div>
          ))}
          {busy && msgs[msgs.length - 1]?.role === 'user' && (
            <div className="chat-msg assistant chat-typing">…</div>
          )}
          {err && <div className="chat-err" role="alert">{err}</div>}
        </div>

        <form
          className="chat-input"
          onSubmit={(e) => { e.preventDefault(); send(text); }}
        >
          {/* Honeypot — offscreen, never filled by a person. */}
          <label className="chat-hp" aria-hidden="true">
            Veebileht
            <input type="text" tabIndex={-1} autoComplete="off" value={honey} onChange={(e) => setHoney(e.target.value)}/>
          </label>
          <input
            ref={inputRef}
            type="text"
            value={text}
            onChange={(e) => setText(e.target.value)}
            placeholder={atLimit ? 'Vestlus on täis — alusta uut' : 'Kirjuta küsimus…'}
            disabled={busy || atLimit}
            aria-label="Sinu küsimus"
          />
          <button type="submit" disabled={busy || atLimit || !text.trim()} aria-label="Saada">
            <GIcon name="send" size={16}/>
          </button>
        </form>

        <div className="chat-foot">
          Assistendi vastused on informatiivsed, mitte finants- ega õigusnõu.
          Kehtivad hinnad ja tingimused kontrolli võrguettevõtjalt.
        </div>
      </div>
    </>
  );
}

window.HeroAsk = HeroAsk;
window.ChatWidget = ChatWidget;
