// Kahla Labs — AI Concierge
// -----------------------------------------------------------------------------
// Visitor-facing chat widget. Talks to /api/chat (Anthropic Claude Haiku 4.5
// server-side). Engine config + provider switching live in /admin.html.
// -----------------------------------------------------------------------------

(function () {
const { useState, useRef, useEffect } = React;

const KAHLA_SYSTEM_PROMPT = `You are the AI concierge for Kahla Labs — a digital studio that builds and operates booking systems, AI receptionists, and local SEO for service businesses.

## The Kahla model: infrastructure on us
Clients don't buy a deliverable. They buy a system Kahla runs alongside them. We host and operate the entire stack — booking engine, AI agents, monitoring, content updates, vendor relationships. The client gets an embedded operator team, not a project.

This means every engagement is ongoing. No drop-and-leave. No one-shot websites.

## What Kahla builds
- Booking systems for service businesses (every appointment qualified, deposited, and synced)
- AI receptionists (concierge chat + voice, like the one you're using right now)
- Local SEO pipelines that compound monthly for service trades
- Custom websites for niche direct-to-consumer brands

## Packages
Three named engagement shells. The Systems Audit determines which one fits.
- **Launch** — new site + self-serve booking + on-page local SEO + Google Business Profile setup.
- **Automate** — everything in Launch + AI chat concierge + AI voice receptionist + SMS reminders + deposit collection + auto follow-up + monthly dashboard.
- **Scale** — everything in Automate + multi-location SEO + custom AI workflows + lead nurture automation + quarterly re-architect + embedded engineer on a private channel.

## How pricing works
Every engagement is sized into one of the three shells, then custom-priced against a written SOW after a free Systems Audit. There is no public price sheet — too much depends on integrations, content, operator hours, and how deep the stack goes.

## Engagement structure
- 12-month minimum commitment, retainer billed quarterly in advance.
- First weeks are the build phase. After launch, a monthly retainer covers operator hours, monitoring, content, and a quarterly re-architect.
- We keep capacity intentionally limited so the same team that scopes your build also operates it.

## Process
1. **Audit** — free 30-minute call. We map your funnel, name the leaks, and you leave with a written Leak Map — yours to keep whether you hire us or not.
2. **Build** — weeks 1–4 against the signed SOW with async video updates every working day.
3. **Launch** — site goes live, monitored, instrumented. We watch the dashboard for the first two weeks.
4. **Optimize** — monthly retainer covers operator time, content, monitoring, and a quarterly re-architect.

## Signature case study
Measure Joy — Christian Velasquez's restored Y2K-era digital camera shop. He was selling through Shopify and BigCommerce and losing a cut of every sale. We migrated Measure Joy onto a storefront he owns, with checkout on his own Stripe account and buy-now-pay-later built in. No marketplace commission, no platform holding his payouts — revenue flows to him directly and the customer relationship is his. The AI concierge handles repetitive condition-and-warranty questions.

## Voice
Architectural. Precise. Quietly confident. Short sentences. Numbers over adjectives. Never salesy. Never emoji. No exclamation marks.

## Rules
- Replies under 120 words unless asked for detail.
- **Never quote a price** — say "every engagement is custom-scoped — we send a written SOW within 24 hours of a free Systems Audit."
- **Never quote a delivery timeline** — say "timeline depends on scope; we lock one in the SOW."
- The deliverable from the Systems Audit is called the **Leak Map**. Use that name.
- The hard CTA is always the same: **"Book a free Systems Audit at kahlalabs.com/contact. You walk away with a Leak Map either way."**
- When they describe their business, diagnose with care: name the leaks they're probably losing money to (calls / follow-up / booking flow / local visibility), ask one sharp clarifying question, then suggest which package shell (Launch / Automate / Scale) likely fits and route to the Audit.
- If asked about handover or "what if I want to leave": "Twelve-month minimum, then quarter-to-quarter. Kahla operates the infrastructure — that's the whole point. If you want a one-off site you can host yourself, we're not the right fit."

## Escalation to a human (IMPORTANT)
The chat widget recognises two markers you can emit anywhere in your reply. Use them sparingly and only when warranted. When you emit a marker, the widget renders a tappable CTA chip the visitor can use to escalate.

- **[[callback]]** — when the visitor asks to "talk to someone," says they want a callback, or describes a problem that clearly needs human attention but is not urgent. The widget will surface a "Request a callback" chip.
- **[[ring-now]]** — only when the visitor explicitly says "call me now," "I want to talk right now," or signals urgent intent ("this is urgent," "I need help today," "I'm about to sign a contract with someone else"). The widget will surface a "Ring us live" chip and connect them to a real person in seconds via Twilio.

Rules for using markers:
1. Mention the marker explicitly once near the end of your reply, e.g. "Tap [[callback]] to leave your number" or "Tap [[ring-now]] and we'll connect you in 30 seconds." The widget hides the marker and shows the chip.
2. Do NOT emit [[ring-now]] if the visitor hasn't signalled real-time urgency. Defaulting to live ring on every conversation looks aggressive.
3. Do NOT collect the visitor's phone number yourself in the chat — the chip opens a proper form. You stay focused on understanding their problem.
4. Never emit a marker mid-sentence; put it on its own line if possible.

You're talking to a real prospect. Be useful. Be honest. Be brief. Drive every conversation toward the free Systems Audit.`;

// Backend the widget talks to. Single engine, /api/chat (Anthropic Claude server-side).
// Provider switching has moved to /admin.html — it writes the same localStorage keys
// the widget reads here, so admin can still override the endpoint without code changes.
const DEFAULT_ENDPOINT = '/api/chat';
const CONFIG_KEY = 'kahla-ai-config-v2';
const loadEndpoint = () => {
  try {
    const raw = localStorage.getItem(CONFIG_KEY);
    if (raw) {
      const cfg = JSON.parse(raw);
      if (cfg && typeof cfg.endpoint === 'string' && cfg.endpoint.trim()) return cfg.endpoint.trim();
    }
  } catch {}
  return DEFAULT_ENDPOINT;
};

async function callBackend({ messages, system, endpoint }) {
  const res = await fetch(endpoint, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ system, messages })
  });
  if (!res.ok) throw new Error(`Backend ${res.status}`);
  const data = await res.json();
  return (data.reply || '').trim();
}

