// ─────────────────────────────────────────────────────
// GUT-70 (F4.2) — ValidacionPanel: plantilla de validación digital +
// comparativa de medidas presupuesto vs. fabricación por hueco/producto.
//
// Flujo guiado en 4 pasos (sin tabla ancha, una tarjeta por hueco):
//   1. Generar huecos desde el presupuesto (o a mano).
//   2. Introducir la medida real de fabricación (ancho a pared / suelo-techo).
//   3. Validar cada hueco (bloquea la fila; la medición pasa a 'validado').
//   4. Generar la revisión del presupuesto con las medidas reales.
//
// La medición SOLO modifica medidas: los atributos (RAL, hojas, apertura,
// guía, cerradura) se muestran de solo lectura — se cambian en el presupuesto.
//
// Lo consume MedicionesPanel (F4.1) vía window.ValidacionPanel.
// expedienteId = pedidos.id.
// API REST bajo /api/expedientes/:pedidoId/validaciones (GUT-70).
// ─────────────────────────────────────────────────────

const VALIDACION_CAMPOS_VACIOS = {
  descripcion: '', ral: '', n_hojas: '', apertura: '', guia: '', cerradura: '',
  ancho_mm: '', alto_mm: '', observacion: '', linea_presupuesto_id: '',
};

function fmtFechaValidacion(val) {
  if (!val) return '';
  const s = String(val).slice(0, 10);
  if (s.includes('/')) return s; // ya viene DD/MM/YYYY del backend
  const [y, m, d] = s.split('-');
  return (y && m && d) ? `${d}/${m}/${y}` : s;
}

function fmtMedida(ancho, alto) {
  const a = ancho == null || ancho === '' ? null : Number(ancho);
  const h = alto == null || alto === '' ? null : Number(alto);
  if (a == null && h == null) return '—';
  return `${a == null ? '—' : a} × ${h == null ? '—' : h}`;
}

// ── Indicador de pasos del proceso ──
const PasoMedicion = ({ num, label, sub, done, active }) => (
  <div style={{display:'flex',alignItems:'center',gap:8,opacity: done || active ? 1 : .5}}>
    <span style={{
      width:24, height:24, borderRadius:'50%', flexShrink:0,
      display:'inline-flex', alignItems:'center', justifyContent:'center',
      fontSize:12, fontWeight:700,
      background: done ? 'var(--ok)' : active ? 'var(--accent-ink)' : 'var(--surface-2)',
      color: done || active ? '#fff' : 'var(--ink-2)',
      border: done || active ? 'none' : '1px solid var(--line-2)',
    }}>
      {done ? <Icon name="check" size={13}/> : num}
    </span>
    <div style={{lineHeight:1.25}}>
      <div style={{fontSize:12.5, fontWeight: active ? 700 : 500}}>{label}</div>
      {sub && <div className="muted" style={{fontSize:11}}>{sub}</div>}
    </div>
  </div>
);

const PasosMedicion = ({ pasos }) => {
  const activo = pasos.findIndex(p => !p.done);
  return (
    <div style={{display:'flex',alignItems:'center',gap:10,flexWrap:'wrap',
      padding:'10px 14px',border:'1px solid var(--line)',borderRadius:10,marginBottom:14}}>
      {pasos.map((p, i) => (
        <React.Fragment key={i}>
          {i > 0 && <span style={{flex:'0 1 28px',minWidth:12,height:1,background:'var(--line-2)'}}/>}
          <PasoMedicion num={i + 1} label={p.label} sub={p.sub} done={p.done} active={i === activo}/>
        </React.Fragment>
      ))}
    </div>
  );
};

