// CustomCalc — let the user build their own simple calculator.
// Variables + formula + optional bands → saved in localStorage.

const { useState: uxS, useMemo: uxM, useEffect: uxE } = React;

const CC_KEY = 'cyna_custom_calcs_v1';

const newCalc = () => ({
  id: 'c_' + Date.now().toString(36),
  nombre: 'Mi calculadora',
  descripcion: '',
  unidad: '',
  formula: 'peso * 0.5',
  variables: [
    { id: 'peso', label: 'Peso', unit: 'kg', value: 70 },
  ],
  bandas: [
    // { hasta: Infinity, label: 'Normal', color: '#6E8A4C' }
  ],
});

function loadCalcs() {
  try {
    const raw = localStorage.getItem(CC_KEY);
    if (raw) return JSON.parse(raw);
  } catch {}
  return [
    {
      id: 'demo1',
      nombre: 'Dosis por kilo',
      descripcion: 'Dosis total a administrar según peso y dosis por kg.',
      unidad: 'mg',
      formula: 'peso * dosis',
      variables: [
        { id: 'peso', label: 'Peso', unit: 'kg', value: 70 },
        { id: 'dosis', label: 'Dosis por kg', unit: 'mg/kg', value: 10 },
      ],
      bandas: [],
    },
  ];
}
function saveCalcs(arr) {
  try { localStorage.setItem(CC_KEY, JSON.stringify(arr)); } catch {}
}

// Safe-ish evaluator: allow only digits, operators, parens, dots, spaces and known variable ids.
function compileFormula(formula, varIds) {
  const idSet = new Set(varIds);
  // Tokenize: numbers, identifiers, operators, parens.
  const tokens = formula.match(/[A-Za-z_][A-Za-z0-9_]*|\d+\.?\d*|[+\-*/().%,]|\*\*|\s+/g) || [];
  for (const t of tokens) {
    if (/^\s+$/.test(t)) continue;
    if (/^[A-Za-z_]/.test(t)) {
      if (!idSet.has(t) && !['Math', 'min', 'max', 'sqrt', 'pow', 'abs', 'round', 'floor', 'ceil', 'log'].includes(t)) {
        return { error: `Variable desconocida: ${t}` };
      }
    } else if (!/^(\d+\.?\d*|[+\-*/().%,]|\*\*)$/.test(t)) {
      return { error: `Token no permitido: ${t}` };
    }
  }
  try {
    // eslint-disable-next-line no-new-func
    const fn = new Function(...varIds, 'Math', 'min', 'max', 'sqrt', 'pow', 'abs', 'round', 'floor', 'ceil', 'log',
      `"use strict"; return (${formula});`);
    return { fn };
  } catch (e) {
    return { error: 'Sintaxis inválida' };
  }
}

function evalCalc(calc) {
  const ids = calc.variables.map(v => v.id);
  const { fn, error } = compileFormula(calc.formula, ids);
  if (error) return { error };
  try {
    const args = calc.variables.map(v => +v.value || 0);
    const r = fn(...args, Math, Math.min, Math.max, Math.sqrt, Math.pow, Math.abs, Math.round, Math.floor, Math.ceil, Math.log);
    return { value: r };
  } catch (e) {
    return { error: 'No se pudo calcular' };
  }
}

function slug(s) {
  return s.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
    .replace(/[^a-z0-9_]+/g, '_').replace(/^_+|_+$/g, '') || 'var';
}