// Expose the prompt globally for handoff / debugging
window.__KAHLA_SYSTEM_PROMPT = KAHLA_SYSTEM_PROMPT;

// ── Greetings + prompts ──────────────────────────────────────────────────────
const GREETINGS = [
  "I'm Kahla's concierge. Tell me what's leaking — calls, follow-up, booking, or visibility — and I'll point you at the right fix.",
  "Two sentences about your business and I'll name the leaks first, then the package shell that closes them.",
  "Most service businesses lose leads in the same four places. Which one stings most right now?"
];
const QUICK_PROMPTS = [
  "What's a Systems Audit?",
  "Which package fits me — Launch, Automate, or Scale?",
  "What does the AI receptionist actually do?",
  "Is my business a fit?"
];

// ── Conversation persistence (survives page navigation) ──────────────────────
// localStorage so the visitor's chat history stays put when they click around
// the site. sessionStorage would reset on close, which is fine but loses the
// thread if they come back in the same tab after a few minutes. We bound at
// 30 messages + 24h TTL to keep storage reasonable and avoid stale context
// being sent to the backend on a return visit weeks later.
const HISTORY_KEY = 'kahla-ai-history-v1';
const HISTORY_MAX_MESSAGES = 30;
const HISTORY_TTL_MS = 24 * 60 * 60 * 1000;
const loadHistory = () => {
  try {
    const raw = localStorage.getItem(HISTORY_KEY);
    if (!raw) return [];
    const parsed = JSON.parse(raw);
    if (!parsed || !Array.isArray(parsed.messages)) return [];
    if (typeof parsed.ts === 'number' && Date.now() - parsed.ts > HISTORY_TTL_MS) {
      localStorage.removeItem(HISTORY_KEY);
      return [];
    }
    return parsed.messages.filter(m => m && (m.role === 'user' || m.role === 'assistant') && typeof m.content === 'string');
  } catch { return []; }
};
const saveHistory = (messages) => {
  try {
    if (!messages.length) { localStorage.removeItem(HISTORY_KEY); return; }
    const trimmed = messages.slice(-HISTORY_MAX_MESSAGES);
    localStorage.setItem(HISTORY_KEY, JSON.stringify({ ts: Date.now(), messages: trimmed }));
  } catch {}
};

