// Wasabilito — floating AI-like assistant chat
// Client-side intent matching with keyword scoring + clarifying questions.

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

  // Intent definitions with keywords + target route + display label
  // Expanded with Chilean slang, synonyms, common typos, colloquial speech
  const INTENT_DB = [
    {
      id: "ecommerce",
      title: "Facturación para e-commerce",
      url: "producto.html#ecommerce",
      keywords: [
        "ecommerce","e-commerce","e commerce","comercio electronico","comercio electrónico",
        "tienda","tienda online","tienda virtual","mi tienda","mitienda",
        "shopify","shopyfy","shopi",
        "mercado libre","mercadolibre","meli","mercadolivre","mercado-libre",
        "marketplace","marketplaces","plaza","marketspace",
        "woocommerce","wocomerce","jumpseller","tiendanube",
        "venta online","ventas online","venta por internet","vender online","vender por internet",
        "vendo online","vendo en internet","vendo en shopify","vendo en mercado",
        "ventas digitales","ventas en linea","ventas en línea","vender","emprendedor","emprendimiento",
        "checkout","carrito","carro","carro de compra","pago online","pagar online",
        "compra online","compras online","cliente compra",
        "boleta automatica","boleta automática","factura automatica","factura automática",
        "emision automatica","emisión automática",
        "devolucion","devolución","devoluciones","devolver","reembolso","reembolsar",
        "nota de credito","nota de crédito","notas de credito","nota credito","cambio","cambios",
        "punto de venta","pos","caja",
      ],
    },
    {
      id: "facturacion",
      title: "Automatización de documentos",
      url: "producto.html#facturacion",
      keywords: [
        "facturacion","facturación","factura","facturar","facturo","facturas","emitir factura",
        "boleta","boletas","emitir boleta","boleta electronica","boleta electrónica",
        "nota de debito","nota de débito","notas de debito","guia de despacho","guía de despacho",
        "guias","guías","documento tributario","documentos tributarios","dte","dtes",
        "automatizar","automatizar factura","automatizar facturas","automatizar documentos",
        "automatizar boletas","automatizar mis facturas","automatizar mis boletas",
        "emitir","emite","emision","emisión","emitir electronico","emitir electrónico",
        "electronica","electrónica","electronico","electrónico",
        "sii","servicio de impuestos","impuestos internos",
        "folio","folios","caf","reobtener folios",
        "no quiero emitir","me olvido","se me olvidan","perdiendo tiempo",
        "ayuda con facturas","ayuda con boletas","manejar facturas","gestionar facturas",
        "facturador","facturador electronico","facturador electrónico","sistema de facturacion","sistema de facturación",
        "bsale","openfactura","lioren","cambiar facturador",
        "boleta de tercero","boletas de tercero",
        "validar factura","error sii","rechazo sii","rechazada","rechazado",
      ],
    },
    {
      id: "gastos",
      title: "Recuperar IVA de gastos extranjeros",
      url: "producto.html#gastos",
      keywords: [
        "iva","recuperar iva","recupero iva","recupera iva","devolucion iva","devolución iva",
        "credito fiscal","crédito fiscal","credito iva","crédito iva","f29","formulario 29","declarar iva",
        "pagar menos iva","menos iva","ahorro iva","ahorrar iva","iva pagado",
        "servicio digital","servicios digitales","gasto digital","gastos digitales",
        "gasto extranjero","gastos extranjeros","gasto en el extranjero","gastos en el extranjero",
        "extranjero","fuera de chile","servicios afuera",
        "google","google ads","google workspace","google cloud","gsuite",
        "meta","facebook","facebook ads","instagram ads","instagram","whatsapp business","wsp business",
        "aws","amazon web services","amazon",
        "openai","chatgpt","chat gpt","anthropic","api de claude",
        "microsoft","azure","office 365","microsoft 365",
        "shopify plus","shopify pro",
        "stripe","paypal","mercado pago",
        "notion","slack","figma","adobe","canva pro",
        "netflix","spotify","zoom","linkedin premium",
        "dolar","dólar","dolares","dólares","usd","en dolares","en dólares",
        "conversion","conversión","tipo de cambio","cambio de moneda",
        "factura de compra","factura de compras","fc","emitir factura de compra",
        "ahorro","ahorrar","ahorros","me ahorro","dejar de pagar","pagar menos",
        "plata de vuelta","devolver plata","me devuelvan plata","devolver iva","retorno iva",
      ],
    },
    {
      id: "conciliacion",
      title: "Conciliación bancaria",
      url: "producto.html#conciliacion",
      keywords: [
        "conciliacion","conciliación","conciliar","concilio","conciliando",
        "cruzar","cruce","cruce bancario","cuadrar","cuadrar caja","cuadrar cuenta",
        "banco","bancaria","bancario","cuenta corriente","cuenta","ctacte","cta corriente",
        "cartola","cartolas","estado de cuenta","estados de cuenta","movimientos",
        "santander","chile","banco de chile","bci","itau","itaú","bice","scotiabank","scotia",
        "bancoestado","banco estado","falabella","ripley","security","consorcio",
        "transferencia","transferencias","tef","deposito","depósito","depósitos",
        "cheque","cheques","abono","cargo","cargos","comision bancaria","comisión bancaria",
        "movimiento","movimientos","movimiento bancario","movimientos bancarios",
        "desastre","mi banco","mi cuenta","vivir en excel","excel","planilla","macro",
        "muchas transferencias","no identifico","sin orden","desordenada","desordenado",
        "caja chica","flujo de caja","cash flow","flujo",
      ],
    },
    {
      id: "mcp",
      title: "Conectar IA (MCP · Claude · Cursor)",
      url: "producto.html#mcp",
      keywords: [
        "ia","ai","inteligencia artificial","inteligencia artifical","i.a.",
        "agente","agente ia","agente ai","agente de ia","agente inteligente",
        "bot","chatbot","asistente","asistente virtual","copilot",
        "llm","modelo de lenguaje","gpt","transformer",
        "claude","cloud","claud","antropic","anthropic",
        "cursor","cursor ai","cursor ide",
        "chatgpt","chat gpt","openai","open ai",
        "gemini","perplexity","grok",
        "mcp","model context protocol","servidor mcp","protocol",
        "tool","tool call","tool-call","tool use","herramienta",
        "api","api wasabil","integracion api","integración api","integrar api",
        "webhook","rest","endpoint","rest api","graphql",
        "automatizar con ia","automatizar con ai","automatizar con claude","automatizar con gpt",
        "conectar con ia","conectar con ai","conectar claude","conectar chatgpt","conectar ai",
        "facturar con ia","facturar con ai","facturar con claude",
        "hablar con wasabil","pedirle a claude","pedirle a gpt",
        "lenguaje natural","en lenguaje natural",
        "desarrollador","programador","developer","sdk",
      ],
    },
    {
      id: "precios",
      title: "Planes y precios",
      url: "pricing.html",
      keywords: [
        "precio","precios","plan","planes","tarifa","tarifas","valor","valores",
        "cuanto cuesta","cuánto cuesta","cuanto sale","cuánto sale","cuanto vale","cuánto vale",
        "cuanto me sale","cuánto me sale","cuanto me cobran","cuánto me cobran","cuanto pago","cuánto pago",
        "cuanto es","cuánto es","que cuesta","qué cuesta","saber cuanto","saber cuánto",
        "costo","costos","costear","inversion","inversión",
        "mensual","mensualidad","al mes","por mes","mensualmente",
        "anual","al año","al ano","por año","por ano","suscripcion","suscripción","suscribir",
        "membresia","membresía",
        "mini","growth","full","unlimited","enterprise","plan mini","plan growth","plan full",
        "mas barato","más barato","mas economico","más económico","mas conveniente","más conveniente",
        "economico","económico","barato","caro","cuanto mas","cuánto más",
        "cotizacion","cotización","cotizar","quiero cotizar","presupuesto","budget",
        "cuanta plata","cuánta plata","cuanta luca","cuánta luca","cuantas lucas","cuántas lucas",
        "la plata","a cuanto","a cuánto","sale caro","sale barato",
        "gratis","prueba gratis","probar","trial","free",
      ],
    },
    {
      id: "agenda",
      title: "Agendar una reunión",
      url: "agenda.html",
      keywords: [
        "agendar","agenda","agendemos","agendar hora","agendar reunion","agendar reunión",
        "reunion","reunión","reunirse","junta","meeting",
        "demo","demostracion","demostración","demito","ver el producto",
        "llamada","call","llamar","telefono","teléfono","zoom","google meet",
        "hablar","hablar con alguien","quiero hablar","conversar","quiero conversar",
        "contacto","contactar","contactenme","contáctenme","contactarlos","contactarse",
        "ejecutivo","persona","humano","vendedor","comercial","ventas",
        "whatsapp","wsp","chat humano","asesor","asesoria","asesoría",
        "soporte","ayuda","help",
      ],
    },
    {
      id: "blog",
      title: "Blog & recursos",
      url: "blog.html",
      keywords: [
        "blog","articulo","artículo","articulos","artículos","post","posts","entrada",
        "guia","guía","guias","guías","tutorial","tutoriales","aprender","leer",
        "recurso","recursos","lectura","lecturas","material",
        "como hacer","cómo hacer","como configurar","cómo configurar",
        "novedades","noticias","news","updates",
      ],
    },
    {
      id: "about",
      title: "Sobre Wasabil",
      url: "about.html",
      keywords: [
        "quienes son","quiénes son","quien son","quién son","nosotros","sobre nosotros",
        "equipo","team","fundadores","founders","ceo","cto","founder",
        "empresa","la empresa","startup","sobre wasabil","conocer","conocerlos",
        "historia","mision","misión","vision","visión","valores",
        "donde estan","dónde están","donde queda","dónde queda","oficina","oficinas",
        "trabajar","jobs","carreras","careers","hiring","contratan","contratando",
      ],
    },
  ];

  // Stop-words — fillers that shouldn't count alone
  const STOP_WORDS = new Set([
    "quiero","necesito","me","yo","tu","tú","de","la","el","los","las","un","una","unos","unas",
    "que","qué","como","cómo","donde","dónde","cuando","cuándo","para","por","con","sin","sobre",
    "y","o","pero","mas","más","menos","es","son","ser","estar","hay","tengo","tiene","tienes",
    "ayuda","saber","quisiera","puedo","podria","podría","mostrar","muestrame","muéstrame",
    "dime","dímelo","favor","gracias","hola","hi","hey","ok","bueno","si","sí","no",
    "en","mi","tu","su","sus","mis","tus","esto","esta","este","eso","esa","ese",
    "porque","porqué","cual","cuál","cuales","cuáles",
  ]);

  // Normalize (lowercase, strip accents, punctuation)
  function norm(s) {
    return (s || "")
      .toLowerCase()
      .normalize("NFD")
      .replace(/[̀-ͯ]/g, "")
      .replace(/[¿?¡!,.:;()]/g, " ")
      .replace(/\s+/g, " ")
      .trim();
  }

  function tokenize(q) {
    return norm(q)
      .split(" ")
      .filter(w => w.length >= 2 && !STOP_WORDS.has(w));
  }

  // Score intents by keyword presence; return ranked matches
  // Hard override — if user mentions these, always eCommerce
  const ECOMMERCE_HARD_HITS = [
    "shopify","shopyfy","shopi",
    "mercado libre","mercadolibre","meli","mercado-libre","mercadolivre",
    "jumpseller","tiendanube","woocommerce","wocomerce",
  ];

  function scoreIntents(text) {
    const t = norm(text);
    if (!t || t.length < 2) return [];

    // Hard override: Shopify / Mercado Libre → always eCommerce with max score
    for (const kw of ECOMMERCE_HARD_HITS) {
      if (t.includes(kw)) {
        const ec = INTENT_DB.find(i => i.id === "ecommerce");
        return [{ intent: ec, score: 999 }];
      }
    }

    const tokens = tokenize(t);

    const scored = INTENT_DB.map(intent => {
      let score = 0;
      for (const kw of intent.keywords) {
        const nk = norm(kw);
        if (t === nk) { score += 8; continue; }
        if (t.includes(nk)) {
          const wholeWord = new RegExp(`\\b${nk.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(t);
          score += Math.min(6, (wholeWord ? 2 : 1) + Math.floor(nk.length / 4));
          continue;
        }
        // Single token with morphology (prefix match 5 chars)
        if (nk.length >= 3 && !nk.includes(" ")) {
          for (const tok of tokens) {
            if (tok === nk) { score += 3; break; }
            if (tok.length >= 4 && nk.length >= 4 &&
                (tok.startsWith(nk.slice(0, Math.min(5, nk.length))) ||
                 nk.startsWith(tok.slice(0, Math.min(5, tok.length))))) {
              score += 2;
              break;
            }
          }
        }
      }
      return { intent, score };
    }).filter(s => s.score > 0).sort((a, b) => b.score - a.score);
    return scored;
  }

  // Suggest clarifying step when ambiguous
  function buildReply(userText) {
    const scored = scoreIntents(userText);
    if (scored.length === 0) {
      return {
        kind: "clarify",
        text: "No soy tan inteligente, ¿me lo puedes decir más tranqui 😅?",
        options: [
          { label: "Facturar desde mi e-commerce", intentId: "ecommerce" },
          { label: "Automatizar mis documentos", intentId: "facturacion" },
          { label: "Recuperar IVA de Google/Meta", intentId: "gastos" },
          { label: "Ver precios", intentId: "precios" },
          { label: "Hablar con un humano", intentId: "agenda" },
        ],
      };
    }

    const top = scored[0];
    const second = scored[1];
    const ambiguous = second && (top.score - second.score) < 2;

    if (ambiguous) {
      return {
        kind: "clarify",
        text: "Podría ser cualquiera de estas. ¿Cuál se parece más a lo que buscas?",
        options: scored.slice(0, 4).map(s => ({
          label: s.intent.title,
          intentId: s.intent.id,
        })),
      };
    }

    return {
      kind: "match",
      intent: top.intent,
      text: `Esto es lo que buscas: ${top.intent.title}. Te llevo ahí ahora.`,
    };
  }

  function getIntent(id) {
    return INTENT_DB.find(i => i.id === id);
  }

  // ---- Component ----
  const TEASER_SHOWN_KEY = "wbt_teaser_shown";

  function WasabilitoChat() {
    const [isOpen, setIsOpen] = useState(false);
    // Start dismissed if the teaser has already shown during this browser session.
    // sessionStorage resets on tab close / hard reload, so a refresh re-shows it.
    const [teaserDismissed, setTeaserDismissed] = useState(() => {
      try {
        return sessionStorage.getItem(TEASER_SHOWN_KEY) === "1";
      } catch (e) {
        return false;
      }
    });
    const [input, setInput] = useState("");
    const [messages, setMessages] = useState([
      {
        role: "bot",
        text: "Hola, soy Wasabilito 🌱. Cuéntame qué necesitas y te llevo al lugar correcto.",
      },
    ]);
    const scrollRef = useRef(null);
    const inputRef = useRef(null);

    // Mark teaser as shown the first time it renders.
    // From that point on, any navigation / click / dismiss keeps it hidden.
    useEffect(() => {
      if (!teaserDismissed) {
        try { sessionStorage.setItem(TEASER_SHOWN_KEY, "1"); } catch (e) {}
      }
    }, []);

    // Auto scroll on new message
    useEffect(() => {
      if (scrollRef.current) {
        scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
      }
    }, [messages]);

    // Focus input on open
    useEffect(() => {
      if (isOpen && inputRef.current) {
        setTimeout(() => inputRef.current.focus(), 300);
      }
    }, [isOpen]);

    function openChat() {
      setIsOpen(true);
      setTeaserDismissed(true);
    }

    function pushMessage(msg) {
      setMessages(m => [...m, msg]);
    }

    function handleSubmit(text) {
      const trimmed = (text || "").trim();
      if (!trimmed) return;
      pushMessage({ role: "user", text: trimmed });
      setInput("");

      // simulate small delay for natural feel
      setTimeout(() => {
        const reply = buildReply(trimmed);
        pushMessage({ role: "bot", ...reply });

        if (reply.kind === "match") {
          setTimeout(() => {
            window.location.href = reply.intent.url;
          }, 1200);
        }
      }, 450);
    }

    function handleOptionPick(intentId) {
      const intent = getIntent(intentId);
      if (!intent) return;
      pushMessage({ role: "user", text: intent.title });
      setTimeout(() => {
        pushMessage({
          role: "bot",
          kind: "match",
          intent,
          text: `Perfecto. Te llevo a ${intent.title}.`,
        });
        setTimeout(() => {
          window.location.href = intent.url;
        }, 1000);
      }, 350);
    }

    function onKeyDown(e) {
      if (e.key === "Enter" && !e.shiftKey) {
        e.preventDefault();
        handleSubmit(input);
      }
    }

    return (
      <>
        {/* Teaser bubble — only when closed and not dismissed */}
        {!isOpen && !teaserDismissed && (
          <div className="wbt-teaser" role="button" tabIndex={0}
            onClick={openChat}
            onKeyDown={e => { if (e.key === "Enter") openChat(); }}>
            <button
              className="wbt-teaser-close"
              onClick={(e) => { e.stopPropagation(); setTeaserDismissed(true); }}
              aria-label="Cerrar">
              <svg width="12" height="12" viewBox="0 0 24 24" fill="none">
                <path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
              </svg>
            </button>
            <div className="wbt-teaser-mascot">
              <img src="assets/wasabilitos/wave.png" alt="" style={{ width: 60, height: 60, objectFit: "contain" }}/>
            </div>
            <div className="wbt-teaser-body">
              <div className="wbt-teaser-eyebrow">Wasabilito · en línea</div>
              <div className="wbt-teaser-title">¿Necesitas algo? Yo te ayudo.</div>
              <div className="wbt-teaser-sub">Cuéntame qué buscas y te llevo directo al lugar correcto — en segundos.</div>
              <div className="wbt-teaser-cta">
                Escríbeme
                <ArrowRight size={14}/>
              </div>
            </div>
          </div>
        )}

        {/* Floating launcher button — visible only after teaser dismissed */}
        {!isOpen && teaserDismissed && (
          <button className="wbt-launcher" onClick={openChat} aria-label="Abrir chat con Wasabilito">
            <Mascot pose="explain" size={40}/>
            <span className="wbt-launcher-dot"/>
          </button>
        )}

        {/* Chat panel */}
        <div className={`wbt-panel ${isOpen ? "is-open" : ""}`} aria-hidden={!isOpen}>
          <div className="wbt-header">
            <div className="wbt-header-left">
              <div className="wbt-header-mascot"><Mascot pose="explain" size={36}/></div>
              <div>
                <div className="wbt-header-name">Wasabilito <span className="wbt-header-status">en línea</span></div>
                <div className="wbt-header-role">Te ayudo a encontrar lo que buscas</div>
              </div>
            </div>
            <button className="wbt-header-close" onClick={() => setIsOpen(false)} aria-label="Cerrar">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
                <path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
              </svg>
            </button>
          </div>

          <div className="wbt-messages" ref={scrollRef}>
            {messages.map((m, i) => (
              <div key={i} className={`wbt-msg ${m.role === "bot" ? "is-bot" : "is-user"}`}>
                {m.role === "bot" && (
                  <div className="wbt-msg-avatar"><Mascot pose="explain" size={22}/></div>
                )}
                <div className="wbt-msg-content">
                  <div className="wbt-msg-bubble">{m.text}</div>
                  {m.kind === "clarify" && m.options && (
                    <div className="wbt-options">
                      {m.options.map((opt, oi) => (
                        <button
                          key={oi}
                          className="wbt-option"
                          onClick={() => handleOptionPick(opt.intentId)}>
                          {opt.label}
                          <ArrowUpRight size={12}/>
                        </button>
                      ))}
                    </div>
                  )}
                  {m.kind === "match" && m.intent && (
                    <a className="wbt-match-link" href={m.intent.url}>
                      <Check size={12}/> Ir a {m.intent.title}
                    </a>
                  )}
                </div>
              </div>
            ))}
          </div>

          {/* Quick suggestions when chat is fresh */}
          {messages.length <= 1 && (
            <div className="wbt-suggestions">
              {[
                "Quiero facturar en mi e-commerce",
                "Recuperar IVA de Google Ads",
                "Ver precios",
              ].map((s, i) => (
                <button key={i} className="wbt-suggestion" onClick={() => handleSubmit(s)}>
                  {s}
                </button>
              ))}
            </div>
          )}

          <div className="wbt-input-row">
            <input
              ref={inputRef}
              type="text"
              placeholder="Escribe lo que buscas…"
              value={input}
              onChange={e => setInput(e.target.value)}
              onKeyDown={onKeyDown}
              className="wbt-input"
            />
            <button className="wbt-send" onClick={() => handleSubmit(input)} aria-label="Enviar">
              <ArrowRight size={14}/>
            </button>
          </div>
        </div>
      </>
    );
  }

  window.WasabilitoChat = WasabilitoChat;
})();
