/* global React, T, publishMenu, generateMenuAI, listQR, createQR, deleteQR, slugify */
const { useState: useStateM, useMemo: useMemoM, useEffect: useEffectM, useRef: useRefM } = React;

const appConfig = () => (window.Supa && window.Supa.config()) || {};

const CATEGORY_ORDER = ["Tapas", "Raciones", "Bebidas", "Postres"];

const SAMPLE_MENU = [
  { category: "Tapas",    name: "Patatas bravas",     price: 5.00,  description: "Crispy potatoes, spicy house aioli." },
  { category: "Tapas",    name: "Croquetas de jamón", price: 6.50,  description: "Five-year Ibérico, béchamel, golden." },
  { category: "Raciones", name: "Pulpo a la gallega", price: 14.00, description: "Galician octopus, paprika, olive oil." },
  { category: "Bebidas",  name: "Vino tinto Rioja",   price: 5.00,  description: "House red, crianza, by the glass." },
  { category: "Postres",  name: "Crema catalana",     price: 4.50,  description: "Cinnamon custard, burnt-sugar crust." },
];

const tmpId = () => "tmp_" + Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
const normalize = (it, i) => ({
  id: it.id != null ? it.id : tmpId(),
  category: it.category || "Tapas",
  name: it.name || "",
  price: Number(it.price) || 0,
  description: it.description || it.desc || "",
  position: it.position != null ? it.position : i,
});

// Real QR rendered to a canvas via qrcode-generator -> crisp PNG.
const makeQRCanvas = (text, px, ecl) => {
  const qr = window.qrcode(0, ecl || "M");
  qr.addData(text);
  qr.make();
  const n = qr.getModuleCount();
  const margin = 4;
  const total = n + margin * 2;
  const cell = Math.max(1, Math.floor(px / total));
  const dim = cell * total;
  const c = document.createElement("canvas");
  c.width = dim; c.height = dim;
  const ctx = c.getContext("2d");
  ctx.fillStyle = "#ffffff"; ctx.fillRect(0, 0, dim, dim);
  ctx.fillStyle = "#0f0f14";
  for (let r = 0; r < n; r++) for (let col = 0; col < n; col++) {
    if (qr.isDark(r, col)) ctx.fillRect((col + margin) * cell, (r + margin) * cell, cell, cell);
  }
  return c;
};

const qrDataUrl = (text, px, ecl) => {
  try { return makeQRCanvas(text, px, ecl).toDataURL("image/png"); }
  catch (e) { return ""; }
};

const QRImage = ({ text, size = 220 }) => {
  const [src, setSrc] = useStateM("");
  useEffectM(() => {
    if (window.qrcode && text) setSrc(qrDataUrl(text, size * 3, "M"));
  }, [text, size]);
  return src
    ? <img src={src} width={size} height={size} alt="QR code" style={{ display: "block", borderRadius: 8, width: size, height: size, imageRendering: "pixelated" }} />
    : <div className="qr-skeleton" style={{ width: size, height: size }} />;
};

const downloadQR = (text, filename) => {
  const url = qrDataUrl(text, 1024, "H");
  if (!url) return;
  const a = document.createElement("a");
  a.href = url; a.download = filename; a.click();
};