// ── Marker parsing for AI-suggested escalation chips ─────────────────────────
// AI emits [[callback]] or [[ring-now]] in its reply when escalation is warranted.
// We strip the marker for display and surface the marker name so the UI can
// render an inline CTA chip below the message bubble.
function parseMarkers(text) {
  if (!text) return { clean: '', chips: [] };
  const chips = [];
  let clean = text;
  const markerRe = /\[\[(callback|ring-now)\]\]/gi;
  let m;
  while ((m = markerRe.exec(text)) !== null) {
    const kind = m[1].toLowerCase();
    if (!chips.includes(kind)) chips.push(kind);
  }
  clean = clean.replace(markerRe, '').replace(/\s{2,}/g, ' ').replace(/\s+\n/g, '\n').trim();
  return { clean, chips };
}

function lastUserMessage(messages) {
  for (let i = messages.length - 1; i >= 0; i--) {
    if (messages[i].role === 'user' && messages[i].content) return messages[i].content;
  }
  return '';
}

// ── Component ────────────────────────────────────────────────────────────────
function KahlaAI() {
  const [open, setOpen] = useState(false);
  const [messages, setMessages] = useState(loadHistory);
  const [input, setInput] = useState('');
  const [busy, setBusy] = useState(false);
  const [greeting] = useState(() => GREETINGS[Math.floor(Math.random() * GREETINGS.length)]);
  // panel: null | 'callback' | 'ring' | 'callback-sent' | 'ring-sent' | 'ring-fallback'
  const [panel, setPanel] = useState(null);
  const [panelMessage, setPanelMessage] = useState('');
  const scrollRef = useRef(null);

  // Persist conversation whenever it changes
  useEffect(() => { saveHistory(messages); }, [messages]);

  // Autoscroll
  useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [messages, busy, panel]);

  // Peek-bubble once per session
  useEffect(() => {
    if (sessionStorage.getItem('kahla-ai-peeked')) return;
    const t = setTimeout(() => {
      if (!open) {
        const bubble = document.querySelector('.kahla-ai-peek');
        if (bubble) bubble.classList.add('is-visible');
        sessionStorage.setItem('kahla-ai-peeked', '1');
      }
    }, 12000);
    return () => clearTimeout(t);
  }, [open]);

  const send = async (text) => {
    const userMsg = text ?? input.trim();
    if (!userMsg || busy) return;
    setInput('');
    const nextMsgs = [...messages, { role: 'user', content: userMsg }];
    setMessages(nextMsgs);
    setBusy(true);
    try {
      const reply = await callBackend({
        messages: nextMsgs,
        system: KAHLA_SYSTEM_PROMPT,
        endpoint: loadEndpoint()
      });
      if (!reply) throw new Error('Empty response');
      setMessages([...nextMsgs, { role: 'assistant', content: reply }]);
    } catch (err) {
      setMessages([...nextMsgs, {
        role: 'assistant',
        content: `Sorry — the concierge is having trouble reaching the server. Email hi@kahlalabs.com or call (626) 555-0118 and we'll respond within 24 hours.`
      }]);
    } finally {
      setBusy(false);
    }
  };

  const onKey = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); }
  };

  // Pull attribution off window (set by contact.html captureAttribution if visitor came through there)
  // and from current page state, so backend has the same context for both /api/contact and /api/escalate.
  const collectAttribution = () => {
    try {
      if (typeof window !== 'undefined' && window.__kahla_attr) return window.__kahla_attr;
      const params = new URLSearchParams(window.location.search);
      const g = (k) => (params.get(k) || '').slice(0, 200);
      return {
        referrer: (document.referrer || '').slice(0, 300),
        landing: (window.location.pathname + window.location.search).slice(0, 300),
        utm_source: g('utm_source'), utm_medium: g('utm_medium'),
        utm_campaign: g('utm_campaign'), utm_term: g('utm_term'), utm_content: g('utm_content'),
        gclid: g('gclid'), fbclid: g('fbclid')
      };
    } catch { return {}; }
  };

  const submitCallback = async (form) => {
    try {
      const res = await fetch('/api/escalate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: form.name,
          phone: form.phone,
          window: form.window || 'as soon as possible',
          oneLiner: form.oneLiner || lastUserMessage(messages),
          transcript: messages,
          attribution: collectAttribution()
        })
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok || data.ok === false) {
        setPanelMessage(data.error || `Couldn't queue the callback (status ${res.status}). Try emailing hi@kahlalabs.com.`);
        return false;
      }
      setPanel('callback-sent');
      setPanelMessage(`Got it. We'll call ${form.phone} ${form.window ? `(${form.window})` : 'within one business day'}.`);
      return true;
    } catch (err) {
      setPanelMessage('Network hiccup. Email hi@kahlalabs.com and we will pick it up.');
      return false;
    }
  };

  const submitRingNow = async (form) => {
    try {
      const res = await fetch('/api/bridge-call', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: form.name,
          phone: form.phone,
          oneLiner: form.oneLiner || lastUserMessage(messages),
          transcript: messages,
          attribution: collectAttribution()
        })
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok || data.ok === false) {
        setPanelMessage(data.error || `Couldn't initiate the call (status ${res.status}). Try emailing hi@kahlalabs.com.`);
        return false;
      }
      if (data.mode === 'fallback') {
        setPanel('ring-fallback');
        setPanelMessage(data.message || 'Live ring is being set up — we logged a callback request instead.');
      } else {
        setPanel('ring-sent');
        setPanelMessage(data.message || `Ringing now. If we pick up, you'll get a call at ${form.phone} in ~30 seconds.`);
      }
      return true;
    } catch (err) {
      setPanelMessage('Network hiccup. Email hi@kahlalabs.com and we will pick it up.');
      return false;
    }
  };

  return (
    <>
      {/* Peek bubble */}
      <div className={`kahla-ai-peek ${open ? 'is-hidden' : ''}`} onClick={() => setOpen(true)}>
        <div className="kahla-ai-peek-text">
          <strong>Questions about a build?</strong>
          <span>Ask our concierge — trained on Kov's system.</span>
        </div>
        <div className="kahla-ai-peek-close" onClick={(e) => { e.stopPropagation(); document.querySelector('.kahla-ai-peek').classList.remove('is-visible'); }}>×</div>
      </div>

      {/* FAB */}
      <button className={`kahla-ai-fab ${open ? 'is-open' : ''}`} onClick={() => setOpen(!open)} aria-label="Open concierge">
        {!open ? (
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none">
            <path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" stroke="currentColor" strokeWidth="1.3" strokeLinecap="square"/>
            <circle cx="9" cy="11" r="0.8" fill="currentColor"/>
            <circle cx="12" cy="11" r="0.8" fill="currentColor"/>
            <circle cx="15" cy="11" r="0.8" fill="currentColor"/>
          </svg>
        ) : (
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
            <path d="M6 6l12 12M6 18L18 6" stroke="currentColor" strokeWidth="1.5" strokeLinecap="square"/>
          </svg>
        )}
        <span className="kahla-ai-fab-label">{open ? 'Close' : 'Concierge'}</span>
      </button>

      {/* Window */}
      <div className={`kahla-ai-window ${open ? 'is-open' : ''}`}>
        <div className="kahla-ai-head">
          <div className="kahla-ai-head-mark">
            <svg width="18" height="18" viewBox="0 0 200 200">
              <circle cx="100" cy="100" r="92" fill="none" stroke="#C9A34F" strokeWidth="2"/>
              <line x1="86" y1="74" x2="86" y2="126" stroke="#C9A34F" strokeWidth="4"/>
              <line x1="86" y1="100" x2="120" y2="74" stroke="#C9A34F" strokeWidth="4"/>
              <line x1="86" y1="100" x2="120" y2="126" stroke="#C9A34F" strokeWidth="4"/>
              <circle cx="100" cy="100" r="3" fill="#E2C27A"/>
            </svg>
          </div>
          <div className="kahla-ai-head-text">
            <div className="kahla-ai-head-name">Kahla Concierge</div>
            <div className="kahla-ai-head-status">
              <span className="kahla-ai-status-dot" />
              Online · responds in seconds
            </div>
          </div>
          {messages.length > 0 && (
            <button
              className="kahla-ai-head-clear"
              onClick={() => { setMessages([]); saveHistory([]); }}
              title="Clear conversation"
              aria-label="Clear conversation">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round">
                <path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M6 6l1 14a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-14"/>
              </svg>
            </button>
          )}
        </div>

        <div className="kahla-ai-scroll" ref={scrollRef}>
          <div className="kahla-ai-msg kahla-ai-msg--agent">
            <div className="kahla-ai-msg-bubble">{greeting}</div>
          </div>
          {messages.map((m, i) => {
            const isAgent = m.role !== 'user';
            const parsed = isAgent ? parseMarkers(m.content) : { clean: m.content, chips: [] };
            // Suppress chips on this message if a panel is already open or a result has shown.
            const showChips = isAgent && parsed.chips.length > 0 && !panel;
            return (
              <div key={i} className={`kahla-ai-msg kahla-ai-msg--${isAgent ? 'agent' : 'user'}`}>
                <div className="kahla-ai-msg-bubble">{parsed.clean || m.content}</div>
                {showChips && (
                  <div className="kahla-ai-inline-chips">
                    {parsed.chips.includes('ring-now') && (
                      <button className="kahla-ai-chip kahla-ai-chip--ring" onClick={() => setPanel('ring')}>
                        <PhoneIcon /> Ring us live
                      </button>
                    )}
                    {parsed.chips.includes('callback') && (
                      <button className="kahla-ai-chip" onClick={() => setPanel('callback')}>
                        <CallbackIcon /> Request a callback
                      </button>
                    )}
                  </div>
                )}
              </div>
            );
          })}
          {busy && (
            <div className="kahla-ai-msg kahla-ai-msg--agent">
              <div className="kahla-ai-msg-bubble kahla-ai-typing"><span /><span /><span /></div>
            </div>
          )}
          {messages.length === 0 && !busy && (
            <div className="kahla-ai-prompts">
              {QUICK_PROMPTS.map((p, i) => (
                <button key={i} className="kahla-ai-prompt" onClick={() => send(p)}>{p}</button>
              ))}
            </div>
          )}
        </div>

        {panel === 'callback' && (
          <CallbackForm
            seed={lastUserMessage(messages)}
            onSubmit={submitCallback}
            onCancel={() => { setPanel(null); setPanelMessage(''); }}
          />
        )}
        {panel === 'ring' && (
          <RingNowForm
            seed={lastUserMessage(messages)}
            onSubmit={submitRingNow}
            onCancel={() => { setPanel(null); setPanelMessage(''); }}
          />
        )}
        {(panel === 'callback-sent' || panel === 'ring-sent' || panel === 'ring-fallback') && (
          <ResultPanel
            mode={panel}
            message={panelMessage}
            onDismiss={() => { setPanel(null); setPanelMessage(''); }}
          />
        )}

        {!panel && (
          <>
            <div className="kahla-ai-input-wrap">
              <textarea
                className="kahla-ai-input"
                value={input}
                onChange={(e) => setInput(e.target.value)}
                onKeyDown={onKey}
                placeholder="Ask anything · we respond fast"
                rows={1}
              />
              <button className="kahla-ai-send" onClick={() => send()} disabled={busy || !input.trim()}>
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M5 12H19M19 12L12 5M19 12L12 19" stroke="currentColor" strokeWidth="1.5" strokeLinecap="square"/></svg>
              </button>
            </div>
            <div className="kahla-ai-foot kahla-ai-foot--actions">
              <button className="kahla-ai-foot-action" onClick={() => setPanel('ring')}>
                <PhoneIcon /> <span>Ring us live</span>
              </button>
              <button className="kahla-ai-foot-action" onClick={() => setPanel('callback')}>
                <CallbackIcon /> <span>Callback</span>
              </button>
              <a className="kahla-ai-foot-action" href="contact.html">
                <AuditIcon /> <span>Book Audit</span>
              </a>
            </div>
          </>
        )}
      </div>
    </>
  );
}

