/* Configuración editable + documentos (presupuesto y recibo) · Pieza 3a
   Los valores de las filas de Configuración se DERIVAN de este estado, así que
   guardar en una pantalla cambia lo que dice la lista. Nada escrito a mano.   */

const CFG_INIT = {
  rubro:'Pintor', patron:'C', tocado:[],
  presupuesto:{ on:true, items:true },
  servicios:[{ n:'Interior · por ambiente', p:48500, m:90 }, { n:'Frente de placard', p:22000, m:45 }, { n:'Exterior · por m²', p:5400, m:60 }],
  domicilio:{ on:true, pct:15, zonas:['Centro','Norte','Abasto'] },
  horario:HORARIO_INIT,
  pagos:{ medios:['Efectivo','Transferencia'], sena:true, pct:50 },
  ausencias:[{ n:'Feriado · 8 dic', d:'LUN' }],
  avisos:{ on:true, hs:24, resena:true, seguimiento:true },
  capacidad:6,
  sobre:{ on:true, max:2 },
  docs:{ nombre:'Nico Ferrari · Pintura', pie:'No válido como factura fiscal', logo:true },
};
const DIAS = ['L','M','X','J','V','S','D'];

/* Lo que gobierna la interfaz es la CONFIGURACIÓN, no el rubro. El rubro solo
   trae el preset inicial; de ahí en adelante manda lo que el emprendedor dejó
   configurado y Mia se adapta a eso.
   Las 7 cards de Configuración están SIEMPRE disponibles — esconder una porque
   "tu rubro no la usa" le saca la libertad de cambiar de opinión.           */
const hayPresupuesto = cfg => cfg.presupuesto.on;
const atiendeDomicilio = cfg => cfg.domicilio.on;
const cfgCards = () => CFG;
/* Preset por flujo. Se aplica al elegir el rubro, solo sobre lo que el
   emprendedor todavía no tocó: si ya lo ajustó, su valor gana. */
const PRESET = {
  A:{ presupuesto:{ on:true,  items:false }, domicilio:true  },
  B:{ presupuesto:{ on:false, items:false }, domicilio:false },
  C:{ presupuesto:{ on:true,  items:true  }, domicilio:true  },
  D:{ presupuesto:{ on:true,  items:true  }, domicilio:true  },
  E:{ presupuesto:{ on:true,  items:true  }, domicilio:true  },
  F:{ presupuesto:{ on:false, items:false }, domicilio:false },
  G:{ presupuesto:{ on:true,  items:true  }, domicilio:false },
};
const aplicarPreset = (c, patron) => {
  const p = PRESET[patron], t = c.tocado || [];
  return {
    ...c,
    presupuesto: t.includes('Recibos y presupuestos') ? c.presupuesto : { ...p.presupuesto },
    domicilio:   t.includes('Visitas a domicilio')    ? c.domicilio   : { ...c.domicilio, on:p.domicilio },
  };
};
/* El rubro trae un preset; lo que el emprendedor tocó queda marcado como suyo. */
const esPreset = (cfg, k) => k !== 'Tu rubro' && !(cfg.tocado || []).includes(k);

const cfgResumen = c => ({
  'Tu rubro':               c.rubro,
  'Servicios y precios':    `${c.servicios.filter(s => s.n.trim()).length} cargados`,
  'Visitas a domicilio':    c.domicilio.on ? `Recargo ${c.domicilio.pct}%` : 'No voy',
  'Horarios y días':        horarioResumen(c.horario),
  'Cobros y señas':         c.pagos.sena ? `Seña ${c.pagos.pct}%` : `${c.pagos.medios.length} medios`,
  'Feriados y vacaciones':  c.ausencias.length ? `${c.ausencias.length} cargados` : 'Ninguno',
  'Avisos al cliente':      c.avisos.on ? `${c.avisos.hs} h antes` : 'Sin recordatorios',
  'Capacidad y metas':      `${c.capacidad} por día`,
  'Sobreturnos':            c.sobre.on ? `Hasta ${c.sobre.max}` : 'No acepto',
  'Recibos y presupuestos': c.presupuesto.on ? (c.presupuesto.items ? 'Con ítems' : 'Monto único') : 'Sin presupuestos',
});

