// chat-mockup.jsx — Animated WhatsApp-style chat (DE / ES bilingual via window.t)

const { useState, useEffect, useRef } = React;

// Script with translation keys. Actual strings live in i18n.jsx.
const CHAT_SCRIPT = [
  { kind: "day", textKey: "chat.day" },
  { kind: "in", textKey: "chat.1", at: 400 },
  { kind: "typing", at: 2200, dur: 1100 },
  { kind: "system", textKey: "chat.2", at: 3500, property: true },
  { kind: "system", textKey: "chat.3", at: 6000 },
  { kind: "in", textKey: "chat.4", at: 9500 },
  { kind: "typing", at: 12000, dur: 1100 },
  { kind: "system", textKey: "chat.5", at: 13300 },
  { kind: "in", textKey: "chat.6", at: 18000 },
  { kind: "typing", at: 19500, dur: 1100 },
  { kind: "system", textKey: "chat.7", at: 20800 },
  { kind: "in", textKey: "chat.8", at: 27000 },
  { kind: "typing", at: 28200, dur: 900 },
  { kind: "system", textKey: "chat.9", at: 29300 },
  { kind: "in", textKey: "chat.10", at: 32500 },
  { kind: "typing", at: 33700, dur: 1100 },
  { kind: "system", textKey: "chat.11", at: 35000 },
  { kind: "in", textKey: "chat.12", at: 40000 },
  { kind: "in", attachment: true, at: 41500 },
  { kind: "typing", at: 42800, dur: 1000 },
  { kind: "system", textKey: "chat.13", at: 44000 },
  { kind: "in", textKey: "chat.14", at: 49000 },
  { kind: "typing", at: 50000, dur: 900 },
  { kind: "system", textKey: "chat.15", at: 51000 },
  { kind: "system", textKey: "chat.16", at: 52800, map: true },
  { kind: "system", textKey: "chat.17", at: 56500 },
  { kind: "in", textKey: "chat.18", at: 60000 },
];

const TOTAL_MS = 63000;