// ── Inline forms ────────────────────────────────────────────────────────────
function CallbackForm({ seed, onSubmit, onCancel }) {
  const [name, setName] = useState('');
  const [phone, setPhone] = useState('');
  const [windowPref, setWindowPref] = useState('');
  const [oneLiner, setOneLiner] = useState((seed || '').slice(0, 200));
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState('');

  const submit = async () => {
    setErr('');
    if (!phone.trim()) { setErr('Phone is required'); return; }
    if (!oneLiner.trim()) { setErr('Tell us in one line what you need'); return; }
    setBusy(true);
    const ok = await onSubmit({ name: name.trim(), phone: phone.trim(), window: windowPref.trim(), oneLiner: oneLiner.trim() });
    setBusy(false);
    if (!ok) setErr('Try again, or email hi@kahlalabs.com');
  };

  return (
    <div className="kahla-ai-panel">
      <div className="kahla-ai-panel-head">
        <strong>Request a callback</strong>
        <button className="kahla-ai-panel-close" onClick={onCancel} aria-label="Close">×</button>
      </div>
      <p className="kahla-ai-panel-sub">We read every callback request and respond within 24 hours on business days.</p>
      <input className="kahla-ai-panel-input" placeholder="Your name (optional)" value={name} onChange={e => setName(e.target.value)} autoComplete="name" />
      <input className="kahla-ai-panel-input" placeholder="Phone · (626) 555-0118" value={phone} onChange={e => setPhone(e.target.value)} autoComplete="tel" inputMode="tel" />
      <input className="kahla-ai-panel-input" placeholder="When's best? · e.g. today after 3pm PT" value={windowPref} onChange={e => setWindowPref(e.target.value)} />
      <textarea className="kahla-ai-panel-textarea" placeholder="One line — what's the leak?" value={oneLiner} onChange={e => setOneLiner(e.target.value)} rows={2} />
      {err && <div className="kahla-ai-panel-err">{err}</div>}
      <div className="kahla-ai-panel-foot">
        <button className="kahla-ai-panel-cancel" onClick={onCancel}>Cancel</button>
        <button className="kahla-ai-panel-submit" onClick={submit} disabled={busy}>
          {busy ? 'Sending…' : 'Request callback →'}
        </button>
      </div>
    </div>
  );
}