/* ── controles ─────────────────────────────────────────────── */
const Toggle = ({ on, onChange, label }) => (
  <button onClick={() => onChange(!on)} style={{ display:'flex', alignItems:'center', gap:12, minHeight:48, width:'100%', background:'transparent', border:'none', padding:0, cursor:'pointer', textAlign:'left' }}>
    <span style={{ flex:1, fontFamily:T.sans, fontSize:14.5, color:T.c100 }}>{label}</span>
    <span style={{ width:44, height:26, flex:'none', borderRadius:99, background:on?T.v600:T.g800, border:`1px solid ${on?T.v600:T.g700}`, position:'relative', transition:'background 200ms ease' }}>
      <i style={{ position:'absolute', top:2, left:on?20:2, width:20, height:20, borderRadius:99, background:'#fff', display:'block', transition:'left 200ms cubic-bezier(.4,0,.2,1)' }} />
    </span>
  </button>
);
const Stepper = ({ v, set, min = 0, max = 20, sufijo }) => (
  <div style={{ display:'flex', alignItems:'center', gap:10 }}>
    <button onClick={() => set(Math.max(min, v - 1))} style={{ width:44, height:44, flex:'none', borderRadius:10, background:T.g950, border:`1px solid ${T.g700}`, color:T.c100, fontSize:19, cursor:'pointer' }}>−</button>
    <span style={{ flex:1, textAlign:'center', fontFamily:T.mono, fontSize:20, fontWeight:500, color:T.c100 }}>{v}{sufijo ? <span style={{ fontSize:12, color:T.c500 }}> {sufijo}</span> : null}</span>
    <button onClick={() => set(Math.min(max, v + 1))} style={{ width:44, height:44, flex:'none', borderRadius:10, background:T.g950, border:`1px solid ${T.g700}`, color:T.c100, fontSize:19, cursor:'pointer' }}>+</button>
  </div>
);
const Campo = ({ v, set, ph, mono, label }) => (
  <div style={{ display:'flex', flexDirection:'column', gap:7 }}>
    {label && <Lbl>{label}</Lbl>}
    <input value={v} onChange={e => set(e.target.value)} placeholder={ph} inputMode={mono?'numeric':undefined}
      style={{ width:'100%', height:46, boxSizing:'border-box', padding:'0 13px', background:T.g950, border:`1px solid ${T.g700}`, borderRadius:11, color:T.c100, fontFamily:mono?T.mono:T.sans, fontSize:14.5, outline:'none' }} />
  </div>
);

/* ── rubro = flujo, una sola decisión ──────────────────────
   Decisión 04-sep: elegir el rubro YA es elegir el patrón de conversación. No
   hay pantalla de "elegí tu patrón" — es una decisión para el emprendedor, no
   dos. 60 rubros no entran en una lista usable en 390 px: se busca. La letra
   del patrón no se nombra nunca; se muestra la consecuencia.                */