function ChatMockup({ playing, onTick, speed = 0.7 }) {
  const lang = window.useLang ? window.useLang().lang : "de";
  const t = window.t || ((k) => k);
  const [time, setTime] = useState(0);
  const rafRef = useRef(0);
  const startRef = useRef(0);
  const offsetRef = useRef(0);

  useEffect(() => {
    if (!playing) {
      cancelAnimationFrame(rafRef.current);
      offsetRef.current = time;
      return;
    }
    startRef.current = performance.now();
    const tick = (now) => {
      const elapsed = offsetRef.current + (now - startRef.current) * speed;
      if (elapsed >= TOTAL_MS) {
        offsetRef.current = -1200;
        startRef.current = performance.now();
        setTime(0);
      } else {
        setTime(Math.max(0, elapsed));
      }
      onTick && onTick(Math.max(0, elapsed) / TOTAL_MS);
      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, [playing, speed]);

  const visible = [];
  for (const item of CHAT_SCRIPT) {
    if (item.kind === "day") {
      visible.push(item);
      continue;
    }
    if (item.at <= time) {
      if (item.kind === "typing") {
        if (time < item.at + item.dur) visible.push(item);
      } else {
        visible.push(item);
      }
    }
  }

  const bodyRef = useRef(null);
  useEffect(() => {
    if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
  }, [visible.length, lang]);

  const fmt = (mins, idx) => {
    const base = 14 * 60 + 32;
    const ti = base + idx;
    const h = Math.floor(ti / 60) % 24;
    const m = ti % 60;
    return `${String(h).padStart(2,"0")}:${String(m).padStart(2,"0")}`;
  };

  return (
    <div className="phone">
      <div className="phone-notch"></div>
      <div className="phone-screen">
        <div className="wa-status">
          <span>9:41</span>
          <span className="right">
            <span>●●●●</span>
            <span style={{marginLeft: 4}}>5G</span>
            <span style={{marginLeft: 4, display:"inline-block", width: 18, height: 9, border:"1px solid #fff", borderRadius:2, position:"relative"}}>
              <i style={{position:"absolute", inset: 1, background:"#fff", borderRadius: 1, width: "70%"}}></i>
            </span>
          </span>
        </div>
        <div className="wa-bar">
          <span className="back">‹</span>
          <span className="ava">IH</span>
          <span className="who">
            <b>{t("chat.contact.name")}</b>
            <small>{t("chat.contact.status")}</small>
          </span>
          <span className="ico">
            <Icon name="video" size={18} stroke={2} />
            <Icon name="phone" size={16} stroke={2} />
          </span>
        </div>
        <div className="wa-body" ref={bodyRef}>
          {visible.map((item, i) => {
            if (item.kind === "day") return <div key={i} className="wa-day">{t(item.textKey)}</div>;
            if (item.kind === "typing") return (
              <div key={i} className="typing"><i className="d"></i><i className="d"></i><i className="d"></i></div>
            );
            const txt = item.textKey ? t(item.textKey) : "";
            const lines = txt.split("\n");
            return (
              <div key={i} className={"bubble " + item.kind}>
                {lines.map((line, j) => (
                  <span key={j}>{renderBubbleLine(line)}{j < lines.length - 1 && <br/>}</span>
                ))}
                {item.property && <PropertyCard title={t("chat.prop.title")} sub={t("chat.prop.sub")} />}
                {item.attachment && <PdfAttachment name={t("chat.attach.name")} size={t("chat.attach.size.short") + " · PDF"} />}
                {item.map && (
                  <MapPreview
                    address={t("chat.address")}
                    url={"https://maps.google.com/?q=" + encodeURIComponent(t("chat.address"))}
                    openLabel={t("chat.map.open")}
                  />
                )}
                <span className="time">
                  {fmt(0, i)}
                  {item.kind !== "in" && <span className="tick">✓✓</span>}
                </span>
              </div>
            );
          })}
        </div>
        <div className="wa-input">
          <div className="field">{t("chat.input.placeholder")}</div>
          <div className="send"><Icon name="arrow-right" size={16} stroke={2.4} /></div>
        </div>
      </div>
    </div>
  );
}

ChatMockup.TOTAL_MS = TOTAL_MS;
window.ChatMockup = ChatMockup;

function renderBubbleLine(line) {
  const re = /([\w.+-]+@[\w-]+\.[\w.-]+)/g;
  const parts = [];
  let last = 0; let m;
  while ((m = re.exec(line)) !== null) {
    if (m.index > last) parts.push(line.slice(last, m.index));
    parts.push(
      <a key={"e" + m.index} href={"mailto:" + m[1]} className="bub-mail"
         onClick={(e) => e.stopPropagation()}
         target="_blank" rel="noopener noreferrer">{m[1]}</a>
    );
    last = m.index + m[1].length;
  }
  if (last < line.length) parts.push(line.slice(last));
  return parts.length ? parts : line;
}

function PropertyCard({ title, sub }) {
  return (
    <div className="prop-prev">
      <div className="prop-thumb" aria-hidden="true">
        <svg viewBox="0 0 240 130" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
          <defs>
            <linearGradient id="propSky" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor="#d8e3ee"/>
              <stop offset="100%" stopColor="#f0eee6"/>
            </linearGradient>
          </defs>
          <rect width="240" height="130" fill="url(#propSky)"/>
          <ellipse cx="30" cy="86" rx="22" ry="20" fill="#9bb98c" opacity=".75"/>
          <rect x="60" y="62" width="130" height="58" fill="#e6dfd1"/>
          <polygon points="50,62 125,28 200,62" fill="#6b4536"/>
          <rect x="115" y="88" width="20" height="32" fill="#3a2418"/>
          <rect x="75" y="75" width="22" height="18" fill="#9cb6c7" stroke="#fff" strokeWidth="1.5"/>
          <rect x="153" y="75" width="22" height="18" fill="#9cb6c7" stroke="#fff" strokeWidth="1.5"/>
          <rect x="85" y="100" width="18" height="14" fill="#9cb6c7" stroke="#fff" strokeWidth="1"/>
          <rect x="147" y="100" width="18" height="14" fill="#9cb6c7" stroke="#fff" strokeWidth="1"/>
          <rect y="120" width="240" height="10" fill="#c9c4b6"/>
        </svg>
      </div>
      <div className="prop-info">
        <b>{title}</b>
        <small>{sub}</small>
      </div>
    </div>
  );
}

function PdfAttachment({ name, size }) {
  return (
    <div className="pdf-att">
      <div className="pdf-ic" aria-hidden="true">
        <svg width="22" height="26" viewBox="0 0 22 26" xmlns="http://www.w3.org/2000/svg">
          <path d="M2 2h11l7 7v15a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2z" fill="#e94c3d"/>
          <path d="M13 2l7 7h-7V2z" fill="#c0382b"/>
          <text x="11" y="20" textAnchor="middle" fontFamily="Arial" fontSize="7" fontWeight="700" fill="#fff">PDF</text>
        </svg>
      </div>
      <div className="pdf-meta">
        <b>{name}</b>
        <small>{size}</small>
      </div>
    </div>
  );
}

function MapPreview({ address, url, openLabel }) {
  return (
    <a className="map-prev" href={url} target="_blank" rel="noopener noreferrer">
      <div className="map-thumb" aria-hidden="true">
        <svg viewBox="0 0 240 120" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
          <defs>
            <linearGradient id="mapBg" x1="0" y1="0" x2="1" y2="1">
              <stop offset="0%" stopColor="#e8efe4"/>
              <stop offset="100%" stopColor="#d6e4d2"/>
            </linearGradient>
            <pattern id="streets" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse">
              <path d="M0 20 L40 20" stroke="#c2cfbf" strokeWidth="6" opacity=".5"/>
              <path d="M20 0 L20 40" stroke="#c2cfbf" strokeWidth="6" opacity=".5"/>
            </pattern>
          </defs>
          <rect width="240" height="120" fill="url(#mapBg)"/>
          <rect width="240" height="120" fill="url(#streets)"/>
          <path d="M0 70 L240 60" stroke="#fff" strokeWidth="6" opacity=".9"/>
          <path d="M90 0 L100 120" stroke="#fff" strokeWidth="5" opacity=".9"/>
          <path d="M160 0 L150 120" stroke="#fff" strokeWidth="3" opacity=".7"/>
          <circle cx="200" cy="95" r="22" fill="#b6cfa7" opacity=".7"/>
          <path d="M0 100 Q40 95 80 105 T160 110 L240 115 L240 120 L0 120 Z" fill="#a8c5d8" opacity=".7"/>
          <g transform="translate(112,40)">
            <ellipse cx="8" cy="36" rx="6" ry="2" fill="rgba(0,0,0,.18)"/>
            <path d="M8 0 C13 0 16 4 16 9 C16 16 8 28 8 28 C8 28 0 16 0 9 C0 4 3 0 8 0 Z" fill="#009660"/>
            <circle cx="8" cy="9" r="3.2" fill="#fff"/>
          </g>
        </svg>
      </div>
      <div className="map-info">
        <span className="map-ic">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M12 22s-7-7.5-7-13a7 7 0 1 1 14 0c0 5.5-7 13-7 13z"/>
            <circle cx="12" cy="9" r="2.5"/>
          </svg>
        </span>
        <div className="map-text">
          <b>{address}</b>
          <small>{openLabel}</small>
        </div>
      </div>
    </a>
  );
}