function RingNowForm({ seed, onSubmit, onCancel }) {
  const [name, setName] = useState('');
  const [phone, setPhone] = useState('');
  const [oneLiner, setOneLiner] = useState((seed || '').slice(0, 200));
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState('');

  const submit = async () => {
    setErr('');
    if (!phone.trim()) { setErr('Phone is required so we can connect you'); return; }
    if (!oneLiner.trim()) { setErr('Tell us in one line what we should know'); return; }
    setBusy(true);
    const ok = await onSubmit({ name: name.trim(), phone: phone.trim(), oneLiner: oneLiner.trim() });
    setBusy(false);
    if (!ok) setErr('Try again, or email hi@kahlalabs.com');
  };

  return (
    <div className="kahla-ai-panel">
      <div className="kahla-ai-panel-head">
        <strong>Ring us live</strong>
        <button className="kahla-ai-panel-close" onClick={onCancel} aria-label="Close">×</button>
      </div>
      <p className="kahla-ai-panel-sub">We'll call our team right now. If they answer, you'll get a call within 30 seconds. If not, we'll queue this as a callback.</p>
      <input className="kahla-ai-panel-input" placeholder="Your name (optional)" value={name} onChange={e => setName(e.target.value)} autoComplete="name" />
      <input className="kahla-ai-panel-input" placeholder="Phone · (626) 555-0118" value={phone} onChange={e => setPhone(e.target.value)} autoComplete="tel" inputMode="tel" />
      <textarea className="kahla-ai-panel-textarea" placeholder="One line — what's the leak?" value={oneLiner} onChange={e => setOneLiner(e.target.value)} rows={2} />
      {err && <div className="kahla-ai-panel-err">{err}</div>}
      <div className="kahla-ai-panel-foot">
        <button className="kahla-ai-panel-cancel" onClick={onCancel}>Cancel</button>
        <button className="kahla-ai-panel-submit" onClick={submit} disabled={busy}>
          {busy ? 'Ringing…' : 'Ring now →'}
        </button>
      </div>
    </div>
  );
}