function CustomCalc() {
  const [list, setList] = uxS(loadCalcs);
  const [activeId, setActiveId] = uxS(() => loadCalcs()[0]?.id || null);
  const [editing, setEditing] = uxS(false);

  uxE(() => { saveCalcs(list); }, [list]);

  const active = list.find(c => c.id === activeId) || list[0];

  const update = (patch) => setList(list.map(c => c.id === active.id ? { ...c, ...patch } : c));
  const remove = (id) => {
    if (!confirm('¿Eliminar esta calculadora?')) return;
    const next = list.filter(c => c.id !== id);
    setList(next);
    if (next.length) setActiveId(next[0].id);
  };
  const create = () => {
    const c = newCalc();
    const next = [...list, c];
    setList(next);
    setActiveId(c.id);
    setEditing(true);
  };

  if (!active) {
    return (
      <div className="calc-card">
        <div className="cc-empty">
          <h3>Aún no tienes calculadoras</h3>
          <p>Crea la primera con tus propias variables y fórmula.</p>
          <button className="btn-primary" onClick={create}>Crear calculadora</button>
        </div>
      </div>
    );
  }

  return (
    <div className="cc-layout">
      <aside className="cc-side">
        <div className="cc-side-head">
          <h4>Mis fórmulas</h4>
          <button className="btn-secondary small" onClick={create}>+ Nueva</button>
        </div>
        <ul>
          {list.map(c => (
            <li key={c.id}>
              <button
                className={'cc-side-btn ' + (activeId === c.id ? 'on' : '')}
                onClick={() => { setActiveId(c.id); setEditing(false); }}
              >
                <span>{c.nombre || 'Sin nombre'}</span>
                <small className="mono">{c.variables.length} variable{c.variables.length === 1 ? '' : 's'}</small>
              </button>
            </li>
          ))}
        </ul>
        <div className="calc-tip">
          <div className="calc-tip-eyebrow">Cómo funciona</div>
          <p>
            Define las variables que quieres usar (p. ej. <span className="mono">peso</span>,
            <span className="mono"> dosis</span>) y escribe una fórmula con esos nombres.
            Soporta <span className="mono">+ − × ÷ ( ) **</span> y funciones de
            <span className="mono"> Math</span>.
          </p>
        </div>
      </aside>

      <div className="cc-main">
        {editing
          ? <CustomCalcEditor calc={active} onSave={(c) => { update(c); setEditing(false); }} onCancel={() => setEditing(false)} onDelete={() => remove(active.id)}/>
          : <CustomCalcRun calc={active} onEdit={() => setEditing(true)} onChange={update}/>
        }
      </div>
    </div>
  );
}

// ─── RUN view (use the calculator) ─────────────────────────
function CustomCalcRun({ calc, onEdit, onChange }) {
  const { value, error } = uxM(() => evalCalc(calc), [calc]);
  const klass = !error && isFinite(value) ? (calc.bandas || []).find(b => value <= (b.hasta ?? Infinity)) : null;

  const setVar = (i, patch) => {
    const next = calc.variables.map((v, j) => j === i ? { ...v, ...patch } : v);
    onChange({ variables: next });
  };

  return (
    <div className="calc-card">
      <div className="calc-head" style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 14, flexWrap: 'wrap' }}>
        <div>
          <h3>{calc.nombre || 'Calculadora'}</h3>
          {calc.descripcion && <p>{calc.descripcion}</p>}
          <p className="mono small muted" style={{ marginTop: 4 }}>
            Fórmula: <span style={{ color: 'var(--cinnamon-700)' }}>{calc.formula}</span>
          </p>
        </div>
        <button className="btn-secondary small" onClick={onEdit}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4 12.5-12.5z"/></svg>
          Editar
        </button>
      </div>

      <div className="calc-fields">
        {calc.variables.map((v, i) => (
          <div key={v.id} className="calc-field">
            <label>{v.label || v.id} {v.unit && <span style={{ color: 'var(--fg-muted)', fontWeight: 600 }}>· {v.unit}</span>}</label>
            <div className="calc-input-row">
              <input
                type="number"
                value={v.value}
                onChange={e => setVar(i, { value: e.target.value === '' ? '' : +e.target.value })}
                step="any"
              />
              {v.unit && <span>{v.unit}</span>}
            </div>
          </div>
        ))}
      </div>

      <div className="calc-result">
        {error ? (
          <div className="cc-error">
            <strong>⚠️ Error en la fórmula:</strong> {error}
            <div className="muted small" style={{ marginTop: 6 }}>Revisa los nombres de tus variables y operadores.</div>
          </div>
        ) : (
          <>
            <div className="calc-result-row main">
              <span className="lbl">Resultado</span>
              <span className="val mono">
                {isFinite(value) ? (Math.abs(value) < 0.01 || Math.abs(value) >= 10000 ? (+value).toExponential(3) : (+value).toFixed(2)) : '—'}
                {calc.unidad && <small style={{ fontSize: 16, marginLeft: 6, color: 'var(--cinnamon-500)' }}> {calc.unidad}</small>}
              </span>
            </div>
            {klass && (
              <div className="imc-classify" style={{ background: klass.tint || 'var(--cream-100)', borderLeft: `4px solid ${klass.color || 'var(--cinnamon-400)'}` }}>
                <div className="imc-classify-eyebrow">Clasificación</div>
                <div className="imc-classify-label" style={{ color: klass.color }}>{klass.label}</div>
              </div>
            )}
          </>
        )}
      </div>
    </div>
  );
}

