/* ============================================================
   SHARED — icons, helpers, Claude API wiring
   ============================================================ */
const { useState, useEffect, useRef, useCallback } = React;

/* ---------- Icon set (line icons) ---------- */
const ICON_PATHS = {
  chat: '<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/>',
  contract: '<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="13" x2="15" y2="13"/><line x1="9" y1="17" x2="13" y2="17"/>',
  review: '<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"/><circle cx="11.5" cy="14.5" r="2.5"/><line x1="16" y1="19" x2="13.3" y2="16.3"/>',
  alerts: '<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/>',
  settings: '<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>',
  send: '<line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/>',
  scale: '<path d="M12 3v18"/><path d="M7 7h10"/><path d="M5 21h14"/><path d="M7 7l-3.5 7a3.5 3.5 0 0 0 7 0z"/><path d="M17 7l-3.5 7a3.5 3.5 0 0 0 7 0z"/>',
  menu: '<line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/>',
  download: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/>',
  copy: '<rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>',
  upload: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/>',
  check: '<polyline points="20 6 9 17 4 12"/>',
  checkCircle: '<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>',
  warn: '<path d="M10.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"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>',
  plus: '<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>',
  calendar: '<rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/>',
  clock: '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
  sparkle: '<path d="M12 3l1.9 5.8a2 2 0 0 0 1.3 1.3L21 12l-5.8 1.9a2 2 0 0 0-1.3 1.3L12 21l-1.9-5.8a2 2 0 0 0-1.3-1.3L3 12l5.8-1.9a2 2 0 0 0 1.3-1.3z"/>',
  trash: '<polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>',
  bolt: '<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>',
  shield: '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>',
  arrowRight: '<line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/>',
  x: '<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>',
  euro: '<path d="M15 18a6 6 0 1 1 0-12"/><line x1="3" y1="10" x2="13" y2="10"/><line x1="3" y1="14" x2="11" y2="14"/>',
  file: '<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"/>',
  user: '<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',
  bell: '<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/>',
  home: '<path d="M3 9.5 12 3l9 6.5"/><path d="M5 10v10a1 1 0 0 0 1 1h3v-6h6v6h3a1 1 0 0 0 1-1V10"/>',
  book: '<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>',
  search: '<circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>',
  globe: '<circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>',
  lock: '<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>',
  history: '<path d="M3 3v5h5"/><path d="M3.05 13A9 9 0 1 0 6 5.3L3 8"/><path d="M12 7v5l4 2"/>',
  message: '<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>',
  building: '<rect x="4" y="2" width="16" height="20" rx="1.5"/><path d="M9 22v-4h6v4"/><line x1="8" y1="6" x2="8" y2="6"/><line x1="12" y1="6" x2="12" y2="6"/><line x1="16" y1="6" x2="16" y2="6"/><line x1="8" y1="10" x2="8" y2="10"/><line x1="12" y1="10" x2="12" y2="10"/><line x1="16" y1="10" x2="16" y2="10"/>',
  home2: '<path d="M3 9.5 12 3l9 6.5V20a1 1 0 0 1-1 1h-5v-7H9v7H4a1 1 0 0 1-1-1z"/>',
  heart: '<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>',
  briefcase: '<rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/>',
  eye: '<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>',
  edit: '<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.12 2.12 0 0 1 3 3L12 15l-4 1 1-4z"/>',
  lockKey: '<rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/><circle cx="12" cy="16" r="1.4"/>',
  mail: '<rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>',
  hourglass: '<path d="M5 22h14"/><path d="M5 2h14"/><path d="M17 22v-4.17a2 2 0 0 0-.59-1.42L12 12l-4.41 4.41A2 2 0 0 0 7 17.83V22"/><path d="M7 2v4.17a2 2 0 0 0 .59 1.42L12 12l4.41-4.41A2 2 0 0 0 17 6.17V2"/>',
};

function Icon({ name, size = 18, className = '', stroke = 1.8 }) {
  return (
    <svg
      className={'ic ' + className}
      width={size} height={size} viewBox="0 0 24 24"
      fill="none" stroke="currentColor"
      strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
      dangerouslySetInnerHTML={{ __html: ICON_PATHS[name] || '' }}
    />
  );
}

/* ---------- Lexly avatar (scales of justice) ---------- */
function LexAvatar({ size = 34 }) {
  return (
    <div className="lex-avatar" style={{ width: size, height: size }}>
      <Icon name="scale" size={size * 0.55} stroke={1.7} className="" />
      <style>{`.lex-avatar .ic { color: var(--violet-soft); }`}</style>
    </div>
  );
}

/* ---------- Loading ---------- */
function Spinner() { return <div className="spinner" />; }
function Typing() { return <div className="typing"><span></span><span></span><span></span></div>; }

/* ============================================================
   Claude API helper — Lexly system prompt baked in
   ============================================================ */
const LEXLY_SYSTEM = `Eres Lexly, un asistente legal inteligente especializado en el ordenamiento jurídico español y la normativa de la Unión Europea. Ayudas a autónomos, freelancers, pymes y particulares a entender sus derechos y obligaciones legales de forma clara, precisa y accesible. Respondes siempre en español, con lenguaje claro y sin jerga jurídica innecesaria. Cuando usas términos legales, los explicas brevemente. Citas la normativa concreta cuando es relevante (ley, artículo, reglamento). Eres empático y cercano, nunca frío ni distante. Vas al grano: primero la respuesta directa, luego la explicación. Tus áreas: contratos mercantiles y civiles, obligaciones fiscales de autónomos y pymes, derecho laboral básico, protección de datos (RGPD), reclamación de deudas, derecho del consumidor. Tus límites: ofreces información legal, no asesoramiento jurídico profesional. Cuando la situación requiere abogado colegiado, lo dices claramente. Al final de cada respuesta importante añades: Recuerda que esta información no sustituye el asesoramiento de un abogado colegiado.`;