// ── Tarjeta por hueco ──
const ValidacionCard = ({ pedidoId, linea, onChanged, onToast }) => {
  const [draft, setDraft] = React.useState(linea);
  const [busy, setBusy] = React.useState(false);
  React.useEffect(() => { setDraft(linea); }, [linea]);

  const toast = (m, e) => onToast && onToast(m, e);
  const set = (k, val) => setDraft(d => ({ ...d, [k]: val }));
  const bloqueado = !!linea.bloqueado;

  const dirty = ['descripcion', 'ancho_mm', 'alto_mm', 'observacion']
    .some(k => String(draft[k] ?? '') !== String(linea[k] ?? ''));

  // La medición solo edita medidas/descripción/observación; los atributos
  // viajan sin cambios para no pisarlos en el backend.
  const guardar = async () => {
    await API.put(`/api/expedientes/${pedidoId}/validaciones/${linea.id}`, {
      descripcion: draft.descripcion,
      ral: linea.ral,
      n_hojas: linea.n_hojas === '' ? null : linea.n_hojas,
      apertura: linea.apertura,
      guia: linea.guia,
      cerradura: linea.cerradura,
      ancho_mm: draft.ancho_mm === '' ? null : draft.ancho_mm,
      alto_mm: draft.alto_mm === '' ? null : draft.alto_mm,
      observacion: draft.observacion,
    });
  };

  const onGuardar = async () => {
    setBusy(true);
    try {
      await guardar();
      toast('Hueco guardado ✓');
      onChanged && onChanged();
    } catch (e) { toast(e.message || 'Error al guardar', true); }
    finally { setBusy(false); }
  };

  // Validar guarda primero el borrador: el operario no debe perder lo
  // tecleado por pulsar Validar sin haber guardado antes.
  const validar = async () => {
    setBusy(true);
    try {
      if (dirty) await guardar();
      await API.post(`/api/expedientes/${pedidoId}/validaciones/${linea.id}/validar`);
      toast('Hueco validado ✓');
      onChanged && onChanged();
    } catch (e) { toast(e.message || 'Error al validar', true); }
    finally { setBusy(false); }
  };

  const desbloquear = async () => {
    setBusy(true);
    try {
      await API.post(`/api/expedientes/${pedidoId}/validaciones/${linea.id}/desbloquear`);
      toast('Hueco desbloqueado ✓');
      onChanged && onChanged();
    } catch (e) { toast(e.message || 'Error al desbloquear', true); }
    finally { setBusy(false); }
  };

  const borrar = async () => {
    if (!confirm('¿Eliminar este hueco?')) return;
    setBusy(true);
    try {
      await API.del(`/api/expedientes/${pedidoId}/validaciones/${linea.id}`);
      onChanged && onChanged();
    } catch (e) { toast(e.message || 'Error al eliminar', true); }
    finally { setBusy(false); }
  };

  const atributos = [
    linea.ral && `RAL ${linea.ral}`,
    linea.n_hojas != null && linea.n_hojas !== '' && `${linea.n_hojas} hojas`,
    linea.apertura && `Apertura: ${linea.apertura}`,
    linea.guia && `Guía: ${linea.guia}`,
    linea.cerradura && `Cerradura: ${linea.cerradura}`,
  ].filter(Boolean);

  const dif = (a, b) => a != null && a !== '' && b != null && Number(a) !== Number(b);
  const difiere = !!linea.linea_presupuesto_id &&
    (dif(draft.ancho_mm, linea.ancho_presupuesto) || dif(draft.alto_mm, linea.alto_presupuesto));

  return (
    <div style={{
      border:'1px solid', borderColor: bloqueado ? 'var(--ok)' : 'var(--line)',
      borderRadius:10, padding:14, display:'flex', flexDirection:'column', gap:10,
    }}>
      <div style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start',gap:8}}>
        {bloqueado ? (
          <div style={{fontSize:13.5,fontWeight:600}}>{linea.descripcion || 'Hueco'}</div>
        ) : (
          <input
            value={draft.descripcion || ''}
            onChange={e=>set('descripcion', e.target.value)}
            placeholder="Hueco / producto"
            style={{fontWeight:600,flex:1,minWidth:0}}
          />
        )}
        {bloqueado
          ? <span className="pill ok" style={{flexShrink:0}}><span className="d"/>Validado</span>
          : <span className="pill warn" style={{flexShrink:0}}><span className="d"/>Pendiente</span>}
      </div>

      {atributos.length > 0 && (
        <div className="muted tip" style={{fontSize:11.5}}
          data-tip="Atributos del presupuesto (solo lectura): se cambian en el presupuesto, no en la medición">
          {atributos.join(' · ')}
        </div>
      )}

      <div style={{display:'flex',alignItems:'flex-end',gap:14,flexWrap:'wrap'}}>
        <div>
          <div className="muted" style={{fontSize:11,marginBottom:3}}>Medida presupuesto (en cliente)</div>
          <div style={{fontSize:15,fontWeight:600,whiteSpace:'nowrap'}}>
            {fmtMedida(linea.ancho_presupuesto, linea.alto_presupuesto)}
            {(linea.ancho_presupuesto != null || linea.alto_presupuesto != null) && <span className="muted" style={{fontSize:11,fontWeight:400}}> mm</span>}
          </div>
        </div>
        <div className="muted" style={{paddingBottom:6,fontSize:14}}>→</div>
        <div>
          <div className="muted" style={{fontSize:11,marginBottom:3}}>Medida real de fabricación</div>
          <div style={{display:'flex',alignItems:'center',gap:6}}>
            <input
              type="number" value={draft.ancho_mm ?? ''} disabled={bloqueado}
              onChange={e=>set('ancho_mm', e.target.value)}
              placeholder="ancho a pared" style={{width:110,fontSize:14,padding:'7px 8px'}}
            />
            <span className="muted">×</span>
            <input
              type="number" value={draft.alto_mm ?? ''} disabled={bloqueado}
              onChange={e=>set('alto_mm', e.target.value)}
              placeholder="suelo-techo" style={{width:110,fontSize:14,padding:'7px 8px'}}
            />
            <span className="muted" style={{fontSize:11}}>mm</span>
          </div>
        </div>
      </div>

      {difiere && !bloqueado && (
        <div style={{fontSize:11.5,color:'var(--warn)'}}>
          La medida real difiere del presupuesto: al final del proceso genera la revisión (paso 4).
        </div>
      )}

      {!bloqueado ? (
        <input
          value={draft.observacion || ''}
          onChange={e=>set('observacion', e.target.value)}
          placeholder="Observación (opcional)"
          style={{fontSize:12}}
        />
      ) : linea.observacion ? (
        <div className="muted" style={{fontSize:12}}>Obs.: {linea.observacion}</div>
      ) : null}

      <div style={{display:'flex',alignItems:'center',gap:8,marginTop:'auto',flexWrap:'wrap'}}>
        {!bloqueado ? (
          <React.Fragment>
            <button className={dirty ? 'btn' : 'btn ghost'} onClick={onGuardar} disabled={busy || !dirty}>
              Guardar
            </button>
            <button className="btn primary" onClick={validar} disabled={busy}>
              <Icon name="check" size={13}/> Validar hueco
            </button>
          </React.Fragment>
        ) : (
          <React.Fragment>
            <span className="muted" style={{fontSize:11.5}}>
              {linea.validado_por_nombre ? `Por ${linea.validado_por_nombre}` : ''}
              {linea.validado_at ? ` · ${fmtFechaValidacion(linea.validado_at)}` : ''}
            </span>
            <button className="btn ghost" onClick={desbloquear} disabled={busy}>Desbloquear</button>
          </React.Fragment>
        )}
        <button className="btn ghost sm" style={{color:'var(--err)',marginLeft:'auto'}} onClick={borrar} disabled={busy}>
          <Icon name="trash" size={12}/> Eliminar
        </button>
      </div>
    </div>
  );
};

