// Animated ChatGPT-style hotel booking mockup.
// Types out a conversation, then renders a hotel card and a confirmation.

const { useState: cgUseState, useEffect: cgUseEffect, useRef: cgUseRef } = React;

const CHAT_COPY = {
  es: {
    userMsg: 'búscame un hotel boutique tranquilo en lisboa para el próximo jueves, dos noches',
    aiMsg: 'Unos cuantos que encajan. Casa Fortunato es un hotel pequeño, una casa señorial en Graça, calle tranquila y a pie desde Alfama. Dos noches, habitación doble con desayuno.',
    followUp: 'resérvalo',
    aiFollow: 'Reservado. Confirmación enviada a tu correo.',
    bookedBadge: 'Reservado vía Listo',
    cardEyebrow: 'GRAÇA · LISBOA',
    cardName: 'Casa Fortunato',
    cardDates: 'Jue 7 may → Sáb 9 may',
    cardGuests: '1 habitación, 2 huéspedes',
    cardPriceSub: '/total',
    cardRate: 'Desayuno incluido · Cancelación gratuita',
    cardCta: 'Reservar →',
    confirmTitle: 'Reserva confirmada',
    confirmMeta: 'REF: LST-2810-9F · Casa Fortunato · 7 may 2026',
    composer: 'Mensaje…',
    sendLabel: 'Enviar',
  },
  en: {
    userMsg: 'Find me a quiet boutique hotel in lisbon for next thursday, two nights',
    aiMsg: 'A few that fit. Casa Fortunato is a small hotel, a manor house in Graça, on a quiet street and walking distance from Alfama. Two nights, double room with breakfast.',
    followUp: 'book it',
    aiFollow: 'Booked. Confirmation sent to your email.',
    bookedBadge: 'Booked via Listo',
    cardEyebrow: 'GRAÇA · LISBON',
    cardName: 'Casa Fortunato',
    cardDates: 'Thu May 7 → Sat May 9',
    cardGuests: '1 room, 2 guests',
    cardPriceSub: '/total',
    cardRate: 'Breakfast included · Free cancellation',
    cardCta: 'Book →',
    confirmTitle: 'Booking confirmed',
    confirmMeta: 'REF: LST-2810-9F · Casa Fortunato · May 7, 2026',
    composer: 'Message…',
    sendLabel: 'Send',
  },
};