// ─── EDIT view (configure variables + formula + bands) ─────
function CustomCalcEditor({ calc, onSave, onCancel, onDelete }) {
  const [draft, setDraft] = uxS(calc);

  const upd = (patch) => setDraft(d => ({ ...d, ...patch }));

  const updVar = (i, patch) => upd({ variables: draft.variables.map((v, j) => j === i ? { ...v, ...patch } : v) });
  const addVar = () => {
    let base = 'var', n = 1;
    while (draft.variables.find(v => v.id === base + n)) n++;
    upd({ variables: [...draft.variables, { id: base + n, label: 'Variable ' + n, unit: '', value: 0 }] });
  };
  const rmVar = (i) => upd({ variables: draft.variables.filter((_, j) => j !== i) });

  const addBand = () => upd({ bandas: [...(draft.bandas || []), { hasta: 0, label: 'Banda', color: '#B97D3D', tint: '#F2E1D2' }] });
  const updBand = (i, patch) => upd({ bandas: draft.bandas.map((b, j) => j === i ? { ...b, ...patch } : b) });
  const rmBand = (i) => upd({ bandas: draft.bandas.filter((_, j) => j !== i) });

  const test = uxM(() => evalCalc(draft), [draft]);

  return (
    <div className="calc-card">
      <div className="calc-head">
        <h3>Editar calculadora</h3>
        <p>Configura los campos que el usuario verá y la fórmula a aplicar.</p>
      </div>

      <div className="cc-section">
        <div className="patient-section-eyebrow">Información general</div>
        <div className="calc-fields">
          <div className="calc-field">
            <label>Nombre</label>
            <div className="calc-input-row"><input type="text" value={draft.nombre} onChange={e => upd({ nombre: e.target.value })}/></div>
          </div>
          <div className="calc-field">
            <label>Unidad del resultado</label>
            <div className="calc-input-row"><input type="text" value={draft.unidad} onChange={e => upd({ unidad: e.target.value })} placeholder="ej. ml/h, mg, %"/></div>
          </div>
          <div className="calc-field full">
            <label>Descripción / contexto clínico</label>
            <div className="calc-input-row"><input type="text" value={draft.descripcion} onChange={e => upd({ descripcion: e.target.value })} placeholder="Para qué sirve esta fórmula"/></div>
          </div>
        </div>
      </div>

      <div className="cc-section">
        <div className="cc-section-head">
          <div className="patient-section-eyebrow">Variables</div>
          <button className="btn-secondary small" onClick={addVar}>+ Variable</button>
        </div>
        <div className="cc-vars">
          {draft.variables.map((v, i) => (
            <div key={i} className="cc-var">
              <div className="cc-var-fields">
                <div className="cc-var-field">
                  <label>Nombre visible</label>
                  <input type="text" value={v.label} onChange={e => updVar(i, { label: e.target.value })}/>
                </div>
                <div className="cc-var-field">
                  <label>Identificador en fórmula</label>
                  <input
                    type="text"
                    value={v.id}
                    onChange={e => updVar(i, { id: slug(e.target.value) })}
                    className="mono"
                  />
                </div>
                <div className="cc-var-field">
                  <label>Unidad</label>
                  <input type="text" value={v.unit || ''} onChange={e => updVar(i, { unit: e.target.value })} placeholder="kg, ml, °C…"/>
                </div>
                <div className="cc-var-field">
                  <label>Valor predeterminado</label>
                  <input type="number" value={v.value} onChange={e => updVar(i, { value: +e.target.value || 0 })} step="any"/>
                </div>
              </div>
              <button className="cc-var-rm" onClick={() => rmVar(i)} aria-label="Quitar">
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M18 6L6 18M6 6l12 12"/></svg>
              </button>
            </div>
          ))}
        </div>
      </div>

      <div className="cc-section">
        <div className="patient-section-eyebrow">Fórmula</div>
        <div className="cc-formula">
          <textarea
            value={draft.formula}
            onChange={e => upd({ formula: e.target.value })}
            rows={3}
            spellCheck={false}
            placeholder="ej. peso * dosis"
          />
          <div className="cc-formula-help">
            Variables disponibles: {draft.variables.map(v => <span key={v.id} className="mono cc-chip">{v.id}</span>)}
            <br/>
            Operadores: <span className="mono">+  −  *  /  **  (  )</span> · Funciones: <span className="mono">sqrt, pow, abs, round, floor, ceil, log, min, max</span>
          </div>
          <div className="cc-test">
            {test.error
              ? <span className="cc-test-bad">⚠️ {test.error}</span>
              : <span className="cc-test-ok">✓ Resultado de prueba: <strong className="mono">{isFinite(test.value) ? (+test.value).toFixed(3) : '—'}</strong> {draft.unidad}</span>
            }
          </div>
        </div>
      </div>

      <div className="cc-section">
        <div className="cc-section-head">
          <div className="patient-section-eyebrow">Bandas / Clasificación (opcional)</div>
          <button className="btn-secondary small" onClick={addBand}>+ Banda</button>
        </div>
        {(draft.bandas || []).length === 0 && (
          <p className="muted small">Sin bandas. Añade rangos para clasificar el resultado (p. ej. "Normal: hasta 24.9").</p>
        )}
        <div className="cc-bands">
          {(draft.bandas || []).map((b, i) => (
            <div key={i} className="cc-band">
              <div className="cc-band-fields">
                <div className="cc-var-field">
                  <label>Hasta (≤)</label>
                  <input type="number" value={b.hasta} onChange={e => updBand(i, { hasta: +e.target.value })} step="any"/>
                </div>
                <div className="cc-var-field flex">
                  <label>Etiqueta</label>
                  <input type="text" value={b.label} onChange={e => updBand(i, { label: e.target.value })}/>
                </div>
                <div className="cc-var-field">
                  <label>Color</label>
                  <input type="color" value={b.color || '#B97D3D'} onChange={e => updBand(i, { color: e.target.value, tint: e.target.value + '30' })} className="cc-color"/>
                </div>
              </div>
              <button className="cc-var-rm" onClick={() => rmBand(i)} aria-label="Quitar">
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M18 6L6 18M6 6l12 12"/></svg>
              </button>
            </div>
          ))}
        </div>
      </div>

      <div className="cc-actions">
        <button className="btn-secondary" onClick={onDelete} style={{ color: 'var(--wine-700)', borderColor: 'var(--wine-100)' }}>Eliminar</button>
        <div style={{ flex: 1 }}/>
        <button className="btn-secondary" onClick={onCancel}>Cancelar</button>
        <button className="btn-primary" onClick={() => onSave(draft)} disabled={!!test.error}>Guardar</button>
      </div>
    </div>
  );
}

window.CustomCalc = CustomCalc;