const MenuTab = ({ lang, restaurantName, slug, initialMenu, onPublished }) => {
  const isES = lang === "es";
  const draftKey = "scanalytics_menu_draft_" + slug;
  const cfg = appConfig();
  const aiEnabled = !!cfg.aiEnabled;

  const [items, setItems] = useStateM(() => {
    try { const d = localStorage.getItem(draftKey); if (d) return JSON.parse(d); } catch {}
    return (initialMenu && initialMenu.length) ? initialMenu.map(normalize) : [];
  });

  // Adopt the published menu once it loads, if the editor is still empty.
  useEffectM(() => {
    if (items.length === 0 && initialMenu && initialMenu.length) setItems(initialMenu.map(normalize));
  }, [initialMenu]); // eslint-disable-line

  useEffectM(() => { try { localStorage.setItem(draftKey, JSON.stringify(items)); } catch {} }, [items, draftKey]);

  // Deployment domain defaults to APP_URL (from /api/config), else this origin.
  const [domain, setDomain] = useStateM(() => {
    try { return localStorage.getItem("scanalytics_domain") || cfg.appUrl || window.location.origin; }
    catch { return cfg.appUrl || window.location.origin; }
  });
  useEffectM(() => { try { localStorage.setItem("scanalytics_domain", domain); } catch {} }, [domain]);

  // QR tracking sources are persisted in the qr_codes table via /api/qr.
  // Each row: { key (local), dbId, sourceId, label, prevSourceId, err }.
  const [sources, setSources] = useStateM([]);
  const [srcErr, setSrcErr] = useStateM("");
  const keyRef = useRefM(0);
  const nk = () => "k" + (++keyRef.current);

  useEffectM(() => {
    let alive = true;
    window.listQR().then((res) => {
      if (!alive) return;
      const rows = (res.codes || []).map((c) => ({ key: nk(), dbId: c.id, sourceId: c.source_id, label: c.label || "", prevSourceId: c.source_id, err: "" }));
      setSources(rows);
    }).catch(() => { /* not signed in / backend off -> start empty */ });
    return () => { alive = false; };
  }, [slug]);

  const persistSource = async (key) => {
    let row;
    setSources((p) => { row = p.find((s) => s.key === key); return p; });
    if (!row) return;
    const sourceId = slugify(row.sourceId);
    if (!sourceId) return;
    try {
      // If the source_id was renamed, drop the old row first.
      if (row.dbId && row.prevSourceId && row.prevSourceId !== sourceId) {
        await window.deleteQR(row.dbId);
      }
      const res = await window.createQR(sourceId, row.label);
      setSources((p) => p.map((s) => s.key === key ? { ...s, dbId: res.code.id, sourceId, prevSourceId: sourceId, err: "" } : s));
      setSrcErr("");
    } catch (e) {
      const msg = e.status === 402 ? (isES ? "Suscríbete para crear QR." : "Subscribe to create QR codes.")
        : e.status === 403 ? (e.body && e.body.error) || (isES ? "Límite del plan alcanzado." : "Plan limit reached.")
        : (isES ? "No se pudo guardar." : "Couldn't save.");
      setSources((p) => p.map((s) => s.key === key ? { ...s, err: msg } : s));
      setSrcErr(msg);
    }
  };

  const [published, setPublished] = useStateM(false);
  const [publishing, setPublishing] = useStateM(false);
  const [pubErr, setPubErr] = useStateM("");
  const [aiBusy, setAiBusy] = useStateM(false);
  const [aiPrompt, setAiPrompt] = useStateM(isES ? "Bar de tapas moderno en Madrid, 15 platos" : "Modern Madrid tapas bar, 15 items");
  const [aiError, setAiError] = useStateM("");
  const [previewOpen, setPreviewOpen] = useStateM(true);

  const cleanDomain = (domain || "").replace(/\/+$/, "");
  const baseUrl = `${cleanDomain}/m/${slug}`;
  const trackUrl = (srcId) => srcId ? `${baseUrl}?qr=${encodeURIComponent(srcId)}` : baseUrl;
  const shortUrl = baseUrl.replace(/^https?:\/\//, "");

  const allCats = useMemoM(() => {
    const extra = [...new Set(items.map((i) => i.category))].filter((c) => !CATEGORY_ORDER.includes(c));
    return [...CATEGORY_ORDER, ...extra];
  }, [items]);

  const byCat = useMemoM(() => {
    const m = {}; allCats.forEach((c) => m[c] = []);
    items.forEach((i) => { (m[i.category] = m[i.category] || []).push(i); });
    return m;
  }, [items, allCats]);

  const addItem = (cat) => setItems((p) => [...p, normalize({ category: cat, name: isES ? "Plato nuevo" : "New dish", price: 0, description: "" }, p.length)]);
  const updateItem = (id, patch) => setItems((p) => p.map((i) => i.id === id ? { ...i, ...patch } : i));
  const removeItem = (id) => setItems((p) => p.filter((i) => i.id !== id));
  const loadSample = () => setItems(SAMPLE_MENU.map(normalize));

  const addSource = () => {
    const n = sources.length + 1;
    const key = nk();
    const defId = "table-" + n;
    setSources((p) => [...p, { key, dbId: null, sourceId: defId, label: isES ? ("Mesa " + n) : ("Table " + n), prevSourceId: "", err: "" }]);
    setTimeout(() => persistSource(key), 0); // generate -> insert qr_codes row
  };
  const editSource = (key, patch) => setSources((p) => p.map((s) => s.key === key ? { ...s, ...patch } : s));
  const removeSource = async (key) => {
    let row;
    setSources((p) => { row = p.find((s) => s.key === key); return p.filter((s) => s.key !== key); });
    if (row && row.dbId) { try { await window.deleteQR(row.dbId); } catch {} }
  };

  const runAI = async () => {
    setAiBusy(true); setAiError("");
    try {
      const res = await window.generateMenuAI(aiPrompt, lang);
      const next = (res.items || []).slice(0, 20).map((i, idx) => normalize({
        category: CATEGORY_ORDER.includes(i.category) ? i.category : "Tapas",
        name: String(i.name || "Dish").slice(0, 60),
        price: Number(i.price) || 0,
        description: String(i.description || i.desc || "").slice(0, 120),
      }, idx));
      if (next.length) setItems(next);
      else setAiError(isES ? "No se generaron platos. Reformula el prompt." : "No items generated. Try rephrasing.");
    } catch (e) {
      if (e.status === 503) setAiError(isES ? "La generación con IA no está activada en este despliegue." : "AI generation isn't enabled on this deployment.");
      else setAiError(isES ? "No se pudo generar el menú. Inténtalo de nuevo." : "Could not generate menu. Try again.");
    } finally { setAiBusy(false); }
  };

  const publish = async () => {
    setPublishing(true); setPubErr("");
    try {
      const payload = items.map((it, i) => ({ category: it.category, name: it.name, price: it.price, description: it.description, position: i }));
      const res = await window.publishMenu(payload);
      const canon = (res.items || []).map(normalize);
      setItems(canon);
      onPublished && onPublished(res.items || []);
      setPublished(true); setTimeout(() => setPublished(false), 2800);
    } catch (e) {
      const msg = e.status === 402 ? (isES ? "Tu prueba ha terminado. Suscríbete para publicar." : "Your trial has ended. Subscribe to publish.")
        : e.status === 401 ? (isES ? "Inicia sesión de nuevo." : "Please sign in again.")
        : (e.message || (isES ? "No se pudo publicar." : "Publish failed."));
      setPubErr(msg);
    } finally { setPublishing(false); }
  };

  const totalItems = items.length;

  return (
    <div className="menu-layout">
      {/* LEFT: editor */}
      <div>
        {aiEnabled && (
        <div className="ai-card">
          <div style={{display:"flex", alignItems:"center", gap:10, marginBottom:12}}>
            <div className="ai-badge">✦</div>
            <div>
              <div style={{fontFamily:"var(--font-head)", fontSize:20, fontWeight:500, letterSpacing:-0.02}}>
                {isES ? "Generar menú con IA" : "Generate menu with AI"}
              </div>
              <div style={{fontSize:13, color:"var(--text-muted)", marginTop:2}}>
                {isES ? "Describe tu restaurante y escribimos un primer borrador." : "Describe your restaurant and we'll write a first draft."}
              </div>
            </div>
          </div>
          <div style={{display:"flex", gap:10, flexWrap:"wrap"}}>
            <input
              type="text" value={aiPrompt} onChange={(e) => setAiPrompt(e.target.value)}
              placeholder={isES ? "Ej: Pequeño bar de tapas, cocina del sur" : "e.g. Small tapas bar, southern cuisine"}
              style={{flex:1, minWidth:220, border:"1.5px solid var(--border)", borderRadius:10, padding:"11px 14px", fontSize:14, fontFamily:"var(--font-body)", background:"#fff"}}
            />
            <button className="btn btn-primary" style={{background:"var(--brand-purple)"}} onClick={runAI} disabled={aiBusy || !aiPrompt.trim()}>
              {aiBusy ? (isES ? "Generando…" : "Generating…") : (isES ? "Generar" : "Generate")}
            </button>
          </div>
          {aiError && <div style={{color:"var(--brand-red)", fontSize:13, marginTop:10}}>{aiError}</div>}
        </div>
        )}

        <div className="menu-editor-header">
          <div>
            <div className="panel-title">{isES ? "Editor de menú" : "Menu editor"}</div>
            <div className="panel-sub">{isES ? `${totalItems} platos · borrador autoguardado` : `${totalItems} items · draft autosaved`}</div>
          </div>
          {totalItems === 0 && (
            <button className="sim-btn" onClick={loadSample}>{isES ? "Cargar menú de ejemplo" : "Load sample menu"}</button>
          )}
        </div>

        {allCats.map((cat) => (
          <div key={cat} className="cat-block">
            <div className="cat-head">
              <div className="cat-name">{cat}</div>
              <button className="sim-btn" onClick={() => addItem(cat)}>+ {isES ? "Añadir plato" : "Add item"}</button>
            </div>
            {(byCat[cat] || []).length === 0 ? (
              <div className="cat-empty">{isES ? "Aún no hay platos en esta categoría." : "No items in this category yet."}</div>
            ) : (
              <div className="menu-item-list">
                {byCat[cat].map((it) => (
                  <div key={it.id} className="menu-item-row">
                    <input className="mi-name" type="text" value={it.name} onChange={(e) => updateItem(it.id, { name: e.target.value })} placeholder={isES ? "Nombre del plato" : "Dish name"} />
                    <input className="mi-desc" type="text" value={it.description} onChange={(e) => updateItem(it.id, { description: e.target.value })} placeholder={isES ? "Descripción corta" : "Short description"} />
                    <div className="mi-price-wrap">
                      <span className="mi-euro">€</span>
                      <input className="mi-price" type="number" step="0.50" value={it.price} onChange={(e) => updateItem(it.id, { price: Number(e.target.value) })} />
                    </div>
                    <button className="mi-remove" onClick={() => removeItem(it.id)} title={isES ? "Eliminar" : "Remove"}>×</button>
                  </div>
                ))}
              </div>
            )}
          </div>
        ))}
      </div>

      {/* RIGHT: QR + sources + preview */}
      <div className="menu-sidebar">
        <div className="qr-card">
          <div className="qr-card-label">{isES ? "Tu QR del menú" : "Your menu QR"}</div>
          <div className="qr-frame"><QRImage text={baseUrl} size={208} /></div>
          <div className="qr-url">{shortUrl}</div>

          <div className="domain-field">
            <label>{isES ? "Dominio de despliegue" : "Deployment domain"}</label>
            <input type="text" value={domain} onChange={(e) => setDomain(e.target.value)} placeholder="https://yourdomain.com" />
          </div>

          <div style={{display:"flex", flexDirection:"column", gap:8, marginTop:14}}>
            <button className="btn btn-primary" style={{background:"var(--brand-purple)", justifyContent:"center"}} onClick={publish} disabled={publishing || totalItems === 0}>
              {publishing ? (isES ? "Publicando…" : "Publishing…") : published ? (isES ? "¡Publicado!" : "Published!") : (isES ? "Publicar menú" : "Publish menu")}
            </button>
            <button className="btn btn-secondary" style={{borderColor:"var(--brand-purple)", color:"var(--brand-purple)", justifyContent:"center"}} onClick={() => downloadQR(baseUrl, `${slug}-menu-qr.png`)}>
              {isES ? "Descargar QR (PNG)" : "Download QR (PNG)"}
            </button>
          </div>
          {pubErr && <div style={{color:"var(--brand-red)", fontSize:12.5, marginTop:10}}>{pubErr}</div>}
          <div className="qr-note">
            {isES
              ? "Publicar guarda tu menú y lo sirve en el enlace de arriba. Imprime el QR para tus mesas."
              : "Publishing saves your menu and serves it at the link above. Print the QR for your tables."}
          </div>
        </div>

        {/* Tracking sources */}
        <div className="src-card">
          <div className="src-head">
            <div>
              <div className="qr-card-label" style={{marginBottom:2}}>{isES ? "Fuentes de seguimiento" : "Tracking sources"}</div>
              <div style={{fontSize:12.5, color:"var(--text-muted)"}}>{isES ? "Un QR por ubicación — sabrás de dónde viene cada escaneo." : "One QR per spot — know where every scan came from."}</div>
            </div>
            <button className="sim-btn" onClick={addSource}>+ {isES ? "Añadir" : "Add"}</button>
          </div>
          <div className="src-list">
            {sources.map((s) => (
              <div key={s.key} className="src-row">
                <div className="src-qr"><QRImage text={trackUrl(s.sourceId)} size={72} /></div>
                <div className="src-meta">
                  <input className="src-input" type="text" value={s.label}
                    onChange={(e) => editSource(s.key, { label: e.target.value })}
                    onBlur={() => persistSource(s.key)}
                    placeholder={isES ? "Etiqueta (ej: Mesa 4)" : "Label (e.g. Table 4)"} />
                  <div className="src-id-row">
                    <span className="src-id-prefix">?qr=</span>
                    <input className="src-id-input" type="text" value={s.sourceId}
                      onChange={(e) => editSource(s.key, { sourceId: e.target.value.replace(/\s+/g, '-').toLowerCase() })}
                      onBlur={() => persistSource(s.key)}
                      placeholder="table-04" />
                  </div>
                  <div className="src-actions">
                    <button className="src-dl" onClick={() => downloadQR(trackUrl(s.sourceId), `${slug}-${slugify(s.sourceId) || "source"}-qr.png`)}>{isES ? "Descargar PNG" : "Download PNG"}</button>
                    <button className="src-rm" onClick={() => removeSource(s.key)}>{isES ? "Quitar" : "Remove"}</button>
                  </div>
                  {s.err && <div style={{color:"var(--brand-red)", fontSize:11.5, marginTop:5}}>{s.err}</div>}
                </div>
              </div>
            ))}
            {sources.length === 0 && <div className="cat-empty">{isES ? "Sin fuentes. Añade una para generar tu primer QR." : "No sources yet. Add one to generate your first QR."}</div>}
          </div>
        </div>

        <div className="preview-card">
          <button className="preview-toggle" onClick={() => setPreviewOpen(!previewOpen)}>
            <span>{isES ? "Vista previa del menú" : "Menu preview"}</span>
            <span style={{transform: previewOpen ? "rotate(180deg)" : "none", transition: "transform 160ms"}}>⌄</span>
          </button>
          {previewOpen && (
            <div className="phone-frame">
              <div className="phone-notch"/>
              <div className="phone-screen">
                <div className="menu-hero">
                  <div className="menu-hero-name">{restaurantName}</div>
                  <div className="menu-hero-tag">{isES ? "Carta · hoy" : "Menu · today"}</div>
                </div>
                {allCats.map((cat) => {
                  const list = byCat[cat] || [];
                  if (list.length === 0) return null;
                  return (
                    <div key={cat} className="menu-sec">
                      <div className="menu-sec-head">{cat}</div>
                      {list.map((it) => (
                        <div key={it.id} className="menu-prev-item">
                          <div className="menu-prev-left">
                            <div className="menu-prev-name">{it.name || "—"}</div>
                            {it.description && <div className="menu-prev-desc">{it.description}</div>}
                          </div>
                          <div className="menu-prev-price">€{Number(it.price).toFixed(2)}</div>
                        </div>
                      ))}
                    </div>
                  );
                })}
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { MenuTab });