function ChatBookingMock() {
  const lang = (typeof window !== 'undefined' && window.detectLang) ? window.detectLang() : 'es';
  const t = CHAT_COPY[lang];

  const [stage, setStage] = cgUseState(0);
  const [userText, setUserText] = cgUseState('');
  const [aiText, setAiText] = cgUseState('');
  const [showCard, setShowCard] = cgUseState(false);
  const [showFollowUp, setShowFollowUp] = cgUseState(false);
  const [followUpText, setFollowUpText] = cgUseState('');
  const [aiFollowUpText, setAiFollowUpText] = cgUseState('');
  const [showConfirm, setShowConfirm] = cgUseState(false);
  const startedRef = cgUseRef(false);
  const rootRef = cgUseRef(null);
  const bodyRef = cgUseRef(null);

  // Fixed-height frame: keep the conversation pinned to the bottom as it streams in,
  // so the widget never grows and the hero layout stays put.
  cgUseEffect(() => {
    if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
  });

  cgUseEffect(() => {
    if (!rootRef.current) return;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting && !startedRef.current) {
            startedRef.current = true;
            setStage(1);
          }
        });
      },
      { threshold: 0.35 }
    );
    io.observe(rootRef.current);
    return () => io.disconnect();
  }, []);

  cgUseEffect(() => {
    if (stage === 0) return;

    const timeouts = [];
    const at = (ms, fn) => timeouts.push(setTimeout(fn, ms));

    if (stage === 1) {
      let i = 0;
      const tick = () => {
        if (i <= t.userMsg.length) {
          setUserText(t.userMsg.slice(0, i));
          i++;
          timeouts.push(setTimeout(tick, 28 + Math.random() * 28));
        } else {
          at(450, () => setStage(2));
        }
      };
      tick();
    } else if (stage === 2) {
      at(900, () => {
        let i = 0;
        const tick = () => {
          if (i <= t.aiMsg.length) {
            setAiText(t.aiMsg.slice(0, i));
            i++;
            timeouts.push(setTimeout(tick, 12 + Math.random() * 14));
          } else {
            at(400, () => setShowCard(true));
            at(1200, () => setStage(3));
          }
        };
        tick();
      });
    } else if (stage === 3) {
      at(800, () => setShowFollowUp(true));
      at(900, () => {
        let i = 0;
        const tick = () => {
          if (i <= t.followUp.length) {
            setFollowUpText(t.followUp.slice(0, i));
            i++;
            timeouts.push(setTimeout(tick, 50));
          } else {
            at(400, () => setStage(4));
          }
        };
        tick();
      });
    } else if (stage === 4) {
      at(700, () => {
        let i = 0;
        const tick = () => {
          if (i <= t.aiFollow.length) {
            setAiFollowUpText(t.aiFollow.slice(0, i));
            i++;
            timeouts.push(setTimeout(tick, 16 + Math.random() * 14));
          } else {
            // v2: play once on entry and rest on the completed conversation.
            // (The v1 build looped the demo continuously; the new design system
            // avoids continuously-looping motion.)
            at(400, () => setShowConfirm(true));
          }
        };
        tick();
      });
    }

    return () => timeouts.forEach(clearTimeout);
  }, [stage, t]);

  return (
    <div ref={rootRef} className="chat-mock" style={{ position: 'relative' }}>
      <div className="chat-mock-frame">
        <div className="chat-mock-titlebar">
          <div className="chat-mock-dots">
            <span /><span /><span />
          </div>
          <div className="chat-mock-url">
            <span>chatgpt.com</span>
          </div>
          <div style={{ width: 60 }} />
        </div>

        <div className="chat-mock-body" ref={bodyRef}>
          {stage >= 1 && (
            <div className="chat-row chat-row-user">
              <div className="chat-bubble chat-bubble-user">
                {userText}
                {stage === 1 && <span className="caret" />}
              </div>
            </div>
          )}

          {stage >= 2 && (
            <div className="chat-row chat-row-ai">
              <div className="chat-avatar">L</div>
              <div style={{ flex: 1 }}>
                {aiText.length === 0 ? (
                  <div className="chat-typing">
                    <span /><span /><span />
                  </div>
                ) : (
                  <div className="chat-text">
                    {aiText}
                    {stage === 2 && aiText.length < t.aiMsg.length && <span className="caret" />}
                  </div>
                )}

                {showCard && (
                  <div className="hotel-card reveal in">
                    <div className="hotel-card-img">
                      <img className="hotel-card-img-photo" src="/assets/photos/Listo_hotel_image_6.png" alt="Boutique hotel room recommended by the AI assistant" loading="lazy" />
                      <div className="hotel-card-badge">
                        <span className="hotel-card-badge-mark">★</span>
                        <span>{t.bookedBadge}</span>
                      </div>
                    </div>
                    <div className="hotel-card-body">
                      <div className="hotel-card-eyebrow">{t.cardEyebrow}</div>
                      <div className="hotel-card-name">{t.cardName}</div>
                      <div className="hotel-card-meta">
                        <span>{t.cardDates}</span>
                        <span className="dot">·</span>
                        <span>{t.cardGuests}</span>
                      </div>
                      <div className="hotel-card-foot">
                        <div>
                          <div className="hotel-card-price">412 €<span className="hotel-card-pricesub">{t.cardPriceSub}</span></div>
                          <div className="hotel-card-rate">{t.cardRate}</div>
                        </div>
                        <div className="hotel-card-cta">{t.cardCta}</div>
                      </div>
                    </div>
                  </div>
                )}
              </div>
            </div>
          )}

          {showFollowUp && (
            <div className="chat-row chat-row-user">
              <div className="chat-bubble chat-bubble-user">
                {followUpText}
                {stage === 3 && <span className="caret" />}
              </div>
            </div>
          )}

          {stage >= 4 && (
            <div className="chat-row chat-row-ai">
              <div className="chat-avatar">L</div>
              <div style={{ flex: 1 }}>
                <div className="chat-text">
                  {aiFollowUpText}
                  {stage === 4 && aiFollowUpText.length < t.aiFollow.length && <span className="caret" />}
                </div>
                {showConfirm && (
                  <div className="confirm-card reveal in">
                    <div className="confirm-tick">
                      <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="2">
                        <path d="M20 6L9 17l-5-5" />
                      </svg>
                    </div>
                    <div>
                      <div className="confirm-title">{t.confirmTitle}</div>
                      <div className="confirm-meta">{t.confirmMeta}</div>
                    </div>
                  </div>
                )}
              </div>
            </div>
          )}
        </div>

        <div className="chat-composer">
          <div className="chat-composer-input">
            <span style={{ color: 'var(--ink-mute)' }}>{t.composer}</span>
          </div>
          <button className="chat-composer-send" aria-label={t.sendLabel}>
            <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2">
              <path d="M5 12l14-7-7 14-2-5-5-2z" />
            </svg>
          </button>
        </div>
      </div>
    </div>
  );
}

window.ChatBookingMock = ChatBookingMock;