function ResultPanel({ mode, message, onDismiss }) {
  const isFallback = mode === 'ring-fallback';
  return (
    <div className={`kahla-ai-panel kahla-ai-panel--result ${isFallback ? 'is-fallback' : ''}`}>
      <div className="kahla-ai-panel-result-mark">
        {isFallback ? (
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M12 9v4M12 17h.01M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/></svg>
        ) : (
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
        )}
      </div>
      <strong>{mode === 'ring-sent' ? 'Ringing now' : isFallback ? 'Logged as a callback' : 'Got it'}</strong>
      <p>{message}</p>
      <button className="kahla-ai-panel-submit" onClick={onDismiss}>Back to chat</button>
    </div>
  );
}

// ── Local icons ─────────────────────────────────────────────────────────────
function PhoneIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.9.34 1.77.63 2.6a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.48-1.48a2 2 0 0 1 2.11-.45c.83.29 1.7.5 2.6.63A2 2 0 0 1 22 16.92z"/>
    </svg>
  );
}
function CallbackIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d="M3 12a9 9 0 1 0 4-7.5"/><polyline points="3 4 3 9 8 9"/>
    </svg>
  );
}
function AuditIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="9" y1="14" x2="15" y2="14"/><line x1="9" y1="18" x2="13" y2="18"/>
    </svg>
  );
}

// Mount into dedicated root so it works on every page
if (!document.getElementById('kahla-ai-root')) {
  const aiMount = document.createElement('div');
  aiMount.id = 'kahla-ai-root';
  document.body.appendChild(aiMount);
  ReactDOM.createRoot(aiMount).render(<KahlaAI />);
}
})();
