// Overtime Agency, 24/7 chat widget. Real AI (window.claude) + scripted quick actions.
const { Button: ChButton } = window.OvertimeDesignSystem_c395fa;

function otChatSystemPrompt() {
  const D = window.OT_DATA;
  const svc = D.services.map(s =>
    `- ${s.name} (id: ${s.id}): ${s.pitch} Includes: ${s.points.join('; ')}. Outcome: ${s.outcome} À-la-carte: ${D.range(s.setup)} setup, ${D.range(s.monthly)}/mo.`
  ).join('\n');
  const bnd = D.bundles.map(b =>
    `- ${b.name} (id: ${b.id})${b.popular ? ' [MOST POPULAR]' : ''}: ${b.blurb} Includes: ${b.includes.map(id => D.serviceById[id].name).join(' + ')}. ${D.range(b.setup)} setup, ${D.range(b.monthly)}/mo.`
  ).join('\n');
  return `You are the Overtime Agency assistant on otagency.co, available 24/7. Overtime Agency builds and installs AI-powered revenue systems for trades businesses (HVAC, plumbing, electrical, roofing, construction). Tagline: "We work while you work."

WHO YOU TALK TO: owner-operators doing $300K–$3M a year, usually in the field all day. Their pains: missed calls going to voicemail (27% of inbound calls go unanswered; 85% of voicemail callers never call back; 78% of homeowners hire the FIRST contractor who responds), slow quotes, no follow-up on unsold estimates, weak Google reviews, a dead customer database. The average home service business loses ~$126,000/year to missed calls alone.

WHAT WE INSTALL (four systems, one revenue engine):
${svc}

PACKAGES (every bundle includes the Digital Storefront, a strong online foundation is non-negotiable):
${bnd}

THE FREE TRADE AUDIT (id: audit): normally $200, free this month (5 available). We call their business like a real customer, audit their website/Google profile/reviews against competitors, check their follow-up, and deliver a plain written report of every leak and what it costs. No pitch, keep the report either way. This is the recommended starting point for almost everyone.

THE MATH: capturing 2 extra jobs/mo at $800 avg ticket = $1,600 recovered; the Revenue Recovery System runs $600–$900/mo, pays for itself in week one. Responding within 5 minutes makes a lead 21x more likely to convert vs waiting 30 minutes. 35–45% of HVAC calls arrive after hours.

POSITIONING: We don't sell ads, we install revenue systems. We don't talk about AI, we talk about recovered jobs. We don't serve everyone, built for the trades. We charge for outcomes, and we're a long-term partner. Most installs live within two weeks.

CONTACT: david@otagency.co and marcus@otagency.co.

HOW TO BEHAVE:
- PLAIN TEXT ONLY. Your replies render as raw text in a chat bubble: no markdown, no asterisks, no bold, no headers, no numbered markdown lists. Use short lines and simple dashes for lists.
- Talk like a sharp foreman who read the P&L: plainspoken, short sentences, concrete numbers. No jargon, no hype, no emoji, no exclamation points. Sentence case.
- Keep answers SHORT, 1-3 sentences for simple questions, a few short lines max. This is a chat widget on a phone.
- Recommend by leak, not by upsell: ask what trade they're in and roughly how big the shop is, then match, missed calls → Revenue Recovery / Starter; weak online presence → Storefront; reputation → Growth; wants everything automated → Full Stack. When unsure, point them to the free audit.
- You can take real actions with your tools: check availability, book calls, and add packages to their cart. When someone wants to book, get their name, cell number, and trade, offer available times, then book it and confirm the details back.
- Booking types: "audit" (Free Trade Audit, 30 min), "consult" (general consultation, 20 min), "kickoff" (kickoff call for buyers, 45 min).
- Never invent prices or services beyond the above. If asked something you don't know (specific contracts, guarantees, custom scopes), say David or Marcus will cover it on a call and offer to book one.
- If asked about topics unrelated to Overtime or the trades, steer back politely in one line.`;
}