function RubroPicker({ cfg, set }) {
  const [q, setQ] = React.useState('');
  const vis = RUBROS.filter(([,n]) => n.toLowerCase().includes(q.toLowerCase())).slice(0, 40);
  const f = FLUJOS[cfg.patron];
  /* Texto libre: el backend ya lo soporta — onboarding-flow.js lo sanitiza con
     sanitizarOficioLibre (una línea, 60 car.), lo guarda como `OTRO:<texto>` y
     cae en patrón A. Mínimo 2 caracteres. Mismo contrato acá.              */
  const libre = q.trim().replace(/\s+/g, ' ').slice(0, 60);
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
      <Card gap={12}>
        <Lbl>A QUÉ TE DEDICÁS</Lbl>
        <div style={{ display:'flex', alignItems:'center', gap:10, padding:'0 13px', height:48, background:T.g950, border:`1px solid ${T.g700}`, borderRadius:12 }}>
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke={T.c500} strokeWidth="2" style={{ flex:'none' }}><circle cx="11" cy="11" r="7"/><path d="M20 20l-4.2-4.2"/></svg>
          <input value={q} onChange={e => setQ(e.target.value)} placeholder="Buscar tu oficio…"
            style={{ flex:1, minWidth:0, height:'100%', background:'transparent', border:'none', color:T.c100, fontFamily:T.sans, fontSize:15, outline:'none' }} />
        </div>
        <div style={{ display:'flex', alignItems:'center', gap:10, padding:'11px 13px', background:T.vSoft, border:`1px solid ${T.vBorder}`, borderRadius:12 }}>
          <span style={{ flex:1, minWidth:0, fontFamily:T.sans, fontSize:14, color:T.c100, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}><b>{cfg.rubro}</b>{cfg.otro && <span style={{ fontFamily:T.mono, fontSize:9.5, color:T.c500 }}> · cargado aparte</span>}</span>
          <span style={{ flex:'none', fontFamily:T.mono, fontSize:9, letterSpacing:'.1em', color:T.v600 }}>{f.s.toUpperCase()}</span>
        </div>
      </Card>
      <Card pad={0} gap={0} style={{ overflow:'hidden' }}>
        {vis.map(([p,n],i) => { const on = cfg.rubro === n;
          return <button key={n} onClick={() => set(c => aplicarPreset({ ...c, rubro:n, otro:false, patron:p }, p))} style={{ display:'flex', alignItems:'center', gap:10, minHeight:50, width:'100%', padding:'8px 14px', background:on?T.vSoft:'transparent', border:'none', borderTop:i?`1px solid ${T.g800}`:'none', cursor:'pointer', textAlign:'left' }}>
            <span style={{ flex:1, minWidth:0, fontFamily:T.sans, fontSize:14.5, fontWeight:on?700:400, color:T.c100, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{n}</span>
            <span style={{ flex:'none', fontFamily:T.mono, fontSize:8.5, letterSpacing:'.09em', color:on ? T.c100:T.c500 }}>{FLUJOS[p].s.toUpperCase()}</span>
          </button>;
        })}
        {!vis.length && <div style={{ padding:'26px 16px', display:'flex', flexDirection:'column', alignItems:'center', gap:12 }}>
          <div style={{ fontFamily:T.sans, fontSize:13.5, lineHeight:1.5, color:T.c500, textAlign:'center' }}>{libre.length >= 2 ? 'No está en la lista, pero lo cargamos igual.' : 'Escribí al menos dos letras de tu oficio.'}</div>
          {libre.length >= 2 && <button onClick={() => { set(c => aplicarPreset({ ...c, rubro:libre, otro:true, patron:'A' }, 'A')); setQ(''); }} style={{ minHeight:46, fontFamily:T.sans, fontSize:13.5, fontWeight:600, color:T.v600, background:T.vSoft, border:`1px solid ${T.vBorder}`, borderRadius:11, padding:'0 18px', cursor:'pointer', maxWidth:'100%', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>Usar “{libre}”</button>}
        </div>}
      </Card>
      <div style={{ fontFamily:T.sans, fontSize:12.5, lineHeight:1.55, color:T.c500, padding:'0 4px' }}>Con <b style={{ color:T.c300 }}>{cfg.rubro}</b>, Mia arranca preconfigurada para {f.pres === 'siempre' ? 'presupuestar con ítems y materiales' : f.pres === 'a veces' ? 'presupuestar sin desglose de materiales' : 'tomar el turno directo, sin presupuesto'}{f.dom ? ' y preguntar por el domicilio' : ' y atender en tu local'}. <b style={{ color:T.c300 }}>Todo eso lo podés cambiar</b> — ella se adapta a lo que dejes configurado.{cfg.otro && <><br/><br/>Tu oficio no estaba en la lista, así que arrancás con el preset de <b style={{ color:T.c300 }}>visitas técnicas</b>, que es el más general. Ajustá lo que no te cierre y queda como vos lo dejes.</>}</div>
    </div>
  );
}

/* ── editor de configuración ───────────────────────────────── */
function CfgEditor({ k, cfg, set }) {
  const p = PASOS_ONB.find(x => x.k === k);
  const ayuda = <div style={{ fontFamily:T.sans, fontSize:12.5, lineHeight:1.55, color:T.c500, padding:'0 4px' }}>{p ? p.x : ''}</div>;

  if (k === 'Tu rubro') return <RubroPicker cfg={cfg} set={set} />;

  if (k === 'Visitas a domicilio') return (
    <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
      <Card gap={8}><Toggle on={cfg.domicilio.on} label="Voy al lugar del cliente" onChange={v => set(c => ({ ...c, domicilio:{ ...c.domicilio, on:v } }))} />
        <div style={{ fontFamily:T.sans, fontSize:12, lineHeight:1.5, color:T.c500 }}>{cfg.domicilio.on ? 'Mia le pregunta al cliente si quiere que vayas o si viene él.' : 'Mia da por hecho que atendés en tu local y no pregunta la dirección.'}</div>
      </Card>
      {cfg.domicilio.on && <Card gap={14}>
        <div><Lbl mb={10}>RECARGO POR VISITA</Lbl><Stepper v={cfg.domicilio.pct} min={0} max={100} sufijo="%" set={v => set(c => ({ ...c, domicilio:{ ...c.domicilio, pct:v } }))} /></div>
        <div style={{ paddingTop:14, borderTop:`1px solid ${T.g800}` }}>
          <Lbl mb={10}>ZONAS QUE CUBRÍS</Lbl>
          <div style={{ display:'flex', flexWrap:'wrap', gap:7 }}>
            {['Centro','Norte','Sur','Oeste','Abasto'].map(z => { const on = cfg.domicilio.zonas.includes(z);
              return <Chip key={z} on={on} onClick={() => set(c => ({ ...c, domicilio:{ ...c.domicilio, zonas:on ? c.domicilio.zonas.filter(x=>x!==z) : [...c.domicilio.zonas, z] } }))}>{z}</Chip>;
            })}
          </div>
        </div>
      </Card>}
      {ayuda}
    </div>
  );

  if (k === 'Servicios y precios') return (
    <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
      <Card pad={0} gap={0} style={{ overflow:'hidden' }}>
        {cfg.servicios.map((s,i) => {
          const upd = (kk, v) => set(c => ({ ...c, servicios:c.servicios.map((x,n) => n===i ? { ...x, [kk]:v } : x) }));
          const num = v => parseInt(String(v).replace(/\D/g,''), 10) || 0;
          return (
            <div key={i} style={{ display:'flex', flexDirection:'column', gap:7, padding:'11px 12px', borderTop:i?`1px solid ${T.g800}`:'none' }}>
              <div style={{ display:'flex', alignItems:'center', gap:7 }}>
                <input value={s.n} onChange={e => upd('n', e.target.value)} placeholder="Nombre del servicio"
                  style={{ flex:1, minWidth:0, height:42, boxSizing:'border-box', padding:'0 11px', background:T.g950, border:`1px solid ${T.g700}`, borderRadius:9, color:T.c100, fontFamily:T.sans, fontSize:14, outline:'none' }} />
                <button onClick={() => set(c => ({ ...c, servicios:c.servicios.filter((_,n) => n!==i) }))} aria-label={'Borrar ' + (s.n || 'servicio')} style={{ width:32, height:42, flex:'none', background:'transparent', border:'none', color:T.c500, fontSize:14, cursor:'pointer', padding:0 }}>✕</button>
              </div>
              <div style={{ display:'flex', alignItems:'center', gap:7 }}>
                <span style={{ fontFamily:T.mono, fontSize:9, letterSpacing:'.1em', color:T.c500, flex:'none' }}>$</span>
                <input value={s.p} onChange={e => upd('p', num(e.target.value))} inputMode="numeric" aria-label="Precio"
                  style={{ flex:1, minWidth:0, height:40, boxSizing:'border-box', padding:'0 10px', textAlign:'right', background:T.g950, border:`1px solid ${T.g700}`, borderRadius:9, color:T.c100, fontFamily:T.mono, fontSize:13.5, outline:'none' }} />
                <span style={{ fontFamily:T.mono, fontSize:9, letterSpacing:'.1em', color:T.c500, flex:'none', paddingLeft:5 }}>MIN</span>
                <input value={s.m || 60} onChange={e => upd('m', num(e.target.value))} inputMode="numeric" aria-label="Duración en minutos"
                  style={{ width:62, flex:'none', height:40, boxSizing:'border-box', padding:'0 9px', textAlign:'center', background:T.g950, border:`1px solid ${T.g700}`, borderRadius:9, color:T.c100, fontFamily:T.mono, fontSize:13.5, outline:'none' }} />
              </div>
            </div>
          );
        })}
        <button onClick={() => set(c => ({ ...c, servicios:[...c.servicios, { n:'', p:0, m:60 }] }))} style={{ minHeight:46, width:'100%', borderTop:`1px solid ${T.g800}`, background:'transparent', border:'none', color:T.v600, fontFamily:T.sans, fontSize:13, fontWeight:600, cursor:'pointer' }}>+ Agregar un servicio</button>
      </Card>
      <DuracionNota />
      {ayuda}
    </div>
  );

  if (k === 'Horarios y días') return <HorarioEditor cfg={cfg} set={set} />;
  if (k === 'Cobros y señas') return <PagosEditor cfg={cfg} set={set} />;
  if (k === 'Feriados y vacaciones') return <AusenciasEditor cfg={cfg} set={set} />;
  if (k === 'Avisos al cliente') return <AvisosEditor cfg={cfg} set={set} />;

  if (k === 'Capacidad y metas') return (
    <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
      <Card gap={12}><Lbl>TRABAJOS POR DÍA COMO MÁXIMO</Lbl><Stepper v={cfg.capacidad} min={1} max={20} set={v => set(c => ({ ...c, capacidad:v }))} />
        <div style={{ fontFamily:T.sans, fontSize:12.5, color:T.c500 }}>Mia deja de ofrecer turnos cuando llega a {cfg.capacidad}.</div>
      </Card>
      {ayuda}
    </div>
  );

  if (k === 'Sobreturnos') return (
    <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
      <Card><Toggle on={cfg.sobre.on} label="Acepto sobreturnos" onChange={v => set(c => ({ ...c, sobre:{ ...c.sobre, on:v } }))} /></Card>
      {cfg.sobre.on && <Card gap={12}><Lbl>CUÁNTOS EXTRA COMO MÁXIMO</Lbl><Stepper v={cfg.sobre.max} min={1} max={6} set={v => set(c => ({ ...c, sobre:{ ...c.sobre, max:v } }))} /></Card>}
      {ayuda}
    </div>
  );

  return (
    <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
      <Card gap={8}>
        <Toggle on={cfg.presupuesto.on} label="Mando presupuestos" onChange={v => set(c => ({ ...c, presupuesto:{ ...c.presupuesto, on:v } }))} />
        <div style={{ fontFamily:T.sans, fontSize:12, lineHeight:1.5, color:T.c500 }}>{cfg.presupuesto.on ? 'Antes de tomar el trabajo, Mia le manda el presupuesto y espera respuesta.' : 'Mia toma el trabajo directo, con el precio de tu lista y sin presupuesto previo.'}</div>
        {cfg.presupuesto.on && <div style={{ paddingTop:8, borderTop:`1px solid ${T.g800}` }}>
          <Toggle on={cfg.presupuesto.items} label="Desglosar materiales y mano de obra" onChange={v => set(c => ({ ...c, presupuesto:{ ...c.presupuesto, items:v } }))} />
          <div style={{ fontFamily:T.sans, fontSize:12, lineHeight:1.5, color:T.c500 }}>{cfg.presupuesto.items ? 'Cada presupuesto se arma por ítems: el cliente ve en qué se le va la plata.' : 'Un solo monto por trabajo, sin lista de ítems.'}</div>
        </div>}
      </Card>
      <Card gap={14}>
        <Campo label="NOMBRE EN LOS COMPROBANTES" v={cfg.docs.nombre} set={v => set(c => ({ ...c, docs:{ ...c.docs, nombre:v } }))} ph="Tu nombre o el del negocio" />
        <Campo label="PIE DE PÁGINA" v={cfg.docs.pie} set={v => set(c => ({ ...c, docs:{ ...c.docs, pie:v } }))} ph="Texto legal al pie" />
        <div style={{ paddingTop:2, borderTop:`1px solid ${T.g800}` }}><Toggle on={cfg.docs.logo} label="Incluir el logo" onChange={v => set(c => ({ ...c, docs:{ ...c.docs, logo:v } }))} /></div>
      </Card>
      {ayuda}
    </div>
  );
}

/* ── presupuesto con ítems ────────────────────────────────────
   El esquema real ya tiene la forma: presupuestos.items es
   [{desc, cantidad, precio_unit, subtotal}]. Lo que hace budget.js hoy es
   colapsar todo en UN ítem con cantidad 1 — así que un pintor no puede
   desglosar pintura, rodillos y mano de obra. Acá el desglose es de verdad.
   En 390 px una tabla de 5 columnas no entra: cada ítem son DOS líneas.    */
const GRUPOS = [
  { t:'mat',  lbl:'MATERIALES',   add:'+ Material' },
  { t:'obra', lbl:'MANO DE OBRA', add:'+ Mano de obra' },
];
const totalItems = its => (its || []).reduce((s,i) => s + (i.c || 0) * (i.p || 0), 0);

function ItemsEditor({ items, set, ticket, setTicket }) {
  const tk = ticket || { fotos:[], como:'En papel' };
  const setTk = setTicket || (() => {});
  const upd = (i, k, v) => set(items.map((x,n) => n === i ? { ...x, [k]:v } : x));
  const num = v => parseInt(String(v).replace(/\D/g,''), 10) || 0;
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:12 }}>
      {GRUPOS.map(g => {
        const idx = items.map((x,n) => [x,n]).filter(([x]) => x.t === g.t);
        const sub = idx.reduce((s,[x]) => s + x.c * x.p, 0);
        return (
          <Card key={g.t} pad={0} gap={0} style={{ overflow:'hidden' }}>
            <div style={{ display:'flex', alignItems:'baseline', gap:10, padding:'14px 14px 10px' }}>
              <Lbl>{g.lbl}</Lbl>
              <span style={{ marginLeft:'auto', fontFamily:T.mono, fontSize:11, color:idx.length?T.c300:T.c500 }}>{idx.length ? money(sub) : '—'}</span>
            </div>
            {idx.map(([x,n]) => (
              <div key={n} style={{ display:'flex', flexDirection:'column', gap:7, padding:'11px 14px', borderTop:`1px solid ${T.g800}` }}>
                <div style={{ display:'flex', alignItems:'center', gap:7 }}>
                  <input value={x.d} onChange={e => upd(n,'d',e.target.value)} placeholder={g.t === 'mat' ? 'Qué material' : 'Qué trabajo'}
                    style={{ flex:1, minWidth:0, height:42, boxSizing:'border-box', padding:'0 11px', background:T.g950, border:`1px solid ${T.g700}`, borderRadius:9, color:T.c100, fontFamily:T.sans, fontSize:14, outline:'none' }} />
                  <button onClick={() => set(items.filter((_,m) => m !== n))} aria-label="Borrar ítem" style={{ width:34, height:42, flex:'none', background:'transparent', border:'none', color:T.c500, fontSize:14, cursor:'pointer', padding:0 }}>✕</button>
                </div>
                <div style={{ display:'flex', alignItems:'center', gap:7 }}>
                  <input value={x.c} onChange={e => upd(n,'c',num(e.target.value))} inputMode="numeric" aria-label="Cantidad"
                    style={{ width:54, flex:'none', height:40, boxSizing:'border-box', padding:'0 8px', textAlign:'center', background:T.g950, border:`1px solid ${T.g700}`, borderRadius:9, color:T.c100, fontFamily:T.mono, fontSize:13.5, outline:'none' }} />
                  <span style={{ fontFamily:T.mono, fontSize:12, color:T.c500, flex:'none' }}>×</span>
                  <input value={x.p} onChange={e => upd(n,'p',num(e.target.value))} inputMode="numeric" aria-label="Precio unitario"
                    style={{ flex:1, minWidth:0, height:40, boxSizing:'border-box', padding:'0 10px', textAlign:'right', background:T.g950, border:`1px solid ${T.g700}`, borderRadius:9, color:T.c100, fontFamily:T.mono, fontSize:13.5, outline:'none' }} />
                  <span style={{ fontFamily:T.mono, fontSize:12.5, color:T.c300, flex:'none', minWidth:74, textAlign:'right' }}>{money(x.c * x.p)}</span>
                </div>
              </div>
            ))}
            <button onClick={() => set([...items, { t:g.t, d:'', c:1, p:0 }])} style={{ minHeight:46, width:'100%', borderTop:`1px solid ${T.g800}`, background:'transparent', border:'none', color:T.v600, fontFamily:T.sans, fontSize:13, fontWeight:600, cursor:'pointer' }}>{g.add}</button>
          </Card>
        );
      })}
      {/* El comprobante de la ferretería: el emprendedor compra el material y
          después le muestra el ticket al cliente para que vea que no le está
          cargando de más. Sacarle una foto lo deja pegado al presupuesto, y
          en el documento queda dicho CÓMO se entregó — en papel o adjunto. */}
      <Card gap={11}>
        <div style={{ display:'flex', alignItems:'baseline', gap:10 }}>
          <Lbl>CARGAR TICKET DE MATERIALES</Lbl>
          <span style={{ marginLeft:'auto', fontFamily:T.mono, fontSize:9.5, color:tk.fotos.length ? T.green : T.c500 }}>{tk.fotos.length ? `${tk.fotos.length} FOTO${tk.fotos.length === 1 ? '' : 'S'}` : 'SIN ADJUNTAR'}</span>
        </div>
        {/* Cada miniatura se puede borrar: la foto de un ticket se saca
            apurado en la ferretería y salir movida es lo normal. */}
        {tk.fotos.length > 0 && <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
          {tk.fotos.map((f,i) => (
            <span key={i} style={{ position:'relative', display:'block' }}>
              <Miniatura n={f} size={62} />
              <button onClick={() => setTk({ ...tk, fotos:tk.fotos.filter((_,n) => n !== i) })} aria-label="Borrar esta foto"
                style={{ position:'absolute', top:-6, right:-6, width:22, height:22, borderRadius:99, background:T.g950, border:`1px solid ${T.g700}`, color:T.c300, fontSize:10, lineHeight:1, cursor:'pointer', padding:0, display:'grid', placeItems:'center' }}>✕</button>
            </span>
          ))}
        </div>}
        {/* Cámara o galería: muchas veces la foto ya está sacada de antes. */}
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:8 }}>
          {[['Cámara','M3 8a2 2 0 0 1 2-2h2l1.5-2h7L17 6h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'],
            ['Galería','M3 6a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2zM3 16l5-5 4 4 3-3 6 6']].map(([l,p]) => (
            <button key={l} onClick={() => setTk({ ...tk, fotos:[...tk.fotos, { tono:tk.fotos.length % 3 }] })}
              style={{ minHeight:46, borderRadius:11, background:'transparent', border:`1px solid ${T.g700}`, color:T.c300, fontFamily:T.sans, fontSize:13, fontWeight:600, cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', gap:7 }}>
              <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke={T.c300} strokeWidth="1.7"><path d={p}/>{l === 'Cámara' && <circle cx="12" cy="12.5" r="3.4"/>}</svg>
              {l}
            </button>
          ))}
        </div>
        <div style={{ paddingTop:11, borderTop:`1px solid ${T.g800}` }}>
          <Lbl mb={9}>CÓMO SE LO ENTREGÁS AL CLIENTE</Lbl>
          <div style={{ display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:6 }}>
            {['En papel','Adjunto','No va'].map(o => <Chip key={o} on={tk.como === o} onClick={() => setTk({ ...tk, como:o })}>{o}</Chip>)}
          </div>
          <div style={{ fontFamily:T.sans, fontSize:12, lineHeight:1.5, color:T.c500, marginTop:9 }}>{tk.como === 'En papel' ? 'El presupuesto dice que el ticket original se entrega en mano.' : tk.como === 'Adjunto' ? 'El ticket va con el presupuesto, así el cliente ve los precios de la ferretería.' : 'El presupuesto no menciona comprobantes de materiales.'}</div>
        </div>
      </Card>
      <div style={{ display:'flex', alignItems:'baseline', gap:12, padding:'14px 16px', background:T.g900, border:`1px solid ${T.vBorder}`, borderRadius:14 }}>
        <span style={{ fontFamily:T.sans, fontSize:13, fontWeight:700, color:T.c100, textTransform:'uppercase', letterSpacing:'.04em' }}>Total</span>
        <span style={{ marginLeft:'auto', fontFamily:T.mono, fontSize:21, fontWeight:500, color:T.c100, letterSpacing:'-.5px' }}>{money(totalItems(items))}</span>
      </div>
      <div style={{ fontFamily:T.sans, fontSize:12.5, lineHeight:1.55, color:T.c500, padding:'0 4px' }}>Los materiales y la mano de obra van separados en el documento, así el cliente ve en qué se le va la plata. Mia arranca el desglose con los precios que tenés cargados en Servicios.</div>
    </div>
  );
}

/* ── documento: presupuesto o recibo ──────────────────────── */
function DocView({ job, tipo, cfg, editar }) {
  const recibo = tipo === 'recibo';
  const nro = recibo ? '00' + job.id : job.id;
  /* El desglose existe si el emprendedor lo dejó prendido. Sin él, el mismo
     documento cae al monto único — los ítems no se borran, quedan guardados. */
  const items = cfg.presupuesto.items ? (job.items || []).filter(i => i.d.trim() || i.p) : [];
  const total = items.length ? totalItems(items) : job.monto;
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
      <Card gap={0} style={{ background:T.c100, borderColor:T.c300, padding:20 }}>
        <div style={{ display:'flex', alignItems:'flex-start', gap:12, paddingBottom:14, borderBottom:`1px solid #E5E1DC` }}>
          {cfg.docs.logo && <svg width="34" height="34" viewBox="0 0 400 400" style={{ flex:'none' }}><circle cx="200" cy="200" r="200" fill={T.v600}/><rect x="118" y="138" width="164" height="100" rx="26" fill={T.c100}/><path d="M152 238 L122 284 L200 238 Z" fill={T.c100}/><circle cx="160" cy="188" r="11" fill={T.v600}/><circle cx="200" cy="188" r="11" fill={T.v600}/><circle cx="240" cy="188" r="11" fill={T.v600}/></svg>}
          <div style={{ flex:1, minWidth:0 }}>
            <div style={{ fontFamily:T.sans, fontSize:15, fontWeight:700, color:T.g950, letterSpacing:'-.2px' }}>{cfg.docs.nombre}</div>
            <div style={{ fontFamily:T.mono, fontSize:9, letterSpacing:'.12em', color:'#7C7772', marginTop:3 }}>{recibo ? 'RECIBO' : 'PRESUPUESTO'} N° {nro}</div>
          </div>
          <div style={{ fontFamily:T.mono, fontSize:9.5, color:'#7C7772', textAlign:'right' }}>03/09/26</div>
        </div>
        <div style={{ padding:'14px 0', borderBottom:`1px solid #E5E1DC` }}>
          <div style={{ fontFamily:T.mono, fontSize:8.5, letterSpacing:'.12em', color:'#7C7772' }}>PARA</div>
          <div style={{ fontFamily:T.sans, fontSize:14, color:T.g950, marginTop:4 }}>{job.cli}</div>
        </div>
        {items.length ? GRUPOS.map(g => { const del = items.filter(i => i.t === g.t);
          if (!del.length) return null;
          return <div key={g.t} style={{ padding:'12px 0 2px' }}>
            <div style={{ fontFamily:T.mono, fontSize:8, letterSpacing:'.13em', color:'#9C9691', paddingBottom:4 }}>{g.lbl}</div>
            {del.map((it,i) => (
              <div key={i} style={{ display:'flex', alignItems:'baseline', gap:10, padding:'7px 0', borderBottom:'1px solid #EFECE8' }}>
                <span style={{ flex:1, minWidth:0, fontFamily:T.sans, fontSize:13, lineHeight:1.35, color:T.g950 }}>{it.d || '—'}{it.c > 1 ? <span style={{ fontFamily:T.mono, fontSize:10.5, color:'#7C7772' }}> ×{it.c}</span> : null}</span>
                <span style={{ fontFamily:T.mono, fontSize:12.5, color:T.g950, flex:'none' }}>{money(it.c * it.p)}</span>
              </div>
            ))}
          </div>;
        }) : (
          <div style={{ display:'flex', alignItems:'baseline', gap:12, padding:'14px 0' }}>
            <div style={{ flex:1, fontFamily:T.sans, fontSize:14, color:T.g950 }}>{job.svc}</div>
            <div style={{ fontFamily:T.mono, fontSize:14, color:T.g950 }}>{money(job.monto)}</div>
          </div>
        )}
        <div style={{ display:'flex', alignItems:'baseline', gap:12, padding:'13px 0', marginTop:items.length?10:0, borderTop:`2px solid ${T.g950}` }}>
          <div style={{ flex:1, fontFamily:T.sans, fontSize:12.5, fontWeight:700, color:T.g950, textTransform:'uppercase', letterSpacing:'.04em' }}>{recibo ? 'Cobrado' : 'Total'}</div>
          <div style={{ fontFamily:T.mono, fontSize:19, fontWeight:500, color:T.g950, letterSpacing:'-.4px' }}>{money(total)}</div>
        </div>
        {!recibo && job.ticket && job.ticket.como !== 'No va' && (
          <div style={{ display:'flex', alignItems:'center', gap:8, padding:'9px 0 0', marginTop:8, borderTop:'1px solid #EFECE8' }}>
            <span style={{ fontFamily:T.mono, fontSize:8, letterSpacing:'.12em', color:'#9C9691' }}>MATERIALES</span>
            <span style={{ fontFamily:T.sans, fontSize:10.5, color:'#7C7772' }}>{job.ticket.como === 'Adjunto' ? `Comprobante de compra adjunto (${job.ticket.fotos.length} foto${job.ticket.fotos.length === 1 ? '' : 's'}).` : 'El comprobante original de la ferretería se entrega en mano.'}</span>
          </div>
        )}
        <div style={{ fontFamily:T.sans, fontSize:10.5, lineHeight:1.5, color:'#7C7772', paddingTop:10 }}>
          {recibo ? cfg.docs.pie : <>Válido por 15 días. {cfg.docs.pie}</>}
        </div>
      </Card>
      {!recibo && editar && <button onClick={editar} style={{ minHeight:48, fontFamily:T.sans, fontSize:13.5, fontWeight:600, color:T.v600, background:T.vSoft, border:`1px solid ${T.vBorder}`, borderRadius:12, cursor:'pointer' }}>{items.length ? `Editar los ${items.length} ítems` : 'Desglosar en ítems y materiales'}</button>}
      <div style={{ fontFamily:T.sans, fontSize:12.5, lineHeight:1.55, color:T.c500, padding:'0 4px' }}>
        {recibo
          ? <>Se lo mandé a {job.cli.split(' ')[0]} por WhatsApp cuando cerraste el trabajo. La versión A4 para imprimir sale del panel.</>
          : job.enviado
            ? <>Enviado a {job.cli.split(' ')[0]} por WhatsApp. Cuando responda te aviso.</>
            : <>Todavía no se lo mandé. Revisá el monto y dale enviar.</>}
      </div>
    </div>
  );
}