// ── Formulario de alta de hueco ──
const ValidacionAlta = ({ pedidoId, onAdded, onCancel, onToast }) => {
  const [draft, setDraft] = React.useState({ ...VALIDACION_CAMPOS_VACIOS });
  const [busy, setBusy] = React.useState(false);
  const set = (k, val) => setDraft(d => ({ ...d, [k]: val }));

  const guardar = async () => {
    if (!String(draft.descripcion || '').trim()) { onToast && onToast('Indica la descripción del hueco', true); return; }
    setBusy(true);
    try {
      await API.post(`/api/expedientes/${pedidoId}/validaciones`, {
        descripcion: draft.descripcion,
        ral: draft.ral,
        n_hojas: draft.n_hojas === '' ? null : draft.n_hojas,
        apertura: draft.apertura,
        guia: draft.guia,
        cerradura: draft.cerradura,
        ancho_mm: draft.ancho_mm === '' ? null : draft.ancho_mm,
        alto_mm: draft.alto_mm === '' ? null : draft.alto_mm,
        observacion: draft.observacion,
      });
      onAdded && onAdded();
    } catch (e) { onToast && onToast(e.message || 'Error al crear hueco', true); }
    finally { setBusy(false); }
  };

  return (
    <div style={{padding:12,marginBottom:12,border:'1px solid var(--line)',borderRadius:8}}>
      <div className="section-title" style={{marginTop:0}}>Nuevo hueco</div>
      <div className="fields-grid" style={{alignItems:'end'}}>
        <div className="field"><label>Descripción *</label><input value={draft.descripcion} onChange={e=>set('descripcion', e.target.value)}/></div>
        <div className="field"><label>Ancho (fabricación)</label><input type="number" value={draft.ancho_mm} onChange={e=>set('ancho_mm', e.target.value)} placeholder="ancho a pared"/></div>
        <div className="field"><label>Alto (fabricación)</label><input type="number" value={draft.alto_mm} onChange={e=>set('alto_mm', e.target.value)} placeholder="suelo-techo"/></div>
        <div className="field"><label>RAL</label><input value={draft.ral} onChange={e=>set('ral', e.target.value)}/></div>
        <div className="field"><label>Nº hojas</label><input type="number" value={draft.n_hojas} onChange={e=>set('n_hojas', e.target.value)}/></div>
        <div className="field"><label>Apertura</label><input value={draft.apertura} onChange={e=>set('apertura', e.target.value)}/></div>
        <div className="field"><label>Guía</label><input value={draft.guia} onChange={e=>set('guia', e.target.value)}/></div>
        <div className="field"><label>Cerradura</label><input value={draft.cerradura} onChange={e=>set('cerradura', e.target.value)}/></div>
        <div className="field" style={{gridColumn:'1 / -1'}}><label>Observación</label><input value={draft.observacion} onChange={e=>set('observacion', e.target.value)}/></div>
        <div className="field" style={{display:'flex',gap:6}}>
          <button className="btn primary" onClick={guardar} disabled={busy}>{busy ? 'Guardando…' : 'Añadir'}</button>
          <button className="btn ghost" onClick={onCancel}>Cancelar</button>
        </div>
      </div>
    </div>
  );
};