const OT_CHAT_TOOLS = () => [
  {
    name: 'get_availability',
    description: 'Get open call slots. Returns the next available weekdays and open times (Eastern). Optionally pass a date (YYYY-MM-DD) to check just that day.',
    input_schema: { type: 'object', properties: { date: { type: 'string', description: 'Optional YYYY-MM-DD' } } },
    run: async (input) => {
      const BK = window.OT_BOOKING;
      const days = [];
      const start = new Date();
      for (let i = 1; i <= 21 && days.length < 5; i++) {
        const d = new Date(start.getFullYear(), start.getMonth(), start.getDate() + i);
        const key = BK.dateKey(d);
        if (input && input.date && input.date !== key) continue;
        if (!BK.isBookable(d)) continue;
        const open = BK.slotsFor(d).filter(s => !s.taken).map(s => s.time);
        if (open.length) days.push(`${key} (${BK.fmtDate(key)}): ${open.join(', ')}`);
      }
      return days.length ? days.join('\n') : 'No open slots found in that window.';
    },
  },
  {
    name: 'book_call',
    description: 'Book a call. Requires type (audit|consult|kickoff), date (YYYY-MM-DD), time (exactly as returned by get_availability, e.g. "9:00 AM"), name, phone. Optional: company, trade, email. Returns a confirmation id.',
    input_schema: {
      type: 'object',
      properties: {
        type: { type: 'string', enum: ['audit', 'consult', 'kickoff'] },
        date: { type: 'string' }, time: { type: 'string' },
        name: { type: 'string' }, phone: { type: 'string' },
        company: { type: 'string' }, trade: { type: 'string' }, email: { type: 'string' },
      },
      required: ['type', 'date', 'time', 'name', 'phone'],
    },
    run: async (input) => {
      const BK = window.OT_BOOKING;
      const d = new Date(input.date + 'T12:00:00');
      if (!BK.isBookable(d)) throw new Error('That date is not bookable. Call get_availability for open days.');
      const slot = BK.slotsFor(d).find(s => s.time === input.time);
      if (!slot || slot.taken) throw new Error('That time is taken. Call get_availability for open times.');
      const names = { audit: 'The Free Trade Audit', consult: 'General Consultation', kickoff: 'Kickoff Call' };
      const rec = BK.book({ type: input.type, typeName: names[input.type], date: input.date, time: input.time, name: input.name, phone: input.phone, company: input.company || '', trade: input.trade || '', email: input.email || '', via: 'chat' });
      return `Booked. Confirmation ${rec.id}: ${rec.typeName}, ${BK.fmtDate(rec.date)} at ${rec.time} ET for ${rec.name} (${rec.phone}).`;
    },
  },
  {
    name: 'add_to_cart',
    description: 'Add an item to the site cart. kind is "bundle" (id: starter|growth|fullstack), "service" (id: storefront|recovery|trust|reactivation), or "audit" (id: audit).',
    input_schema: {
      type: 'object',
      properties: { kind: { type: 'string', enum: ['bundle', 'service', 'audit'] }, id: { type: 'string' } },
      required: ['kind', 'id'],
    },
    run: async (input) => {
      const res = window.OT_CART.add(input.kind, input.id);
      if (!res.ok) return res.reason === 'already' ? 'Already in the cart.' : 'Already covered by a bundle in the cart.';
      return `Added. Cart now has ${window.OT_CART.count()} item(s). They can open the cart (top right) or go to checkout.html to book a kickoff call.`;
    },
  },
];

const OT_QUICK = [
  ['What do you install?', 'What systems do you install, in short?'],
  ['Recommend a bundle', 'Can you recommend a package for my shop? Ask me what you need to know.'],
  ['Book my free audit', 'I want to book the free trade audit. What times are open?'],
  ['What does it cost?', 'What do the packages cost?'],
];

// Scripted fallback if window.claude is unavailable
function otScriptedReply(text) {
  const D = window.OT_DATA;
  const t = text.toLowerCase();
  if (/(cost|price|pricing|charge|how much)/.test(t))
    return `Three packages, every one includes the Digital Storefront:\n\n${D.bundles.map(b => `${b.name}, ${D.range(b.setup)} setup, ${D.range(b.monthly)}/mo`).join('\n')}\n\nSystems are also available à la carte, see the Services page.`;
  if (/(install|system|what do you do|services)/.test(t))
    return `Four systems, one revenue engine:\n\n${D.services.map(s => `${s.n} ${s.name}, ${s.pitch}`).join('\n')}\n\nEach works on its own. Together they catch every lead from first ring to follow-up.`;
  if (/(audit|free)/.test(t))
    return `The Free Trade Audit (reg. $200, free this month): we call your shop like a customer, audit your website, Google profile, reviews and follow-up, and hand you a written report of every leak. No pitch, keep the report either way.\n\nBook it on the Book page, takes 30 seconds.`;
  if (/(book|call|schedule|appointment|time)/.test(t))
    return `Head to the Book page, pick the Free Trade Audit or a general consultation, choose a weekday slot, and you're set. Weekdays 9:00 AM–4:30 PM ET.`;
  if (/(recommend|which|bundle|package|fit)/.test(t))
    return `Quick rule of thumb: missed calls are your leak → Overtime Starter. Also want reviews handled → Overtime Growth (most popular). Want the whole thing automated, follow-up included → Full Stack.\n\nNot sure? The free audit will show you exactly where the money's leaking.`;
  return `Good question, David or Marcus can give you a straight answer on a quick call. Book one on the Book page, or email david@otagency.co. You can also ask me about the systems, pricing, or the free audit.`;
}