/* ── documentos, en Negocio ───────────────────────────────── */
function Documentos({ jobs, abrir, conPresupuesto = true }) {
  const pres = conPresupuesto ? jobs.filter(j => j.dia === 'PRESUPUESTO' && !esCierre(j.tsm)) : [];
  const recs = jobs.filter(j => esCobrado(j.tsm));
  const fila = (j, tipo) => (
    <button key={tipo + j.id} onClick={() => abrir(j, tipo)} style={{ display:'flex', alignItems:'center', gap:12, minHeight:60, width:'100%', padding:'0 16px', background:'transparent', border:'none', borderTop:`1px solid ${T.g800}`, cursor:'pointer', textAlign:'left' }}>
      <span style={{ width:28, height:34, flex:'none', borderRadius:4, border:`1px solid ${tipo==='recibo'?T.gBorder:T.vBorder}`, background:tipo==='recibo'?T.gSoft:T.vSoft, display:'grid', placeItems:'center', fontFamily:T.mono, fontSize:8, color:tipo==='recibo'?T.green:T.v600 }}>{tipo==='recibo'?'REC':'PRE'}</span>
      <span style={{ flex:1, minWidth:0 }}>
        <span style={{ display:'block', fontFamily:T.sans, fontSize:14, color:T.c100, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{j.svc}</span>
        <span style={{ display:'block', fontFamily:T.mono, fontSize:9.5, color:T.c500, marginTop:3 }}>{j.cli} · {tipo === 'recibo' ? 'COBRADO' : j.enviado ? 'ENVIADO' : 'SIN ENVIAR'}</span>
      </span>
      <span style={{ fontFamily:T.mono, fontSize:12, color:T.c300, flex:'none' }}>{money(j.monto)}</span>
    </button>
  );
  return (
    <Card pad={0} gap={0} style={{ overflow:'hidden' }}>
      <div style={{ display:'flex', alignItems:'baseline', gap:10, padding:'15px 16px 13px' }}>
        <Lbl>DOCUMENTOS</Lbl>
        <span style={{ marginLeft:'auto', fontFamily:T.mono, fontSize:9.5, color:T.c500 }}>{conPresupuesto ? `${pres.length} PRESUP · ` : ''}{recs.length} RECIBO{recs.length === 1 ? '' : 'S'}</span>
      </div>
      {!pres.length && !recs.length
        ? <div style={{ padding:'0 16px 18px', fontFamily:T.sans, fontSize:13, color:T.c500 }}>Todavía no emitiste ninguno.</div>
        : <>{pres.map(j => fila(j, 'presupuesto'))}{recs.map(j => fila(j, 'recibo'))}</>}
    </Card>
  );
}

Object.assign(window, { CFG_INIT, cfgResumen, cfgCards, hayPresupuesto, atiendeDomicilio, aplicarPreset, esPreset, CfgEditor, RubroPicker, DocView, Documentos, Toggle, Stepper, Campo, ItemsEditor, totalItems, GRUPOS });