const ValidacionPanel = ({ expedienteId, onToast }) => {
  const [data, setData] = React.useState(null);
  const [adding, setAdding] = React.useState(false);
  const [seeding, setSeeding] = React.useState(false);
  const [revisando, setRevisando] = React.useState(false);

  const load = React.useCallback(() => {
    if (!expedienteId) return;
    API.get(`/api/expedientes/${expedienteId}/validaciones`)
      .then(d => setData(d))
      .catch(e => { setData({ presupuesto_id: null, lineas: [] }); onToast && onToast(e.message || 'Error al cargar validaciones', true); });
  }, [expedienteId]);

  React.useEffect(() => { load(); }, [load]);

  const generarDesdePresupuesto = async () => {
    setSeeding(true);
    try {
      await API.post(`/api/expedientes/${expedienteId}/validaciones/seed`);
      onToast && onToast('Huecos generados desde presupuesto ✓');
      load();
    } catch (e) { onToast && onToast(e.message || 'Error al generar desde presupuesto', true); }
    finally { setSeeding(false); }
  };

  // Tras la medición, aplica las medidas de fabricación al presupuesto
  // (aunque esté aceptado): se archiva la versión actual y el presupuesto
  // vuelve a Borrador con Rev. N para hacer llegar la variación al cliente.
  const generarRevision = async () => {
    if (!confirm('Se archivará la versión actual del presupuesto, se aplicarán las medidas de fabricación a sus líneas y volverá a Borrador como Rev. nueva para ajustar la variación y reenviarla al cliente. ¿Continuar?')) return;
    setRevisando(true);
    try {
      const r = await API.post(`/api/presupuestos/${data.presupuesto_id}/revision-medicion`, { pedido_id: expedienteId });
      onToast && onToast(`Presupuesto revisado (Rev. ${r.revision}, ${r.medidas_aplicadas} medidas aplicadas) — ajusta precios y reenvíalo al cliente ✓`);
      load();
    } catch (e) { onToast && onToast(e.message || 'Error al generar la revisión', true); }
    finally { setRevisando(false); }
  };

  if (!expedienteId) return <p className="muted" style={{fontSize:12}}>Expediente no disponible.</p>;
  if (data === null) return <p className="muted" style={{fontSize:12}}>Cargando…</p>;

  const lineas = data.lineas || [];
  const medidos = lineas.filter(l => l.ancho_mm != null || l.alto_mm != null).length;
  const validados = lineas.filter(l => l.bloqueado).length;
  const hayMedidasFab = lineas.some(l =>
    l.linea_presupuesto_id && (l.ancho_mm != null || l.alto_mm != null));
  const revisionActual = Number(data.presupuesto_revision) || 0;
  const todoValidado = lineas.length > 0 && validados === lineas.length;

  const pasos = [
    { label: 'Generar huecos', sub: lineas.length ? `${lineas.length} huecos` : 'desde el presupuesto', done: lineas.length > 0 },
    { label: 'Medir en obra', sub: lineas.length ? `${medidos} de ${lineas.length} medidos` : 'medida real de fabricación', done: lineas.length > 0 && medidos === lineas.length },
    { label: 'Validar huecos', sub: lineas.length ? `${validados} de ${lineas.length} validados` : 'bloquea cada hueco', done: todoValidado },
    { label: 'Revisar presupuesto', sub: revisionActual > 0 ? `Rev. ${revisionActual} generada` : 'aplica las medidas reales', done: revisionActual > 0 },
  ];

  return (
    <div>
      <PasosMedicion pasos={pasos}/>

      <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',gap:12,marginBottom:12,flexWrap:'wrap'}}>
        <div className="muted" style={{fontSize:11.5}}>
          Presupuesto: medida en cliente (solo lectura) · Fabricación: medida real (ancho a pared / suelo-techo).
        </div>
        {lineas.length > 0 && (
          <div style={{display:'flex',gap:8,flexWrap:'wrap'}}>
            <button className="btn ghost" onClick={generarDesdePresupuesto} disabled={seeding || !data.presupuesto_id} title={!data.presupuesto_id ? 'El expediente no tiene presupuesto' : ''}>
              <Icon name="sparkles" size={13}/> {seeding ? 'Generando…' : 'Generar desde presupuesto'}
            </button>
            <button className="btn" onClick={()=>setAdding(a=>!a)}><Icon name="plus" size={13}/> Añadir hueco</button>
          </div>
        )}
      </div>

      {adding && (
        <ValidacionAlta
          pedidoId={expedienteId}
          onAdded={()=>{ setAdding(false); load(); }}
          onCancel={()=>setAdding(false)}
          onToast={onToast}
        />
      )}

      {lineas.length === 0 && !adding && (
        <div style={{textAlign:'center',padding:'36px 16px',border:'1px dashed var(--line-2)',borderRadius:10}}>
          <p style={{fontSize:13,marginTop:0}}>Sin huecos que medir todavía.</p>
          <button className="btn primary" onClick={generarDesdePresupuesto} disabled={seeding || !data.presupuesto_id}
            title={!data.presupuesto_id ? 'El expediente no tiene presupuesto' : ''}>
            <Icon name="sparkles" size={13}/> {seeding ? 'Generando…' : 'Generar huecos desde el presupuesto'}
          </button>
          <div className="muted" style={{fontSize:11.5,margin:'8px 0'}}>o</div>
          <button className="btn ghost" onClick={()=>setAdding(true)}><Icon name="plus" size={13}/> Añadir hueco a mano</button>
        </div>
      )}

      {lineas.length > 0 && (
        <div style={{display:'grid',gridTemplateColumns:'repeat(auto-fill, minmax(380px, 1fr))',gap:12}}>
          {lineas.map(l => (
            <ValidacionCard key={l.id} pedidoId={expedienteId} linea={l} onChanged={load} onToast={onToast}/>
          ))}
        </div>
      )}

      {data.presupuesto_id && hayMedidasFab && (
        <div style={{
          marginTop:14, padding:'14px 16px', borderRadius:10,
          border:'1px solid var(--line)', background:'var(--surface-2)',
          display:'flex', alignItems:'center', gap:14, flexWrap:'wrap',
        }}>
          <div style={{flex:'1 1 320px'}}>
            <div style={{fontSize:13,fontWeight:700,marginBottom:2}}>
              Paso 4 · Revisión del presupuesto
              {revisionActual > 0 && <span className="pill ok" style={{marginLeft:8}}><span className="d"/>Rev. {revisionActual} generada</span>}
            </div>
            <div className="muted" style={{fontSize:11.5}}>
              {todoValidado
                ? 'Medición completa. Aplica las medidas reales al presupuesto: se archiva la versión actual y vuelve a Borrador como nueva revisión para ajustar precios y reenviar al cliente.'
                : `Puedes generarla ya, pero quedan ${lineas.length - validados} huecos sin validar. Solo cambian las medidas; RAL y demás atributos no se tocan.`}
            </div>
          </div>
          <button className="btn primary" onClick={generarRevision} disabled={revisando} style={{flexShrink:0}}>
            <Icon name="edit" size={13}/> {revisando ? 'Generando…' : `Generar revisión (Rev. ${revisionActual + 1})`}
          </button>
        </div>
      )}
    </div>
  );
};

window.ValidacionPanel = ValidacionPanel;