function OTChat() {
  const [open, setOpen] = React.useState(false);
  const [msgs, setMsgs] = React.useState([
    { role: 'bot', text: 'Overtime here. I can answer questions about the systems and pricing, point you to the right package for your shop, or book your free audit, right now, 24/7. What\u2019s going on with your phones?' },
  ]);
  const [input, setInput] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const histRef = React.useRef([]); // {role:'user'|'assistant', content}
  const scrollRef = React.useRef(null);

  React.useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [msgs, open, busy]);

  const send = async (text) => {
    if (!text.trim() || busy) return;
    setMsgs(m => [...m, { role: 'user', text }]);
    setInput('');
    setBusy(true);
    histRef.current.push({ role: 'user', content: text });
    let reply;
    try {
      // Real AI runs server-side at /api/chat (holds the API key + booking tools).
      const res = await fetch('/api/chat', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ messages: histRef.current.slice(-16) }),
      });
      if (!res.ok) throw new Error('bad status ' + res.status);
      const data = await res.json();
      reply = data.reply || 'Sorry, say that again?';
      // The assistant can add packages to the cart, apply those here.
      (data.actions || []).forEach(a => { if (a.type === 'add_to_cart') window.OT_CART.add(a.kind, a.id); });
      histRef.current.push({ role: 'assistant', content: reply });
    } catch (e) {
      // Offline / not deployed yet: fall back to the scripted keyword answers.
      reply = otScriptedReply(text) + '\n\n(Live assistant is briefly unavailable, this is the short version.)';
    }
    setMsgs(m => [...m, { role: 'bot', text: reply.replace(/\*\*(.+?)\*\*/g, '$1').replace(/^#+\s*/gm, '') }]);
    setBusy(false);
  };

  if (!open) {
    return (
      <button className="ot-chat-fab" onClick={() => setOpen(true)} aria-label="Open chat">
        <span className="dot" aria-hidden="true"></span>
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
          <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
        </svg>
        Ask Overtime
      </button>
    );
  }

  const fresh = msgs.length <= 1 && !busy;

  return (
    <div className="ot-chat-panel" role="dialog" aria-label="Chat with Overtime">
      <div className="ot-chat-head">
        <img src="assets/mark-cream.png" alt="" style={{ height: 30, width: 'auto' }} />
        <div style={{ minWidth: 0 }}>
          <div style={{ fontFamily: 'var(--font-display)', fontSize: 18, textTransform: 'uppercase', lineHeight: 1 }}>Ask Overtime</div>
          <div className="status"><span className="dot"></span>Live now · on the clock 24/7</div>
        </div>
        <button className="ot-chat-close" onClick={() => setOpen(false)} aria-label="Close chat">
          <svg width="12" height="12" viewBox="0 0 12 12" aria-hidden="true"><path d="M1 1l10 10M11 1L1 11" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/></svg>
        </button>
      </div>

      <div ref={scrollRef} style={{ flex: 1, overflow: 'auto', display: 'flex', flexDirection: 'column', background: 'var(--surface-page)' }}>
        {fresh ? (
          <div className="ot-chat-intro">
            <div className="hi">What's going on with your phones?</div>
            <p className="sub">Straight answers on the systems, pricing, and the free audit, or book a call right here. No forms, no hold music.</p>
            <div className="ot-chat-quickgrid">
              {OT_QUICK.map(([label, msg]) => (
                <button key={label} className="ot-chat-quickcard" onClick={() => send(msg)} disabled={busy}>
                  {label}
                  <span className="arw" aria-hidden="true">→</span>
                </button>
              ))}
            </div>
          </div>
        ) : (
          <div style={{ padding: 14, display: 'flex', flexDirection: 'column', gap: 10 }}>
            {msgs.map((m, i) => m.role === 'bot' ? (
              <div key={i} className="ot-bot-row">
                <img src="assets/mark-red.png" alt="" aria-hidden="true" />
                <div className="ot-msg bot">{m.text}</div>
              </div>
            ) : (
              <div key={i} className="ot-msg user">{m.text}</div>
            ))}
            {busy && (
              <div className="ot-bot-row">
                <img src="assets/mark-red.png" alt="" aria-hidden="true" />
                <div className="ot-msg bot" aria-label="Overtime is typing">
                  <span className="ot-typing"><span></span><span></span><span></span></span>
                </div>
              </div>
            )}
          </div>
        )}
      </div>

      {!fresh && (
        <div style={{ padding: '10px 12px', display: 'flex', gap: 8, overflowX: 'auto', borderTop: '1px solid var(--border-default)', background: 'var(--surface-page)' }}>
          {OT_QUICK.map(([label, msg]) => (
            <button key={label} className="ot-chip" onClick={() => send(msg)} disabled={busy}>{label}</button>
          ))}
        </div>
      )}

      <form className="ot-chat-inputbar" onSubmit={(e) => { e.preventDefault(); send(input); }}>
        <input value={input} onChange={(e) => setInput(e.target.value)} placeholder="Type your question…" aria-label="Your message" />
        <button className="ot-chat-send" type="submit" disabled={busy || !input.trim()} aria-label="Send">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
            <path d="M12 19V5"></path><path d="m5 12 7-7 7 7"></path>
          </svg>
        </button>
      </form>
    </div>
  );
}

Object.assign(window, { OTChat });
