/* views.jsx — Dashboard, Editor, Preview */

/* ============================== DASHBOARD ============================== */
function Dashboard({ quotes, openQuote, openPreview, newQuote, duplicateQuote, deleteQuote, onGenerate }) {
  const [filter, setFilter] = React.useState('all');
  const [query, setQuery] = React.useState('');

  const filtered = quotes.filter(q => {
    if (filter !== 'all' && q.status !== filter) return false;
    if (query) {
      const t = (q.client.company + ' ' + q.project.name + ' ' + q.id).toLowerCase();
      if (!t.includes(query.toLowerCase())) return false;
    }
    return true;
  });

  /* Stats */
  const now = new Date();
  const thisMonth = quotes.filter(q => {
    const d = new Date(q.createdAt);
    return d.getMonth() === now.getMonth() && d.getFullYear() === now.getFullYear();
  });
  const monthTotal = thisMonth.reduce((s, q) => s + computeTotals(q).total, 0);
  const accepted = quotes.filter(q => q.status === 'accepted');
  const acceptedTotal = accepted.reduce((s, q) => s + computeTotals(q).total, 0);
  const inReview = quotes.filter(q => q.status === 'sent').length;
  const decided = quotes.filter(q => q.status === 'accepted' || q.status === 'rejected');
  const winRate = decided.length ? Math.round(100 * accepted.length / decided.length) : 0;

  const counts = {
    all: quotes.length,
    draft: quotes.filter(q => q.status === 'draft').length,
    sent: quotes.filter(q => q.status === 'sent').length,
    accepted: quotes.filter(q => q.status === 'accepted').length,
    rejected: quotes.filter(q => q.status === 'rejected').length,
    expired: quotes.filter(q => q.status === 'expired').length,
  };

  return (
    <div>
      <div className="page-head">
        <div>
          <SectionLabel>Panel principal</SectionLabel>
          <h1 className="page-title">Cotizaciones</h1>
          <div className="page-subtitle">{quotes.length} cotizaciones en total · {inReview} esperando respuesta</div>
        </div>
        <div style={{display: 'flex', gap: 10}}>
          <button className="btn btn-secondary" onClick={onGenerate}><Icon.spark /> Generar con IA</button>
          <button className="btn btn-primary" onClick={newQuote}><Icon.plus /> Nueva cotización</button>
        </div>
      </div>

      {/* Stats */}
      <div className="stats">
        <div className="card card-pad stat">
          <SectionLabel>Facturado este mes</SectionLabel>
          <div className="stat-num mono-num">{fmtMXNshort(monthTotal)}</div>
          <div className="stat-delta up">▲ 18% vs. abril</div>
        </div>
        <div className="card card-pad stat">
          <SectionLabel>Aceptadas (YTD)</SectionLabel>
          <div className="stat-num mono-num">{fmtMXNshort(acceptedTotal)}</div>
          <div className="stat-delta">{accepted.length} proyectos firmados</div>
        </div>
        <div className="card card-pad stat">
          <SectionLabel>En revisión</SectionLabel>
          <div className="stat-num mono-num">{inReview}</div>
          <div className="stat-delta">Vigencia promedio 22 días</div>
        </div>
        <div className="card card-pad stat">
          <SectionLabel>Tasa de conversión</SectionLabel>
          <div className="stat-num mono-num">{winRate}%</div>
          <div className="stat-delta up">▲ 6 pts vs. trimestre</div>
        </div>
      </div>

      {/* Table */}
      <div className="card table-card">
        <div className="table-toolbar">
          <div className="search">
            <Icon.search style={{color: '#94A3B8'}} />
            <input
              placeholder="Buscar por cliente, proyecto o folio…"
              value={query}
              onChange={e => setQuery(e.target.value)}
            />
          </div>
          <div className="filter-chips">
            {[
              ['all', 'Todas'],
              ['draft', 'Borrador'],
              ['sent', 'Enviadas'],
              ['accepted', 'Aceptadas'],
              ['rejected', 'Rechazadas'],
              ['expired', 'Expiradas'],
            ].map(([k, l]) => (
              <button key={k} className={`chip ${filter === k ? 'active' : ''}`} onClick={() => setFilter(k)}>
                {l} <span style={{opacity: 0.6, marginLeft: 4}}>{counts[k]}</span>
              </button>
            ))}
          </div>
        </div>
        <table className="quotes">
          <thead>
            <tr>
              <th style={{width: 110}}>Folio</th>
              <th>Cliente / Proyecto</th>
              <th style={{width: 130}}>Monto</th>
              <th style={{width: 130}}>Estado</th>
              <th style={{width: 110}}>Enviada</th>
              <th style={{width: 110}}>Vigencia</th>
              <th style={{width: 110, textAlign: 'right'}}>Acciones</th>
            </tr>
          </thead>
          <tbody>
            {filtered.map(q => {
              const tot = computeTotals(q);
              return (
                <tr key={q.id} onClick={() => openQuote(q.id)}>
                  <td className="id">{q.id}</td>
                  <td className="client-name">
                    {q.client.company}
                    <span className="project">{q.project.name}</span>
                  </td>
                  <td className="amount mono-num">{fmtMXNshort(tot.total)}</td>
                  <td><StatusPill status={q.status} /></td>
                  <td className="date">{fmtDateShort(q.createdAt)}</td>
                  <td className="date">{fmtDateShort(q.validUntil)}</td>
                  <td style={{textAlign: 'right'}} onClick={e => e.stopPropagation()}>
                    <button className="btn btn-ghost" style={{padding: '6px 8px'}} title="Vista cliente" onClick={() => openPreview(q.id)}><Icon.eye /></button>
                    <button className="btn btn-ghost" style={{padding: '6px 8px'}} title="Duplicar" onClick={() => duplicateQuote(q.id)}><Icon.copy /></button>
                    <button className="btn btn-ghost" style={{padding: '6px 8px', color: '#ef4444'}} title="Eliminar" onClick={() => { if (confirm(`¿Eliminar "${q.client.company}"? Esta acción no se puede deshacer.`)) deleteQuote(q.id); }}><Icon.trash /></button>
                  </td>
                </tr>
              );
            })}
            {!filtered.length && (
              <tr><td colSpan={7} style={{padding: '60px 22px', textAlign: 'center', color: 'var(--text-2)'}}>
                Sin resultados para los filtros aplicados.
              </td></tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}

/* ============================== EDITOR ============================== */
function Editor({ quote, updateQuote, openPreview, back }) {
  const [catalogOpen, setCatalogOpen] = React.useState(false);
  if (!quote) return null;
  const tot = computeTotals(quote);

  const patch = (path, value) => {
    updateQuote(quote.id, prev => {
      const next = JSON.parse(JSON.stringify(prev));
      const segs = path.split('.');
      let cur = next;
      for (let i = 0; i < segs.length - 1; i++) {
        if (cur[segs[i]] == null || typeof cur[segs[i]] !== 'object') cur[segs[i]] = {};
        cur = cur[segs[i]];
      }
      cur[segs[segs.length - 1]] = value;
      return next;
    });
  };
  const patchItem = (id, key, value) => {
    updateQuote(quote.id, prev => ({
      ...prev,
      items: prev.items.map(it => it.id === id ? { ...it, [key]: value } : it),
    }));
  };
  const removeItem = (id) => updateQuote(quote.id, prev => ({ ...prev, items: prev.items.filter(it => it.id !== id) }));
  const addFromCatalog = (entry) => {
    const newItem = {
      id: Date.now(),
      ref: entry.id, name: entry.name, sub: entry.sub,
      qty: 1, unit: entry.unit, price: entry.price,
    };
    updateQuote(quote.id, prev => ({ ...prev, items: [...prev.items, newItem] }));
    setCatalogOpen(false);
  };
  const addBlank = () => {
    updateQuote(quote.id, prev => ({
      ...prev,
      items: [...prev.items, { id: Date.now(), name: 'Nuevo concepto', sub: '', qty: 1, unit: 'pieza', price: 0 }],
    }));
  };
  const setSchedulePct = (idx, pct) => {
    updateQuote(quote.id, prev => ({
      ...prev,
      schedule: prev.schedule.map((s, i) => i === idx ? { ...s, pct: Number(pct) || 0 } : s),
    }));
  };

  return (
    <div>
      <button className="editor-back" onClick={back}><Icon.back /> Volver a cotizaciones</button>

      <div className="page-head" style={{alignItems: 'center', marginBottom: 28}}>
        <div>
          <SectionLabel>Editor de cotización · {quote.id}</SectionLabel>
          <h1 className="page-title" style={{display: 'flex', alignItems: 'center', gap: 14}}>
            {quote.project.name}
            <StatusPill status={quote.status} />
          </h1>
          <div className="page-subtitle">{quote.client.company} · Creada {fmtDateLong(quote.createdAt)}</div>
        </div>
        <div style={{display: 'flex', gap: 10}}>
          <button className="btn btn-secondary" onClick={() => openPreview(quote.id)}><Icon.eye /> Vista cliente</button>
          <button className="btn btn-primary" onClick={() => patch('status', 'sent')}><Icon.send /> {quote.status === 'sent' ? 'Reenviar' : 'Enviar al cliente'}</button>
        </div>
      </div>

      <div className="editor-grid">
        <div style={{display: 'grid', gap: 20, minWidth: 0}}>

          {/* Cliente */}
          <div className="card card-pad">
            <SectionLabel style={{marginBottom: 14}}>Cliente</SectionLabel>
            <div style={{display: 'grid', gap: 14}}>
              <div className="field-row">
                <div className="field-group">
                  <label className="field-label">Empresa</label>
                  <input className="field-input" value={quote.client.company} onChange={e => patch('client.company', e.target.value)} />
                </div>
                <div className="field-group">
                  <label className="field-label">Contacto</label>
                  <input className="field-input" value={quote.client.contact} onChange={e => patch('client.contact', e.target.value)} />
                </div>
              </div>
              <div className="field-row">
                <div className="field-group">
                  <label className="field-label">Email</label>
                  <input className="field-input" value={quote.client.email} onChange={e => patch('client.email', e.target.value)} />
                </div>
                <div className="field-group">
                  <label className="field-label">RFC</label>
                  <input className="field-input" value={quote.client.rfc} onChange={e => patch('client.rfc', e.target.value)} />
                </div>
              </div>
              <div className="field-group">
                <label className="field-label">Domicilio fiscal</label>
                <input className="field-input" value={quote.client.address} onChange={e => patch('client.address', e.target.value)} />
              </div>
            </div>
          </div>

          {/* Proyecto */}
          <div className="card card-pad">
            <SectionLabel style={{marginBottom: 14}}>Proyecto</SectionLabel>
            <div style={{display: 'grid', gap: 14}}>
              <div className="field-row">
                <div className="field-group">
                  <label className="field-label">Nombre del proyecto</label>
                  <input className="field-input" value={quote.project.name} onChange={e => patch('project.name', e.target.value)} />
                </div>
                <div className="field-group">
                  <label className="field-label">Tipo de proyecto</label>
                  <input className="field-input" placeholder="Ej. Sitio web institucional + e-commerce" value={quote.project.type || ''} onChange={e => patch('project.type', e.target.value)} />
                </div>
              </div>
              <div className="field-group">
                <label className="field-label">Resumen ejecutivo <span style={{color: 'var(--text-2)', fontWeight: 400, fontSize: 11}}>· 2–3 oraciones que demuestran que entendiste el proyecto</span></label>
                <textarea className="field-textarea" value={quote.project.summary} onChange={e => patch('project.summary', e.target.value)} />
              </div>
              <div className="field-row">
                <div className="field-group">
                  <label className="field-label">Inicio estimado</label>
                  <input className="field-input" value={quote.project.startDate} onChange={e => patch('project.startDate', e.target.value)} />
                </div>
                <div className="field-group">
                  <label className="field-label">Duración total</label>
                  <input className="field-input" value={quote.project.duration} onChange={e => patch('project.duration', e.target.value)} />
                </div>
              </div>
            </div>
          </div>

          {/* Alcance */}
          <div className="card card-pad">
            <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 14}}>
              <SectionLabel>Alcance · entregables</SectionLabel>
              <span style={{fontSize: 12, color: 'var(--text-2)'}}>{(quote.scope || []).length} de 5–7 recomendados</span>
            </div>
            <div style={{display: 'grid', gap: 10}}>
              {(quote.scope || []).map((s, i) => (
                <div key={i} style={{display: 'grid', gridTemplateColumns: '32px 1fr 28px', gap: 12, alignItems: 'start'}}>
                  <div style={{paddingTop: 8, fontFamily: 'Poppins', fontWeight: 700, color: 'var(--primary)', fontSize: 18, fontVariantNumeric: 'tabular-nums'}}>{String(i + 1).padStart(2, '0')}</div>
                  <div style={{display: 'grid', gap: 6}}>
                    <input className="field-input" placeholder="Título del entregable" value={s.title} onChange={e => updateQuote(quote.id, prev => ({ ...prev, scope: prev.scope.map((x, j) => j === i ? { ...x, title: e.target.value } : x) }))} />
                    <input className="field-input" style={{fontSize: 13}} placeholder="Descripción corta" value={s.desc} onChange={e => updateQuote(quote.id, prev => ({ ...prev, scope: prev.scope.map((x, j) => j === i ? { ...x, desc: e.target.value } : x) }))} />
                  </div>
                  <button className="item-remove" onClick={() => updateQuote(quote.id, prev => ({ ...prev, scope: prev.scope.filter((_, j) => j !== i) }))} title="Eliminar"><Icon.trash /></button>
                </div>
              ))}
              <button className="btn btn-ghost" style={{justifySelf: 'start'}} onClick={() => updateQuote(quote.id, prev => ({ ...prev, scope: [...(prev.scope || []), { title: '', desc: '' }] }))}><Icon.plus /> Agregar entregable</button>
            </div>
          </div>

          {/* Fases */}
          <div className="card card-pad">
            <SectionLabel style={{marginBottom: 14}}>Tiempos de entrega · fases</SectionLabel>
            <div style={{display: 'grid', gap: 14}}>
              {(quote.phases || []).map((p, i) => (
                <div key={i} style={{display: 'grid', gap: 8}}>
                  <div style={{display: 'grid', gridTemplateColumns: '60px 1fr 140px 28px', gap: 12, alignItems: 'center'}}>
                    <div style={{fontFamily: 'Poppins', fontWeight: 500, fontSize: 11, color: 'var(--text-2)', letterSpacing: 2, textTransform: 'uppercase'}}>Fase {String(i + 1).padStart(2, '0')}</div>
                    <input className="field-input" placeholder="Nombre de la fase" value={p.name} onChange={e => updateQuote(quote.id, prev => ({ ...prev, phases: prev.phases.map((x, j) => j === i ? { ...x, name: e.target.value } : x) }))} />
                    <input className="field-input" placeholder="Ej. 2 semanas" value={p.duration} onChange={e => updateQuote(quote.id, prev => ({ ...prev, phases: prev.phases.map((x, j) => j === i ? { ...x, duration: e.target.value } : x) }))} />
                    <button className="item-remove" onClick={() => updateQuote(quote.id, prev => ({ ...prev, phases: prev.phases.filter((_, j) => j !== i) }))}><Icon.trash /></button>
                  </div>
                  <div style={{paddingLeft: 72}}>
                    <input className="field-input" style={{fontSize: 13}} placeholder="Descripción de la fase (entregables, actividades clave…)" value={p.desc || ''} onChange={e => updateQuote(quote.id, prev => ({ ...prev, phases: prev.phases.map((x, j) => j === i ? { ...x, desc: e.target.value } : x) }))} />
                  </div>
                </div>
              ))}
              <button className="btn btn-ghost" style={{justifySelf: 'start'}} onClick={() => updateQuote(quote.id, prev => ({ ...prev, phases: [...(prev.phases || []), { name: '', duration: '1 semana' }] }))}><Icon.plus /> Agregar fase</button>
            </div>
          </div>

          {/* No incluye */}
          <div className="card card-pad">
            <SectionLabel style={{marginBottom: 14}}>No incluye</SectionLabel>
            <div style={{display: 'flex', flexWrap: 'wrap', gap: 8, marginBottom: 12}}>
              {(quote.excludes || []).map((x, i) => (
                <span key={i} className="exclude-pill" style={{cursor: 'pointer'}} onClick={() => updateQuote(quote.id, prev => ({ ...prev, excludes: prev.excludes.filter((_, j) => j !== i) }))}>
                  {x} <span style={{marginLeft: 4, color: 'var(--text-2)'}}>×</span>
                </span>
              ))}
            </div>
            <div style={{display: 'flex', gap: 8}}>
              <input className="field-input" placeholder="Agregar exclusión y presiona Enter" onKeyDown={e => {
                if (e.key === 'Enter' && e.target.value.trim()) {
                  const v = e.target.value.trim();
                  updateQuote(quote.id, prev => ({ ...prev, excludes: [...(prev.excludes || []), v] }));
                  e.target.value = '';
                }
              }} />
            </div>
          </div>

          {/* Por qué nosotros */}
          <div className="card card-pad">
            <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 14}}>
              <SectionLabel>¿Por qué trabajar con nosotros?</SectionLabel>
              <span style={{fontSize: 12, color: 'var(--text-2)'}}>máx. 3 bullets</span>
            </div>
            <div style={{display: 'grid', gap: 10}}>
              {(quote.whyUs || []).map((b, i) => (
                <div key={i} style={{display: 'grid', gridTemplateColumns: '24px 1fr 28px', gap: 10, alignItems: 'center'}}>
                  <span style={{fontFamily: 'Poppins', fontWeight: 700, color: 'var(--primary)', fontSize: 16, textAlign: 'center'}}>✦</span>
                  <input className="field-input" value={b} onChange={e => updateQuote(quote.id, prev => ({ ...prev, whyUs: prev.whyUs.map((x, j) => j === i ? e.target.value : x) }))} />
                  <button className="item-remove" onClick={() => updateQuote(quote.id, prev => ({ ...prev, whyUs: prev.whyUs.filter((_, j) => j !== i) }))}><Icon.trash /></button>
                </div>
              ))}
              {(quote.whyUs || []).length < 3 && (
                <button className="btn btn-ghost" style={{justifySelf: 'start'}} onClick={() => updateQuote(quote.id, prev => ({ ...prev, whyUs: [...(prev.whyUs || []), ''] }))}><Icon.plus /> Agregar bullet</button>
              )}
            </div>
          </div>

          {/* Próximos pasos */}
          <div className="card card-pad">
            <SectionLabel style={{marginBottom: 14}}>Próximos pasos <span style={{color: 'var(--text-2)', textTransform: 'none', letterSpacing: 0, fontSize: 11, marginLeft: 8}}>· una sola oración de acción clara</span></SectionLabel>
            <textarea className="field-textarea" style={{minHeight: 70}} value={quote.nextStep || ''} onChange={e => patch('nextStep', e.target.value)} />
          </div>

          {/* Conceptos */}
          <div className="card items-card">
            <div className="items-head">
              <SectionLabel></SectionLabel>
              <SectionLabel>Concepto</SectionLabel>
              <SectionLabel style={{textAlign: 'right'}}>Cant.</SectionLabel>
              <SectionLabel style={{textAlign: 'right'}}>P. Unit.</SectionLabel>
              <SectionLabel style={{textAlign: 'right'}}>Importe</SectionLabel>
              <SectionLabel></SectionLabel>
            </div>
            {quote.items.map(it => (
              <div className="item-row" key={it.id}>
                <div className="handle"><Icon.drag /></div>
                <div className="item-desc">
                  <input value={it.name} onChange={e => patchItem(it.id, 'name', e.target.value)} />
                  <input className="subdesc" placeholder="Descripción / alcance" value={it.sub || ''} onChange={e => patchItem(it.id, 'sub', e.target.value)} />
                </div>
                <div className="item-qty">
                  <input type="number" min="0" value={it.qty} onChange={e => patchItem(it.id, 'qty', Number(e.target.value) || 0)} />
                  <div style={{textAlign: 'right', fontSize: 11, color: 'var(--text-2)', marginTop: 2}}>{it.unit}</div>
                </div>
                <div className="item-price">
                  <input type="number" min="0" value={it.price} onChange={e => patchItem(it.id, 'price', Number(e.target.value) || 0)} />
                </div>
                <div className="item-total">{fmtMXNshort(it.qty * it.price)}</div>
                <button className="item-remove" onClick={() => removeItem(it.id)} title="Eliminar"><Icon.trash /></button>
              </div>
            ))}
            <div className="items-foot">
              <div className="catalog-picker">
                <button className="btn btn-secondary" onClick={() => setCatalogOpen(o => !o)}>
                  <Icon.plus /> Agregar del catálogo <Icon.chev />
                </button>
                {catalogOpen && (
                  <div className="catalog-menu">
                    <SectionLabel style={{padding: '6px 12px 8px'}}>Catálogo de servicios</SectionLabel>
                    {CATALOG.map(c => (
                      <div className="catalog-item" key={c.id} onClick={() => addFromCatalog(c)}>
                        <div>
                          <div className="ci-name">{c.name}</div>
                          <div className="ci-sub">{c.sub}</div>
                        </div>
                        <div style={{textAlign: 'right'}}>
                          <div className="ci-price">{fmtMXNshort(c.price)}</div>
                          <div className="ci-sub">/ {c.unit}</div>
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </div>
              <button className="btn btn-ghost" onClick={addBlank}><Icon.plus /> Renglón en blanco</button>
              <div style={{marginLeft: 'auto', fontSize: 13, color: 'var(--text-2)'}}>
                {quote.items.length} conceptos · subtotal {fmtMXN(tot.subtotal)}
              </div>
            </div>
          </div>

          {/* Esquema de pago */}
          <div className="card card-pad">
            <SectionLabel style={{marginBottom: 14}}>Esquema de pago</SectionLabel>
            <div style={{display: 'grid', gap: 10}}>
              {quote.schedule.map((s, i) => (
                <div key={i} style={{display: 'grid', gridTemplateColumns: '1fr 100px 140px', gap: 12, alignItems: 'center'}}>
                  <input className="field-input" value={s.label} onChange={e => {
                    updateQuote(quote.id, prev => ({ ...prev, schedule: prev.schedule.map((x, j) => j === i ? { ...x, label: e.target.value } : x) }));
                  }} />
                  <div style={{display: 'flex', alignItems: 'center', gap: 6}}>
                    <input className="field-input" type="number" min="0" max="100" style={{textAlign: 'right'}} value={s.pct} onChange={e => setSchedulePct(i, e.target.value)} />
                    <span style={{color: 'var(--text-2)'}}>%</span>
                  </div>
                  <div style={{textAlign: 'right', fontFamily: 'Poppins', fontWeight: 700, fontVariantNumeric: 'tabular-nums'}}>
                    {fmtMXN(tot.total * s.pct / 100)}
                  </div>
                </div>
              ))}
              <div style={{fontSize: 12, color: quote.schedule.reduce((s,x)=>s+x.pct,0) === 100 ? 'var(--text-2)' : 'var(--red)'}}>
                Suma: {quote.schedule.reduce((s,x)=>s+x.pct,0)}%
              </div>
            </div>
          </div>

          {/* Términos */}
          <div className="card card-pad">
            <SectionLabel style={{marginBottom: 14}}>Términos y condiciones</SectionLabel>
            <textarea className="field-textarea" style={{minHeight: 120}} value={quote.terms} onChange={e => patch('terms', e.target.value)} />
          </div>
        </div>

        {/* SIDEBAR — Totales */}
        <div className="totals-side">
          <div className="card totals-card">
            <SectionLabel>Resumen</SectionLabel>
            <div className="totals-row" style={{marginTop: 14}}>
              <span className="lbl">Subtotal</span>
              <span className="val">{fmtMXN(tot.subtotal)}</span>
            </div>
            <div className="totals-row discount">
              <span className="lbl">
                Descuento{' '}
                <span style={{fontSize: 12, color: 'var(--text-2)'}}>
                  ({quote.discount?.type === 'pct' ? `${quote.discount.value}%` : 'fijo'})
                </span>
              </span>
              <span className="val">− {fmtMXN(tot.discount)}</span>
            </div>
            <div className="totals-row">
              <span className="lbl">IVA 16%</span>
              <span className="val">{fmtMXN(tot.iva)}</span>
            </div>
            <div className="totals-row grand">
              <span className="lbl">Total</span>
              <span className="val">{fmtMXNshort(tot.total)}</span>
            </div>

            <div style={{display: 'flex', gap: 8, marginTop: 14, flexWrap: 'wrap'}}>
              <button className="chip" onClick={() => patch('discount', { type: 'pct', value: quote.discount?.type === 'pct' ? 0 : 5 })}>
                {quote.discount?.value ? 'Quitar descuento' : '+ Descuento 5%'}
              </button>
            </div>
          </div>

          <div className="card totals-card">
            <SectionLabel>Calendario de pagos</SectionLabel>
            {quote.schedule.map((s, i) => (
              <div className="schedule-row" key={i} style={{marginTop: i === 0 ? 10 : 0}}>
                <div>
                  <div style={{fontFamily: 'Poppins', fontWeight: 500, fontSize: 13.5}}>{s.label}</div>
                  <div className="when">{s.pct}% del total</div>
                </div>
                <div className="amount">{fmtMXNshort(tot.total * s.pct / 100)}</div>
              </div>
            ))}
          </div>

          <div className="card totals-card">
            <SectionLabel>Vigencia</SectionLabel>
            <div style={{marginTop: 12, fontFamily: 'Poppins', fontWeight: 600, fontSize: 16}}>
              {fmtDateLong(quote.validUntil)}
            </div>
            <div style={{fontSize: 12.5, color: 'var(--text-2)', marginTop: 4}}>
              30 días desde el envío
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ============================== PREVIEW (client-facing) ============================== */
/* Structure:
 *  1  Header — ID · Fecha · Válida hasta
 *  2  Datos del cliente — Empresa · Contacto · Tipo de proyecto
 *  3  Resumen ejecutivo
 *  4  Objetivo del proyecto
 *  5  Tecnología
 *  6  Alcance — entregables numerados
 *  7  Inversión — desglose + total + nota IVA / pago
 *  8  Tiempos de entrega — fases
 *  9  No incluye — pills
 * 10  Próximos pasos
 * 11  Footer — contacto agencia
 */
function downloadPDF(quote) {
  const el = document.getElementById('preview-doc-root');
  if (!el || !window.html2pdf) return;
  const filename = `Propuesta_${(quote.client?.company || 'Cliente').replace(/\s+/g, '_')}_${quote.id || 'SC'}.pdf`;
  window.html2pdf().set({
    margin: 0,
    filename,
    image: { type: 'jpeg', quality: 0.97 },
    html2canvas: { scale: 2, useCORS: true, logging: false },
    jsPDF: { unit: 'px', format: [880, 1120], orientation: 'portrait' },
    pagebreak: { mode: ['avoid-all', 'css', 'legacy'] },
  }).from(el).save();
}

function Preview({ quote, back, openEditor }) {
  if (!quote) return null;
  const tot = computeTotals(quote);
  const [copied, setCopied] = React.useState(false);

  function handleCopyLink() {
    const token = quote.token;
    if (!token) return;
    const url = `${window.location.origin}/propuesta/${token}`;
    navigator.clipboard.writeText(url).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  }

  /* parse phase duration to weeks for bar visualization */
  const parseWeeks = (s) => {
    const m = String(s).match(/([\d.]+)/);
    return m ? parseFloat(m[1]) : 1;
  };
  const phases = quote.phases || [];
  const maxPhase = Math.max(1, ...phases.map(p => parseWeeks(p.duration)));
  const totalWeeks = phases.reduce((s, p) => s + parseWeeks(p.duration), 0);

  return (
    <div className="preview-stage">
      <div style={{maxWidth: 880, margin: '0 auto 20px'}}>
        <div className="preview-toolbar">
          <button className="editor-back" onClick={back} style={{margin: 0}}><Icon.back /> Volver al panel</button>
          <div style={{display: 'flex', gap: 10}}>
            <button className="btn btn-secondary" onClick={() => openEditor(quote.id)}>Editar</button>
            <button className="btn btn-secondary" onClick={() => downloadPDF(quote)}><Icon.dl /> Descargar PDF</button>
            <button className="btn btn-secondary" onClick={handleCopyLink}>
              {copied ? <><Icon.check /> ¡Copiado!</> : <><Icon.copy /> Copiar enlace</>}
            </button>
            <button className="btn btn-primary"><Icon.send /> Enviar al cliente</button>
          </div>
        </div>
      </div>

      <div className="preview-doc" id="preview-doc-root">

        {/* 1 — HEADER */}
        <div className="doc-hero">
          <div className="doc-hero-top">
            <Brand />
            <div style={{textAlign: 'right'}}>
              <div style={{fontFamily: 'Poppins', fontWeight: 400, fontSize: 11, letterSpacing: 3, textTransform: 'uppercase', color: 'rgba(255,255,255,0.45)', marginBottom: 6}}>Propuesta de Proyecto</div>
              <div className="doc-num">{quote.id}</div>
              <div style={{color: 'rgba(255,255,255,0.55)', fontSize: 12.5, marginTop: 6, fontWeight: 400}}>Emitida {fmtDateLong(quote.createdAt)}</div>
            </div>
          </div>
          <h1>{quote.project.name}</h1>
          <div className="doc-sub">Preparada para {quote.client.company}</div>
          <div className="doc-meta-grid">
            <div>
              <div className="label">ID de propuesta</div>
              <div className="value">{quote.id}</div>
              <div style={{color: 'rgba(255,255,255,0.6)', fontSize: 13, fontWeight: 400, marginTop: 2}}>Folio interno</div>
            </div>
            <div>
              <div className="label">Fecha</div>
              <div className="value">{fmtDateLong(quote.createdAt)}</div>
              <div style={{color: 'rgba(255,255,255,0.6)', fontSize: 13, fontWeight: 400, marginTop: 2}}>Día de emisión</div>
            </div>
            <div>
              <div className="label">Válida hasta</div>
              <div className="value">{fmtDateLong(quote.validUntil)}</div>
              <div style={{color: 'rgba(255,255,255,0.6)', fontSize: 13, fontWeight: 400, marginTop: 2}}>30 días naturales</div>
            </div>
          </div>
        </div>

        <div className="doc-body">

          {/* 2 — DATOS DEL CLIENTE */}
          <div className="doc-section">
            <SectionLabel>02 · Datos del cliente</SectionLabel>
            <h2 style={{marginBottom: 14}}>Para quién es esta propuesta</h2>
            <div className="client-strip">
              <div>
                <div className="label">Empresa</div>
                <div className="value">{quote.client.company}</div>
                <div className="sub">{quote.client.address}</div>
              </div>
              <div>
                <div className="label">Contacto</div>
                <div className="value">{quote.client.contact || '—'}</div>
                <div className="sub">{quote.client.email}</div>
              </div>
              <div>
                <div className="label">Tipo de proyecto</div>
                <div className="value">{quote.project.type || quote.project.name}</div>
                <div className="sub">Vigencia {fmtDateLong(quote.validUntil)}</div>
              </div>
            </div>
          </div>

          {/* 3 — RESUMEN EJECUTIVO */}
          <div className="doc-section">
            <SectionLabel>03 · Resumen ejecutivo</SectionLabel>
            <h2>Cómo entendemos el proyecto</h2>
            <p className="executive-summary">{quote.project.summary}</p>
          </div>

          {/* 4 — ALCANCE */}
          <div className="doc-section">
            <SectionLabel>04 · Alcance del proyecto</SectionLabel>
            <h2>Entregables</h2>
            <div className="scope-list">
              {(quote.scope || []).map((it, i) => (
                <div className="scope-item" key={i}>
                  <div className="num">{String(i + 1).padStart(2, '0')}</div>
                  <div>
                    <div className="title">{it.title}</div>
                    <div className="desc">{it.desc}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>

          {/* 5 — INVERSIÓN */}
          <div className="doc-section">
            <SectionLabel>05 · Inversión</SectionLabel>
            <h2>Desglose y total</h2>
            <table className="invest-table">
              <thead>
                <tr>
                  <th>Concepto</th>
                  <th className="r" style={{width: 160}}>Precio</th>
                </tr>
              </thead>
              <tbody>
                {quote.items.map(it => (
                  <tr key={it.id}>
                    <td className="desc">
                      <div className="name">{it.name}</div>
                      {it.sub && <div className="sub">{it.sub}</div>}
                    </td>
                    <td className="tot r">{fmtMXNshort(it.qty * it.price)}</td>
                  </tr>
                ))}
              </tbody>
            </table>

            <div className="total-band">
              <div>
                <div className="label">Total de la inversión</div>
                <div className="total">{fmtMXNshort(tot.total)}<span className="ccy">MXN</span></div>
              </div>
              <div className="breakdown">
                <div>Subtotal · <b>{fmtMXNshort(tot.subtotal)}</b></div>
                {tot.discount > 0 && <div>Descuento · <b>− {fmtMXNshort(tot.discount)}</b></div>}
                <div>IVA 16% · <b>{fmtMXNshort(tot.iva)}</b></div>
              </div>
            </div>

            <div className="invest-note">
              <span><b>IVA</b> 16% incluido en el total.</span>
              <span><b>Forma de pago</b> {paymentSummary(quote)} · {quote.schedule.map(s => s.label).join(' / ')}.</span>
            </div>
          </div>

          {/* 6 — TIEMPOS DE ENTREGA */}
          <div className="doc-section">
            <SectionLabel>06 · Tiempos de entrega</SectionLabel>
            <h2>Fases del proyecto</h2>
            <div className="timeline">
              {phases.map((p, i) => {
                const w = parseWeeks(p.duration);
                const pct = (w / maxPhase) * 100;
                return (
                  <div className="timeline-row" key={i}>
                    <div className="step">Fase {String(i + 1).padStart(2, '0')}</div>
                    <div>
                      <div className="name">{p.name}</div>
                      {p.desc && <div style={{fontSize: 13.5, color: 'var(--text-2)', marginTop: 3, marginBottom: 6}}>{p.desc}</div>}
                      <div className="timeline-bar"><i style={{width: pct + '%'}}></i></div>
                    </div>
                    <div className="duration">{p.duration}</div>
                  </div>
                );
              })}
            </div>
            <div className="timeline-total">
              <span className="l">Total estimado</span>
              <span className="v">{quote.project.duration || (totalWeeks + ' semanas')}</span>
            </div>
          </div>

          {/* 7 — NO INCLUYE */}
          <div className="doc-section">
            <SectionLabel>07 · No incluye</SectionLabel>
            <h2>Fuera del alcance de esta propuesta</h2>
            <div className="exclude-list">
              {(quote.excludes || []).map((x, i) => (
                <span className="exclude-pill" key={i}>{x}</span>
              ))}
            </div>
          </div>

          {/* 8 — POR QUÉ NOSOTROS */}
          {(() => {
            const bullets = (quote.whyUs && quote.whyUs.length > 0)
              ? quote.whyUs
              : ['8 años diseñando experiencias digitales en CDMX', 'Proceso de revisión abierto y colaborativo en cada etapa', 'Soporte real después de la entrega, no desaparecemos'];
            return (
              <div className="doc-section">
                <SectionLabel>08 · ¿Por qué trabajar con nosotros?</SectionLabel>
                <h2>Lo que nos diferencia</h2>
                <div style={{display: 'grid', gap: 14, marginTop: 4}}>
                  {bullets.slice(0, 3).map((b, i) => (
                    <div key={i} style={{display: 'flex', gap: 16, alignItems: 'flex-start'}}>
                      <span style={{fontFamily: 'Poppins', fontWeight: 700, fontSize: 18, color: 'var(--primary)', lineHeight: 1.3, flexShrink: 0}}>✦</span>
                      <span style={{fontSize: 15.5, lineHeight: 1.6}}>{b}</span>
                    </div>
                  ))}
                </div>
              </div>
            );
          })()}

          {/* 9 — PRÓXIMOS PASOS */}
          <div className="doc-section">
            <SectionLabel>09 · Próximos pasos</SectionLabel>
            <h2>Para arrancar el proyecto</h2>
            <div className="next-step-card">
              <div className="ns-text">{quote.nextStep || 'Acepta la propuesta para comenzar.'}</div>
              <div style={{display: 'flex', gap: 10}}>
                <button className="btn btn-lg" style={{background: 'rgba(255,255,255,0.15)', color: '#fff', border: '1px solid rgba(255,255,255,0.3)'}}>Tengo dudas</button>
                <button className="btn btn-lg"><Icon.check /> Aceptar propuesta</button>
              </div>
            </div>
          </div>
        </div>

        {/* 11 — FOOTER */}
        <div className="doc-foot">
          <div>
            <div style={{fontFamily: 'Poppins', fontWeight: 700, color: 'var(--text)', fontSize: 14}}>Source Code Studio S.A. de C.V.</div>
            <div>RFC SCS210418F11 · Av. Insurgentes Sur 1602, Ciudad de México</div>
          </div>
          <div style={{textAlign: 'right'}}>
            <div>hola@sourcecode.mx · +52 55 4321 8800</div>
            <div style={{fontFamily: 'Poppins', fontWeight: 600, color: 'var(--primary)'}}>sourcecode.mx</div>
          </div>
        </div>
      </div>
    </div>
  );
}

function ClientPreview({ quote }) {
  if (!quote) return null;
  const [dlBusy, setDlBusy] = React.useState(false);

  function handleDownload() {
    if (dlBusy || !window.html2pdf) return;
    setDlBusy(true);
    const el = document.getElementById('client-doc-root');
    const filename = `Propuesta_${(quote.client?.company || 'Cliente').replace(/\s+/g, '_')}.pdf`;
    window.html2pdf().set({
      margin: 0,
      filename,
      image: { type: 'jpeg', quality: 0.97 },
      html2canvas: { scale: 2, useCORS: true, logging: false },
      jsPDF: { unit: 'px', format: [880, 1120], orientation: 'portrait' },
      pagebreak: { mode: ['avoid-all', 'css', 'legacy'] },
    }).from(el).save().then(() => setDlBusy(false)).catch(() => setDlBusy(false));
  }

  const tot = computeTotals(quote);
  const parseWeeks = (s) => { const m = String(s).match(/([\d.]+)/); return m ? parseFloat(m[1]) : 1; };
  const phases = quote.phases || [];
  const maxPhase = Math.max(1, ...phases.map(p => parseWeeks(p.duration)));
  const totalWeeks = phases.reduce((s, p) => s + parseWeeks(p.duration), 0);
  const whyUs = quote.whyUs?.length ? quote.whyUs : ['Equipo especializado con más de 8 años en proyectos digitales.', 'Proceso claro y entregas puntuales en cada etapa.', 'Soporte continuo y comunicación directa durante todo el proyecto.'];

  return (
    <div>
      <div className="client-topbar">
        <Brand />
        <button className="btn-dl" onClick={handleDownload} disabled={dlBusy}>
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none"><path d="M12 4v12m0 0l-4-4m4 4l4-4M5 20h14" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"/></svg>
          {dlBusy ? 'Generando…' : 'Descargar PDF'}
        </button>
      </div>

      <div className="preview-stage">
        <div className="preview-doc" id="client-doc-root">

          {/* 1 — HEADER */}
          <div className="doc-hero">
            <div className="doc-hero-top">
              <Brand />
              <div style={{textAlign: 'right'}}>
                <div style={{fontFamily: 'Poppins', fontWeight: 400, fontSize: 11, letterSpacing: 3, textTransform: 'uppercase', color: 'rgba(255,255,255,0.45)', marginBottom: 6}}>Propuesta de Proyecto</div>
                <div className="doc-num">{quote.id}</div>
                <div style={{color: 'rgba(255,255,255,0.55)', fontSize: 12.5, marginTop: 6, fontWeight: 400}}>Emitida {fmtDateLong(quote.createdAt)}</div>
              </div>
            </div>
            <h1>{quote.project?.name}</h1>
            <div className="doc-sub">Preparada para {quote.client?.company}</div>
            <div className="doc-meta-grid">
              <div><div className="label">ID de propuesta</div><div className="value">{quote.id}</div><div style={{color: 'rgba(255,255,255,0.6)', fontSize: 13, fontWeight: 400, marginTop: 2}}>Folio interno</div></div>
              <div><div className="label">Fecha</div><div className="value">{fmtDateLong(quote.createdAt)}</div><div style={{color: 'rgba(255,255,255,0.6)', fontSize: 13, fontWeight: 400, marginTop: 2}}>Día de emisión</div></div>
              <div><div className="label">Válida hasta</div><div className="value">{fmtDateLong(quote.validUntil)}</div><div style={{color: 'rgba(255,255,255,0.6)', fontSize: 13, fontWeight: 400, marginTop: 2}}>30 días naturales</div></div>
            </div>
          </div>

          {/* 2 — DATOS DEL CLIENTE */}
          <div className="doc-section">
            <SectionLabel>01 · Datos del cliente</SectionLabel>
            <div className="doc-client-grid">
              <div><div className="label">Empresa</div><div className="value-lg">{quote.client?.company || '—'}</div></div>
              <div><div className="label">Contacto</div><div className="value-lg">{quote.client?.contact || '—'}</div></div>
              <div><div className="label">Correo electrónico</div><div className="value-lg">{quote.client?.email || '—'}</div></div>
              {quote.client?.rfc && <div><div className="label">RFC</div><div className="value-lg">{quote.client.rfc}</div></div>}
            </div>
          </div>

          {/* 3 — RESUMEN EJECUTIVO */}
          <div className="doc-section">
            <SectionLabel>02 · Resumen ejecutivo</SectionLabel>
            <div className="doc-summary-box">
              <div className="doc-project-type">{quote.project?.type}</div>
              <p className="doc-summary-text">{quote.project?.summary}</p>
              <div className="doc-summary-meta">
                <div><span className="label">Inicio estimado</span><span className="value">{quote.project?.startDate || 'A convenir'}</span></div>
                <div><span className="label">Duración total</span><span className="value">{quote.project?.duration}</span></div>
              </div>
            </div>
          </div>

          {/* 4 — ALCANCE */}
          <div className="doc-section">
            <SectionLabel>03 · Alcance del proyecto</SectionLabel>
            <div className="doc-scope-grid">
              {(quote.scope || []).map((s, i) => (
                <div key={i} className="doc-scope-card">
                  <div className="scope-num">0{i + 1}</div>
                  <div className="scope-title">{s.title}</div>
                  <div className="scope-desc">{s.desc}</div>
                </div>
              ))}
            </div>
          </div>

          {/* 5 — INVERSIÓN */}
          <div className="doc-section">
            <SectionLabel>04 · Inversión</SectionLabel>
            <table className="doc-table">
              <thead><tr><th>Concepto</th><th style={{textAlign: 'right'}}>Precio</th></tr></thead>
              <tbody>
                {(quote.items || []).map((it, i) => (
                  <tr key={i}>
                    <td><div style={{fontWeight: 600}}>{it.name}</div><div className="sub">{it.sub}</div></td>
                    <td style={{textAlign: 'right', fontFamily: 'Poppins', fontWeight: 600}}>{fmtMXN(it.qty * it.price)}</td>
                  </tr>
                ))}
              </tbody>
              <tfoot>
                {tot.discount > 0 && <tr className="subtotal-row"><td>Subtotal</td><td style={{textAlign: 'right'}}>{fmtMXN(tot.subtotal)}</td></tr>}
                {tot.discount > 0 && <tr className="discount-row"><td>Descuento</td><td style={{textAlign: 'right', color: '#22C55E'}}>−{fmtMXN(tot.discount)}</td></tr>}
                <tr className="iva-row"><td>IVA 16%</td><td style={{textAlign: 'right'}}>{fmtMXN(tot.iva)}</td></tr>
                <tr className="total-row"><td>Total</td><td style={{textAlign: 'right'}}>{fmtMXN(tot.total)}</td></tr>
              </tfoot>
            </table>
            {(quote.schedule || []).length > 0 && (
              <div className="doc-schedule">
                <div className="label" style={{marginBottom: 10}}>Esquema de pagos</div>
                <div className="schedule-pills">
                  {quote.schedule.map((s, i) => (
                    <div key={i} className="schedule-pill">
                      <span className="sched-label">{s.label}</span>
                      <span className="sched-pct">{s.pct}%</span>
                      <span className="sched-amt">{fmtMXN(tot.total * s.pct / 100)}</span>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>

          {/* 6 — TIEMPOS */}
          <div className="doc-section">
            <SectionLabel>05 · Tiempos de entrega</SectionLabel>
            <div className="label" style={{marginBottom: 14}}>Duración total estimada: <strong>{totalWeeks} semanas</strong></div>
            {phases.map((p, i) => (
              <div key={i} className="phase-row">
                <div className="phase-meta">
                  <span className="phase-name">{p.name}</span>
                  <span className="phase-dur">{p.duration}</span>
                </div>
                {p.desc && <div style={{fontSize: 13, color: 'var(--text-muted)', marginBottom: 8}}>{p.desc}</div>}
                <div className="phase-bar-track">
                  <div className="phase-bar-fill" style={{width: `${(parseWeeks(p.duration) / maxPhase) * 100}%`}} />
                </div>
              </div>
            ))}
          </div>

          {/* 7 — NO INCLUYE */}
          {(quote.excludes || []).length > 0 && (
            <div className="doc-section">
              <SectionLabel>06 · No incluye</SectionLabel>
              <ul className="doc-excludes">
                {quote.excludes.map((e, i) => <li key={i}>{e}</li>)}
              </ul>
            </div>
          )}

          {/* 8 — POR QUÉ NOSOTROS */}
          <div className="doc-section">
            <SectionLabel>07 · ¿Por qué trabajar con nosotros?</SectionLabel>
            <div className="doc-why-grid">
              {whyUs.map((w, i) => (
                <div key={i} className="doc-why-card">
                  <span className="why-bullet">✦</span>
                  <p>{w}</p>
                </div>
              ))}
            </div>
          </div>

          {/* 9 — PRÓXIMOS PASOS */}
          <div className="doc-section">
            <SectionLabel>08 · Próximos pasos</SectionLabel>
            <div className="doc-next-box">
              <p className="next-text">{quote.nextStep || 'Confirma el proyecto para iniciar en la fecha acordada.'}</p>
              <div className="next-terms">{quote.terms}</div>
              <div style={{display: 'flex', gap: 12, marginTop: 24}}>
                <button className="btn btn-lg" style={{background: 'rgba(255,255,255,0.15)', color: '#fff', border: '1px solid rgba(255,255,255,0.3)'}}>Tengo dudas</button>
                <button className="btn btn-lg"><Icon.check /> Aceptar propuesta</button>
              </div>
            </div>
          </div>

          {/* FOOTER */}
          <div className="doc-foot">
            <div>
              <div style={{fontFamily: 'Poppins', fontWeight: 700, color: 'var(--text)', fontSize: 14}}>Source Code Studio S.A. de C.V.</div>
              <div>RFC SCS210418F11 · Av. Insurgentes Sur 1602, Ciudad de México</div>
            </div>
            <div style={{textAlign: 'right'}}>
              <div>hola@sourcecode.mx · +52 55 4321 8800</div>
              <div style={{fontFamily: 'Poppins', fontWeight: 600, color: 'var(--primary)'}}>sourcecode.mx</div>
            </div>
          </div>

        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Dashboard, Editor, Preview, ClientPreview });