/* Calls Claude. Accepts an array of {role, content} turns OR a single string.
   The Lexly system prompt is injected as a preamble on the first user turn so
   it works regardless of whether the host supports a separate `system` field. */
async function callLexly(messagesOrPrompt, systemOverride, maxTokens) {
  let system = systemOverride || LEXLY_SYSTEM;
  // Personalización RGPD: añade el contexto del perfil consentido SIN eliminar las reglas existentes.
  try {
    if (typeof window.lxProfileContext === 'function') {
      const ctx = window.lxProfileContext();
      if (ctx) system = system + '\n\n' + ctx;
    }
  } catch (e) {}
  let messages;
  if (typeof messagesOrPrompt === 'string') {
    messages = [{ role: 'user', content: messagesOrPrompt }];
  } else {
    messages = messagesOrPrompt.map(m => ({ role: m.role, content: m.content }));
  }

  const res = await fetch('/api/chat', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ messages, system, max_tokens: maxTokens || 1024 }),
  });

  if (!res.ok) {
    let msg = 'API_ERROR';
    try { const j = await res.json(); if (j.error) msg = j.error; } catch (e) {}
    throw new Error(msg);
  }
  const data = await res.json();
  if (data.error) throw new Error(data.error);
  return data.content;
}

/* ============================================================
   Minimal markdown renderer (bold, headings, lists, paragraphs)
   ============================================================ */
function mdInline(text) {
  let t = text
    .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  t = t.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
  t = t.replace(/\*(.+?)\*/g, '<em>$1</em>');
  t = t.replace(/`(.+?)`/g, '<code>$1</code>');
  return t;
}

function Markdown({ text }) {
  const blocks = [];
  const lines = (text || '').split('\n');
  let list = null;
  let para = [];
  const flushPara = () => {
    if (para.length) { blocks.push({ type: 'p', content: para.join(' ') }); para = []; }
  };
  const flushList = () => {
    if (list) { blocks.push(list); list = null; }
  };
  lines.forEach(raw => {
    const line = raw.trimEnd();
    if (!line.trim()) { flushPara(); flushList(); return; }
    let m;
    if ((m = line.match(/^(#{1,4})\s+(.*)/))) {
      flushPara(); flushList();
      blocks.push({ type: 'h', level: m[1].length, content: m[2] });
    } else if ((m = line.match(/^\s*[-*•]\s+(.*)/))) {
      flushPara();
      if (!list || list.ordered) { flushList(); list = { type: 'ul', ordered: false, items: [] }; }
      list.items.push(m[1]);
    } else if ((m = line.match(/^\s*\d+[.)]\s+(.*)/))) {
      flushPara();
      if (!list || !list.ordered) { flushList(); list = { type: 'ul', ordered: true, items: [] }; }
      list.items.push(m[1]);
    } else {
      flushList();
      para.push(line);
    }
  });
  flushPara(); flushList();

  return (
    <div className="md">
      {blocks.map((b, i) => {
        if (b.type === 'h') {
          const Tag = 'h' + Math.min(b.level + 2, 6);
          return <Tag key={i} className="md-h" dangerouslySetInnerHTML={{ __html: mdInline(b.content) }} />;
        }
        if (b.type === 'ul') {
          return b.ordered
            ? <ol key={i} className="md-list">{b.items.map((it, j) => <li key={j} dangerouslySetInnerHTML={{ __html: mdInline(it) }} />)}</ol>
            : <ul key={i} className="md-list">{b.items.map((it, j) => <li key={j} dangerouslySetInnerHTML={{ __html: mdInline(it) }} />)}</ul>;
        }
        return <p key={i} className="md-p" dangerouslySetInnerHTML={{ __html: mdInline(b.content) }} />;
      })}
      <style>{`
        .md { font-size: 14px; line-height: 1.62; color: var(--text); }
        .md > *:first-child { margin-top: 0; }
        .md > *:last-child { margin-bottom: 0; }
        .md-p { margin: 9px 0; }
        .md-h { color: var(--white); font-weight: 600; letter-spacing: -0.01em; margin: 16px 0 7px; }
        h3.md-h { font-size: 15.5px; }
        h4.md-h { font-size: 14px; }
        h5.md-h, h6.md-h { font-size: 13px; }
        .md-list { margin: 9px 0; padding-left: 20px; }
        .md-list li { margin: 5px 0; padding-left: 3px; }
        .md-list li::marker { color: var(--violet-soft); }
        .md strong { color: var(--white); font-weight: 600; }
        .md code { background: var(--surface-3); padding: 1px 6px; border-radius: 5px; font-size: 0.88em; font-family: ui-monospace, monospace; color: var(--violet-soft); }
      `}</style>
    </div>
  );
}

/* ---------- Error banner ---------- */
function ErrorNote({ children, onRetry }) {
  return (
    <div className="err-note">
      <Icon name="warn" size={15} />
      <span>{children}</span>
      {onRetry && <button onClick={onRetry}>Reintentar</button>}
      <style>{`
        .err-note {
          display: flex; align-items: center; gap: 9px;
          font-size: 12.5px; color: var(--red);
          background: var(--red-dim); border: 1px solid rgba(248,113,113,0.28);
          border-radius: 10px; padding: 9px 13px; margin: 10px 0;
        }
        .err-note button {
          margin-left: auto; color: var(--red); font-weight: 600; font-size: 12px;
          text-decoration: underline; text-underline-offset: 2px;
        }
      `}</style>
    </div>
  );
}

Object.assign(window, {
  Icon, LexAvatar, Spinner, Typing,
  callLexly, LEXLY_SYSTEM, Markdown, ErrorNote,
});
