// ========= DASHBOARD PAGE — A-D grading system =========
const { useState, useEffect } = React;

// Grading: audit_data.score puede venir como 0-10 o 0-100. Normalizamos a 0-100.
const toGrade = (s) => {
  if (s >= 85) return { g: 'A', tag: 'good', label: 'Excelente' };
  if (s >= 70) return { g: 'B', tag: 'good', label: 'Bueno' };
  if (s >= 55) return { g: 'C', tag: 'warn', label: 'Mejorable' };
  if (s >= 30) return { g: 'D', tag: 'bad', label: 'Malo' };
  return { g: 'F', tag: 'bad', label: 'Crítico' };
};

// El backend usa grade letra; mapa letra -> tag visual/label
const gradeMeta = (letter) => {
  const L = (letter || '').toUpperCase();
  if (L === 'A') return { g: 'A', tag: 'good', label: 'Excelente' };
  if (L === 'B') return { g: 'B', tag: 'good', label: 'Bueno' };
  if (L === 'C') return { g: 'C', tag: 'warn', label: 'Medio' };
  if (L === 'D') return { g: 'D', tag: 'bad', label: 'Malo' };
  if (L === 'F') return { g: 'F', tag: 'bad', label: 'Crítico' };
  return { g: '—', tag: 'warn', label: 'N/E' };
};

// Normaliza score a escala 0-100 para barras. Acepta 0-10 o 0-100.
const scoreTo100 = (s) => {
  if (s == null || isNaN(s)) return 0;
  const n = Number(s);
  return n <= 10 ? Math.round(n * 10) : Math.round(n);
};

// Normaliza score a 0-10 para display. Acepta 0-10 o 0-100.
const scoreTo10 = (s) => {
  if (s == null || isNaN(s)) return 0;
  const n = Number(s);
  return n <= 10 ? n : n / 10;
};

const DashHeader = ({ audit, reportId }) => {
  const title = (audit && audit.title) || '—';
  const location = (audit && audit.location) || '—';
  const isPremium = !!(audit && (audit.premium || audit.isPremium));
  const coverImage = audit && (audit.cover_image_url || audit.image_url);
  const initial = (title && title !== '—') ? title.trim().charAt(0).toUpperCase() : 'A';
  const [pdfState, setPdfState] = useState('idle'); // idle | sending | sent | err
  const [shareState, setShareState] = useState('idle'); // idle | copied

  const handleResend = async () => {
    if (!reportId || pdfState === 'sending') return;
    setPdfState('sending');
    try {
      const res = await fetch(`/api/v2/report-resend?id=${encodeURIComponent(reportId)}`, {
        method: 'POST', credentials: 'include',
      });
      if (!res.ok) throw new Error(String(res.status));
      setPdfState('sent');
      setTimeout(() => setPdfState('idle'), 4000);
    } catch (_) {
      setPdfState('err');
      setTimeout(() => setPdfState('idle'), 4000);
    }
  };

  const handleShare = async () => {
    const url = reportId ? `${window.location.origin}/dashboard?id=${encodeURIComponent(reportId)}` : window.location.href;
    try {
      await navigator.clipboard.writeText(url);
      setShareState('copied');
      setTimeout(() => setShareState('idle'), 2000);
    } catch (_) {
      window.prompt('Copia este link:', url);
    }
  };

  return (
    <div className="dash-header">
      <div className="wrap">
        <div className="dash-breadcrumb">
          <a href="/">Inicio</a><span>/</span>
          <a href="/dashboard">Mis propiedades</a><span>/</span>
          <span className="current">{title}</span>
        </div>
        <div className="dash-head-row">
          <div style={{display:'flex', gap: 20, alignItems:'center'}}>
            <div className="property-thumb" aria-hidden>
              {coverImage
                ? <img src={coverImage} alt="" onError={(e) => { e.target.style.display='none'; }} />
                : <>
                    <div className="property-thumb-inner"></div>
                    <span className="property-thumb-initial">{initial}</span>
                  </>
              }
            </div>
            <div>
              <div className={`chip ${isPremium ? 'chip-accent' : ''}`} style={{marginBottom: 10}}>
                {isPremium ? 'Reporte premium' : 'Auditoría gratuita'}
              </div>
              <h1 className="serif" style={{fontSize: 44, letterSpacing:'-0.02em', margin: 0, lineHeight: 1.05}}>
                {title}
              </h1>
              <div className="muted" style={{marginTop: 8, fontSize: 15}}>
                {location}
              </div>
            </div>
          </div>
          <div style={{display:'flex', gap: 8, flexWrap: 'wrap'}}>
            <a className="btn btn-outline" href={audit && audit.url ? `/?url=${encodeURIComponent(audit.url)}` : '/'}>
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/><path d="M12 8v4l3 2"/></svg>
              Re-auditar
            </a>
            {isPremium && (
              <button className="btn btn-outline" onClick={handleResend} disabled={pdfState === 'sending'}>
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
                {pdfState === 'sending' ? 'Enviando…' : pdfState === 'sent' ? '✓ Revisa tu email' : pdfState === 'err' ? 'Reintentar' : 'Re-enviar PDF'}
              </button>
            )}
            <button className="btn btn-primary" onClick={handleShare}>
              {shareState === 'copied' ? '✓ Link copiado' : 'Compartir reporte'}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

const ScoreCard = ({ audit }) => {
  const target = scoreTo100(audit && audit.score);
  const [score, setScore] = useState(0);
  useEffect(() => {
    const start = performance.now(); const dur = 900;
    const tick = (now) => {
      const t = Math.min(1, (now - start) / dur);
      setScore(Math.round((1 - Math.pow(1-t, 3)) * target));
      if (t < 1) requestAnimationFrame(tick);
    };
    requestAnimationFrame(tick);
  }, [target]);
  const grade = toGrade(score);
  return (
    <div className="card card-pad score-card">
      <div className="flex items-center justify-between">
        <span className="eyebrow">Calificación Auditbnb</span>
        <span className={`chip chip-${grade.tag}`}>{grade.label}</span>
      </div>
      <div style={{display:'flex', alignItems:'center', gap: 20, marginTop: 20}}>
        <div className={`grade-badge grade-${grade.tag}`} style={{width: 76, height: 76, fontSize: 48, borderRadius: 14}}>{grade.g}</div>
        <div>
          <div className="score-num" style={{fontSize: 44}}>{(score / 10).toFixed(1)}<sup>/10</sup></div>
          <div className="muted" style={{fontSize: 13, marginTop: 2}}>Basado en 9 categorías</div>
        </div>
      </div>
      <div className="score-bar" style={{marginTop: 20, height: 12}}>
        <div className={`score-bar-fill is-${grade.tag}`} style={{width: `${score}%`}}></div>
      </div>
    </div>
  );
};

const KPICards = ({ audit }) => {
  // KPIs derivados de audit_data cuando existen; sino placeholder "—"
  const score100 = scoreTo100(audit && audit.score);
  const nProblems = (audit && Array.isArray(audit.top_problems)) ? audit.top_problems.length : null;
  const nCats = (audit && Array.isArray(audit.categories)) ? audit.categories.length : null;
  const kpis = [
    { label: 'Score global', val: audit && audit.score != null ? (score100 / 10).toFixed(1) : '—', unit: '/10', sub: 'Calificación Auditbnb' },
    { label: 'Categorías', val: nCats != null ? String(nCats) : '—', unit: 'evaluadas', sub: 'Cobertura del reporte' },
    { label: 'Problemas top', val: nProblems != null ? String(nProblems) : '—', unit: 'detectados', sub: 'Ordenados por impacto' },
    { label: 'Grado', val: (audit && audit.global_grade) || (audit && toGrade(score100).g) || '—', unit: '', sub: 'Letra A–F' },
  ];
  return (
    <div className="kpi-grid">
      {kpis.map(k => (
        <div key={k.label} className="kpi-card">
          <div className="muted" style={{fontSize: 12, textTransform:'uppercase', letterSpacing: '0.08em'}}>{k.label}</div>
          <div className="mono" style={{fontSize: 26, marginTop: 10, fontWeight: 500}}>
            {k.val} {k.unit && <span style={{fontSize: 12, color:'var(--muted)', fontWeight: 400}}>{k.unit}</span>}
          </div>
          <div style={{marginTop: 8, display:'flex', gap: 8, alignItems:'center'}}>
            <span className="muted" style={{fontSize: 12}}>{k.sub}</span>
          </div>
        </div>
      ))}
    </div>
  );
};

const CategoryBreakdown = ({ audit }) => {
  const cats = (audit && Array.isArray(audit.categories)) ? audit.categories : [];
  if (!cats.length) {
    return (
      <div className="card card-pad">
        <h2 className="h3" style={{margin: 0}}>9 categorías evaluadas</h2>
        <div className="muted" style={{fontSize: 13, marginTop: 8}}>—</div>
      </div>
    );
  }
  return (
    <div className="card card-pad">
      <div className="flex items-center justify-between" style={{marginBottom: 24}}>
        <div>
          <h2 className="h3" style={{margin: 0}}>{cats.length} categorías evaluadas</h2>
          <div className="muted" style={{fontSize: 13, marginTop: 4}}>Cada una aporta un peso distinto al score global</div>
        </div>
        <button className="btn btn-ghost" style={{fontSize: 13}}>Ver metodología →</button>
      </div>
      <div className="cats-list">
        {cats.map((c, idx) => {
          const g = gradeMeta(c.grade);
          const name = c.label || c.name || c.key || `Categoría ${idx + 1}`;
          const scoreVal = scoreTo100(c.score);
          const weight = c.weight != null ? c.weight : null;
          const issues = Array.isArray(c.issues) ? c.issues : [];
          const diagnosis = c.diagnosis || (issues[0] || '—');
          return (
            <div key={name + idx} className="cat-row">
              <div className="cat-row-main">
                <div className="flex items-center justify-between" style={{marginBottom: 8}}>
                  <div style={{display:'flex', alignItems:'center', gap: 12, flexWrap:'wrap'}}>
                    <span className={`grade-badge grade-${g.tag}`} style={{width: 28, height: 28, fontSize: 15, borderRadius: 6}}>{g.g}</span>
                    <span style={{fontWeight: 600, fontSize: 15}}>{name}</span>
                    {weight != null && <span className="chip" style={{fontSize: 11}}>Peso {weight}%</span>}
                    {issues.length > 0 && <span className="chip" style={{fontSize: 11}}>{issues.length} issue{issues.length>1?'s':''}</span>}
                  </div>
                  <div className="mono" style={{fontSize: 15}}>{(scoreVal / 10).toFixed(1)}<span className="muted">/10</span></div>
                </div>
                <div className="score-bar" style={{height: 6}}>
                  <div className={`score-bar-fill is-${g.tag}`} style={{width: `${scoreVal}%`}}></div>
                </div>
                <div className="muted" style={{fontSize: 13, marginTop: 10}}>{diagnosis}</div>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

const Improvements = ({ audit }) => {
  const [done, setDone] = useState(new Set());
  const toggle = (i) => { const n = new Set(done); n.has(i) ? n.delete(i) : n.add(i); setDone(n); };
  const raw = (audit && Array.isArray(audit.top_problems)) ? audit.top_problems : [];
  const items = raw.map((p, i) => {
    if (typeof p === 'string') {
      return { cat: 'General', title: p, body: '', impact: 0, effort: '—', priority: i + 1 };
    }
    return {
      cat: p.category || p.cat || 'General',
      title: p.title || p.problem || p.name || `Problema ${i + 1}`,
      body: p.body || p.description || p.diagnosis || '',
      impact: p.impact_mxn || p.impact || 0,
      effort: p.effort || '—',
      priority: p.priority || i + 1,
      note: p.note,
    };
  });
  const totalImpact = items.reduce((a, b) => a + (Number(b.impact) || 0), 0);
  const doneImpact = [...done].reduce((a, i) => a + (Number(items[i]?.impact) || 0), 0);

  if (!items.length) {
    return (
      <div className="card card-pad">
        <h2 className="h3" style={{margin: 0}}>Plan de acción</h2>
        <div className="muted" style={{fontSize: 13, marginTop: 8}}>—</div>
      </div>
    );
  }

  return (
    <div className="card" style={{padding: 0, overflow:'hidden'}}>
      <div style={{padding: 24, display:'flex', justifyContent:'space-between', alignItems:'flex-start', borderBottom: '1px solid var(--line)'}}>
        <div>
          <h2 className="h3" style={{margin: 0}}>Plan de acción</h2>
          <div className="muted" style={{fontSize: 13, marginTop: 4}}>Ordenadas por impacto estimado en reservas</div>
        </div>
        {totalImpact > 0 && (
          <div style={{textAlign:'right'}}>
            <div className="mono" style={{fontSize: 22, fontWeight: 500}}>+${doneImpact.toLocaleString('es-MX')}<span className="muted" style={{fontSize: 14}}> / +${totalImpact.toLocaleString('es-MX')}</span></div>
            <div className="muted" style={{fontSize: 12}}>Revenue recuperado (MXN/mes)</div>
          </div>
        )}
      </div>
      <div className="imp-progress">
        <div className="imp-progress-fill" style={{width: `${totalImpact ? (doneImpact/totalImpact*100) : 0}%`}}></div>
      </div>
      <ul className="imp-list">
        {items.map((it, i) => (
          <li key={i} className={`imp-item ${done.has(i) ? 'done' : ''}`}>
            <button className="imp-check" onClick={() => toggle(i)}>
              {done.has(i) && <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3"><path d="M20 6L9 17l-5-5"/></svg>}
            </button>
            <div className="imp-priority">P{it.priority}</div>
            <div className="imp-body">
              <div style={{display:'flex', alignItems:'center', gap: 8, marginBottom: 6, flexWrap:'wrap'}}>
                <span className="chip" style={{fontSize: 11}}>{it.cat}</span>
                {it.effort && it.effort !== '—' && <span className="muted" style={{fontSize: 12}}>Esfuerzo: {it.effort}</span>}
                {it.note && <span className="chip chip-accent" style={{fontSize: 11}}>{it.note}</span>}
              </div>
              <div style={{fontWeight: 600, fontSize: 15}}>{it.title}</div>
              {it.body && <div className="muted" style={{fontSize: 13, marginTop: 4, lineHeight: 1.5}}>{it.body}</div>}
            </div>
            <div className="imp-impact">
              <div className="mono" style={{fontSize: 16, fontWeight: 500, color: it.impact ? 'var(--good)' : 'var(--muted)'}}>
                {it.impact ? `+$${Number(it.impact).toLocaleString('es-MX')}` : '—'}
              </div>
              <div className="muted" style={{fontSize: 11}}>MXN/mes</div>
            </div>
          </li>
        ))}
      </ul>
    </div>
  );
};

// Estos dos siguen con visual mock — no vienen en audit_data aún, pero mantienen el layout.
const PricingChart = ({ audit }) => {
  const your = [1620, 1690, 1780, 1820, 1850, 1940, 2010, 1980, 1940, 1880, 1810, 1780];
  const zone = [1790, 1850, 1940, 2040, 2110, 2180, 2280, 2230, 2110, 2010, 1940, 1880];
  const months = ['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'];
  const max = 2400, min = 1500;
  const toY = v => 100 - ((v - min) / (max - min)) * 100;
  const toPath = arr => arr.map((v, i) => `${i === 0 ? 'M' : 'L'}${(i/(arr.length-1))*100},${toY(v)}`).join(' ');
  return (
    <div className="card card-pad">
      <div className="flex items-center justify-between" style={{marginBottom: 8}}>
        <div>
          <h2 className="h3" style={{margin: 0}}>Tu precio vs zona</h2>
          <div className="muted" style={{fontSize: 13, marginTop: 4}}>Precio promedio por noche · 12 meses · MXN</div>
        </div>
        <div style={{display:'flex', gap: 16, fontSize: 12}}>
          <span style={{display:'flex', alignItems:'center', gap: 6}}><em style={{width:10, height:2, background:'var(--ink)', display:'inline-block'}}></em> Tu propiedad</span>
          <span style={{display:'flex', alignItems:'center', gap: 6}}><em style={{width:10, height:2, background:'var(--accent)', display:'inline-block'}}></em> Zona</span>
        </div>
      </div>
      <div className="chart-wrap">
        <svg viewBox="0 0 100 100" preserveAspectRatio="none" className="chart-svg">
          {[0,25,50,75,100].map(y => <line key={y} x1="0" x2="100" y1={y} y2={y} stroke="var(--line)" strokeWidth="0.2" vectorEffect="non-scaling-stroke" />)}
          <path d={toPath(zone)} fill="none" stroke="var(--accent)" strokeWidth="1.5" strokeDasharray="2 2" vectorEffect="non-scaling-stroke" />
          <path d={toPath(your)} fill="none" stroke="var(--ink)" strokeWidth="2" vectorEffect="non-scaling-stroke" />
          {your.map((v, i) => (
            <circle key={i} cx={(i/(your.length-1))*100} cy={toY(v)} r="0.8" fill="var(--ink)" vectorEffect="non-scaling-stroke" />
          ))}
        </svg>
        <div className="chart-labels">
          {months.map(m => <span key={m}>{m}</span>)}
        </div>
      </div>
      <div className="chart-callout">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="12" cy="12" r="10"/><path d="M12 8v4M12 16h.01"/></svg>
        <span>Estás <strong>$150–270 MXN por debajo</strong> de la zona casi todo el año. Potencial claro en pricing.</span>
      </div>
    </div>
  );
};

const Competitors = ({ audit }) => {
  const rows = [
    { name: 'Casa Roma (tú)', score: 68, grade: 'C', adr: 1880, occ: 68, you: true },
    { name: 'Loft Condesa', score: 84, grade: 'A', adr: 2140, occ: 82 },
    { name: 'Casa Juárez', score: 78, grade: 'B', adr: 1960, occ: 74 },
    { name: 'Piso Álamos', score: 81, grade: 'B', adr: 2180, occ: 71 },
    { name: 'Estudio Roma', score: 62, grade: 'C', adr: 1620, occ: 65 },
  ];
  return (
    <div className="card card-pad">
      <div style={{marginBottom: 16}}>
        <h2 className="h3" style={{margin: 0}}>Competencia directa · 1km</h2>
        <div className="muted" style={{fontSize: 13, marginTop: 4}}>5 propiedades similares (2 hab, capacidad 4)</div>
      </div>
      <table className="comp-table">
        <thead>
          <tr>
            <th>Propiedad</th>
            <th>Calif.</th>
            <th>Precio</th>
            <th>Ocup.</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r, i) => {
            const g = toGrade(r.score);
            return (
              <tr key={i} className={r.you ? 'you' : ''}>
                <td>{r.name} {r.you && <span className="chip chip-accent" style={{fontSize: 10, marginLeft: 6}}>Tú</span>}</td>
                <td>
                  <span className={`grade-badge grade-${g.tag}`} style={{width: 22, height: 22, fontSize: 12, borderRadius: 4}}>{g.g}</span>
                </td>
                <td className="mono">${r.adr.toLocaleString('es-MX')}</td>
                <td className="mono">{r.occ}%</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
};

const UpgradeBanner = () => (
  <div className="upgrade-banner">
    <div>
      <div className="chip chip-accent" style={{marginBottom: 12}}>Estás viendo la vista previa gratuita</div>
      <h3 className="serif" style={{fontSize: 28, margin: 0, letterSpacing:'-0.02em', color: 'var(--bg)'}}>
        Desbloquea el plan de acción completo
      </h3>
      <p style={{margin: '12px 0 0', color: 'rgba(250,248,243,0.65)', maxWidth: 540}}>
        Recomendaciones específicas, reescritura con IA del título y descripción,
        análisis de competencia detallado y reporte en PDF. Pago único de $20 USD.
      </p>
    </div>
    <a href="/premium" className="btn btn-accent btn-lg">Obtener reporte premium</a>
  </div>
);

// ========== Loader ==========
// Hace fetch de /api/v2/reports-list al montar; si 401 redirige a login.
// Si ?id=<uuid> está en URL, fetch /api/v2/reports-get?id=...
// Si no hay id, usa el primer report de la lista.
const DashboardRoot = () => {
  const [state, setState] = useState({ loading: true, audit: null, reports: [], reportId: null, error: null });

  useEffect(() => {
    let cancelled = false;
    const load = async () => {
      try {
        const listRes = await fetch('/api/v2/reports-list', { credentials: 'include' });
        if (listRes.status === 401) {
          window.location.href = '/login';
          return;
        }
        if (!listRes.ok) throw new Error(`reports-list ${listRes.status}`);
        const list = await listRes.json();
        const reports = Array.isArray(list) ? list : (list.reports || []);

        const params = new URLSearchParams(window.location.search);
        const idParam = params.get('id');
        const targetId = idParam || (reports[0] && (reports[0].id || reports[0].report_id));

        let audit = null;
        let reportPremium = false;
        if (targetId) {
          const getRes = await fetch(`/api/v2/reports-get?id=${encodeURIComponent(targetId)}`, { credentials: 'include' });
          if (getRes.status === 401) {
            window.location.href = '/login';
            return;
          }
          if (getRes.ok) {
            const body = await getRes.json();
            const report = body.report || body;
            audit = (report && (report.audit_data || report.audit)) || {};
            reportPremium = !!(report && report.premium);
          }
        } else if (reports[0] && (reports[0].audit_data || reports[0].audit)) {
          audit = reports[0].audit_data || reports[0].audit;
          reportPremium = !!reports[0].premium;
        }

        // Inject premium flag into audit so DashHeader can read it
        if (audit) audit.premium = reportPremium;

        if (!cancelled) setState({ loading: false, audit: audit || {}, reports, reportId: targetId || null, error: null });
      } catch (err) {
        if (!cancelled) setState({ loading: false, audit: {}, reports: [], reportId: null, error: err.message || 'Error' });
      }
    };
    load();
    return () => { cancelled = true; };
  }, []);

  if (state.loading) {
    return (
      <div className="wrap" style={{ padding: '80px 32px', textAlign: 'center' }}>
        <div className="muted" style={{ fontSize: 14 }}>Cargando tu reporte…</div>
      </div>
    );
  }

  const audit = state.audit || {};
  const reports = state.reports || [];
  return (
    <>
      <DashHeader audit={audit} reportId={state.reportId} />
      {reports.length > 1 && (
        <div style={{background:'var(--bg-2)', borderBottom:'1px solid var(--line)', padding:'14px 0'}}>
          <div className="wrap" style={{display:'flex', gap:10, alignItems:'center', overflowX:'auto'}}>
            <span className="muted" style={{fontSize: 12, textTransform:'uppercase', letterSpacing:'0.08em', flexShrink:0}}>
              Mis propiedades · {reports.length}
            </span>
            {reports.map((r) => {
              const isActive = r.id === state.reportId;
              const label = (r.listing_title || 'Sin título').slice(0, 36);
              return (
                <a
                  key={r.id}
                  href={`/dashboard?id=${encodeURIComponent(r.id)}`}
                  style={{
                    padding: '6px 12px', borderRadius: 999,
                    background: isActive ? 'var(--ink)' : 'var(--card)',
                    color: isActive ? 'var(--bg)' : 'var(--ink-2)',
                    border: '1px solid ' + (isActive ? 'var(--ink)' : 'var(--line)'),
                    fontSize: 13, whiteSpace: 'nowrap', flexShrink: 0,
                    textDecoration: 'none',
                  }}
                >
                  {r.premium && <span style={{color: isActive ? 'var(--accent)' : 'var(--accent)', marginRight: 6}}>●</span>}
                  {label}
                </a>
              );
            })}
          </div>
        </div>
      )}
      <main className="dash-body">
        <div className="wrap">
          {state.error && (
            <div className="muted" style={{ marginBottom: 16, fontSize: 13 }}>
              No se pudo cargar: {state.error}
            </div>
          )}
          <div style={{marginBottom: 24}}>
            <KPICards audit={audit} />
          </div>
          <div className="dash-grid">
            <div className="dash-col">
              <Improvements audit={audit} />
              <PricingChart audit={audit} />
            </div>
            <div className="dash-col">
              <ScoreCard audit={audit} />
              <CategoryBreakdown audit={audit} />
              <Competitors audit={audit} />
            </div>
          </div>
          {audit.premium ? (
            <>
              <PremiumResumen audit={audit} />
              <PremiumQuickWins audit={audit} />
              <PremiumTitulos audit={audit} />
              <PremiumDescripcion audit={audit} />
              <PremiumPricing audit={audit} />
              <PremiumComparables audit={audit} />
              <PremiumRoadmap audit={audit} />
            </>
          ) : (
            <div style={{marginTop: 32}}>
              <UpgradeBanner />
            </div>
          )}
        </div>
      </main>
    </>
  );
};

// ========== Premium-only sections (render solo si audit tiene data enriquecida) ==========

const PremiumSection = ({ eyebrow, title, children }) => (
  <section className="card card-pad" style={{marginTop: 24}}>
    {eyebrow && <div className="eyebrow" style={{marginBottom: 10}}>{eyebrow}</div>}
    {title && (
      <h2 className="serif" style={{fontSize: 28, letterSpacing:'-0.02em', margin: '0 0 20px', fontWeight: 400, lineHeight: 1.15}}>
        {title}
      </h2>
    )}
    {children}
  </section>
);

const PremiumResumen = ({ audit }) => {
  const r = audit && audit.resumen_ejecutivo;
  if (!r || (!r.fortalezas && !r.areas_mejora && !r.accion_urgente)) return null;
  const F = Array.isArray(r.fortalezas) ? r.fortalezas : [];
  const M = Array.isArray(r.areas_mejora) ? r.areas_mejora : [];
  const U = typeof r.accion_urgente === 'string' ? r.accion_urgente : (Array.isArray(r.accion_urgente) ? r.accion_urgente.join(' ') : '');
  return (
    <PremiumSection eyebrow="Resumen ejecutivo" title="Qué está funcionando, qué frenar.">
      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap: 14}}>
        <div style={{background:'var(--bg-2)', padding: 18, borderRadius: 12}}>
          <div className="mono" style={{fontSize: 11, color:'var(--muted)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom: 10}}>✓ Fortalezas</div>
          <ul style={{margin:0, paddingLeft: 18, fontSize: 13.5, lineHeight: 1.55, color:'var(--ink-2)'}}>
            {F.map((x, i) => <li key={i} style={{marginBottom: 4}}>{x}</li>)}
          </ul>
        </div>
        <div style={{background:'var(--bg-2)', padding: 18, borderRadius: 12}}>
          <div className="mono" style={{fontSize: 11, color:'var(--muted)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom: 10}}>→ Áreas a mejorar</div>
          <ul style={{margin:0, paddingLeft: 18, fontSize: 13.5, lineHeight: 1.55, color:'var(--ink-2)'}}>
            {M.map((x, i) => <li key={i} style={{marginBottom: 4}}>{x}</li>)}
          </ul>
        </div>
        <div style={{background:'var(--accent-soft)', padding: 18, borderRadius: 12, border:'1px solid var(--accent)'}}>
          <div className="mono" style={{fontSize: 11, color:'var(--accent-ink)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom: 10, fontWeight: 600}}>! Acción urgente</div>
          <div style={{fontSize: 13.5, lineHeight: 1.55, color:'var(--accent-ink)'}}>{U}</div>
        </div>
      </div>
    </PremiumSection>
  );
};

const PremiumQuickWins = ({ audit }) => {
  const qw = audit && (audit.quick_wins_enriched || audit.quick_wins);
  if (!Array.isArray(qw) || !qw.length) return null;
  // Normalize — accept objects with titulo+pasos+tiempo+impacto OR {category, action} legacy format
  const items = qw.map((w, i) => ({
    n: i + 1,
    t: w.titulo || w.title || w.category || w.action || 'Acción',
    steps: Array.isArray(w.pasos) ? w.pasos : (Array.isArray(w.steps) ? w.steps : (typeof w.action === 'string' ? [w.action] : [])),
    tiempo: w.tiempo || w.time || '',
    impacto: w.impacto || w.impact || '',
  })).filter((w) => w.t);
  if (!items.length) return null;
  return (
    <PremiumSection eyebrow={`${items.length} quick wins`} title="Lo primero que debes hacer.">
      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap: 14}}>
        {items.map((w) => (
          <div key={w.n} style={{background:'var(--bg)', border:'1px solid var(--line)', borderRadius: 12, padding: 20}}>
            <div style={{display:'flex', alignItems:'baseline', gap: 12, marginBottom: 8}}>
              <span className="serif" style={{fontSize: 22, color:'var(--accent)', fontStyle:'italic', lineHeight: 1}}>{String(w.n).padStart(2, '0')}</span>
              <div style={{fontWeight: 600, fontSize: 15}}>{w.t}</div>
            </div>
            {w.steps.length > 0 && (
              <ol style={{margin: '10px 0 12px', paddingLeft: 18, fontSize: 13, color:'var(--ink-2)', lineHeight: 1.55}}>
                {w.steps.map((s, i) => <li key={i} style={{marginBottom: 3}}>{s}</li>)}
              </ol>
            )}
            {(w.tiempo || w.impacto) && (
              <div style={{display:'flex', gap: 14, fontSize: 12, color:'var(--muted)', paddingTop: 10, borderTop:'1px solid var(--line)'}}>
                {w.tiempo && <span>⏱ {w.tiempo}</span>}
                {w.impacto && <span>📈 <b style={{color:'var(--good)', fontWeight: 600}}>{w.impacto}</b></span>}
              </div>
            )}
          </div>
        ))}
      </div>
    </PremiumSection>
  );
};

const PremiumTitulos = ({ audit }) => {
  const tn = audit && audit.titulo_nuevo;
  if (!tn || (!tn.opcion_a && !tn.opcion_b && !tn.opcion_c)) return null;
  const opts = [
    { tag: 'A · Experiencia', data: tn.opcion_a },
    { tag: 'B · Amenidades', data: tn.opcion_b },
    { tag: 'C · Ubicación', data: tn.opcion_c },
  ].filter((o) => o.data && (o.data.titulo || o.data.title));
  if (!opts.length) return null;
  return (
    <PremiumSection eyebrow="Títulos propuestos" title="Elige uno y cópialo tal cual.">
      <div style={{display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap: 14}}>
        {opts.map((o, i) => (
          <div key={i} style={{background:'var(--bg)', border:'1px solid var(--line)', borderRadius: 12, padding: 20}}>
            <div className="mono" style={{fontSize: 10.5, color:'var(--muted)', letterSpacing:'0.08em', textTransform:'uppercase', fontWeight: 600}}>{o.tag}</div>
            <div className="serif" style={{fontSize: 19, lineHeight: 1.25, margin: '10px 0 12px', letterSpacing:'-0.01em'}}>
              "{o.data.titulo || o.data.title}"
            </div>
            {o.data.enfoque && (
              <div style={{display:'inline-block', padding: '3px 10px', background:'var(--accent-soft)', color:'var(--accent-ink)', borderRadius: 999, fontSize: 11.5, fontWeight: 600, marginBottom: 10}}>{o.data.enfoque}</div>
            )}
            {(o.data.porque || o.data.porqué) && (
              <div style={{fontSize: 12.5, color:'var(--ink-2)', lineHeight: 1.5}}>{o.data.porque || o.data.porqué}</div>
            )}
          </div>
        ))}
      </div>
    </PremiumSection>
  );
};

const PremiumDescripcion = ({ audit }) => {
  const d = audit && audit.descripcion_nueva;
  const text = d && (d.descripcion_completa || d.descripcion || d.text);
  if (!text) return null;
  return (
    <PremiumSection eyebrow="Descripción optimizada" title="Un texto completo, listo para pegar.">
      <div style={{background:'var(--bg)', border:'1px solid var(--line)', borderRadius: 12, padding: 24, fontSize: 14.5, lineHeight: 1.65, whiteSpace:'pre-wrap', color:'var(--ink)'}}>
        {text}
      </div>
      {Array.isArray(d.porque_funciona) && d.porque_funciona.length > 0 && (
        <ul style={{margin: '16px 0 0', paddingLeft: 18, fontSize: 13, color:'var(--muted)', lineHeight: 1.55}}>
          {d.porque_funciona.map((r, i) => <li key={i} style={{marginBottom: 4}}>{r}</li>)}
        </ul>
      )}
    </PremiumSection>
  );
};

const PremiumPricing = ({ audit }) => {
  const ps = audit && audit.pricing_strategy;
  if (!ps || typeof ps !== 'object' || !Object.keys(ps).length) return null;
  const rows = [
    ['Precio base', ps.precio_base],
    ['Fin de semana', ps.fin_de_semana],
    ['Temporada alta', ps.temporada_alta],
    ['Descuento semanal', ps.descuento_semanal],
    ['Descuento mensual', ps.descuento_mensual],
  ].filter((r) => r[1]);
  return (
    <PremiumSection eyebrow="Pricing strategy" title="Precio basado en tu zona real.">
      <div style={{background:'var(--bg)', border:'1px solid var(--line)', borderRadius: 12, padding: 20}}>
        <table style={{width:'100%', borderCollapse:'collapse', fontSize: 13.5}}>
          <tbody>
            {rows.map((r, i) => (
              <tr key={i} style={{borderBottom: i < rows.length - 1 ? '1px solid var(--line)' : '0'}}>
                <td style={{padding: '10px 0', color:'var(--ink-2)'}}>{r[0]}</td>
                <td className="mono" style={{padding: '10px 0', textAlign:'right', fontWeight: 600}}>{r[1]}</td>
              </tr>
            ))}
          </tbody>
        </table>
        {ps.estrategia && (
          <div style={{marginTop: 16, padding: 14, background:'var(--bg-2)', borderRadius: 8, fontSize: 13, color:'var(--ink-2)', lineHeight: 1.55}}>
            {ps.estrategia}
          </div>
        )}
      </div>
    </PremiumSection>
  );
};

const PremiumComparables = ({ audit }) => {
  const comp = audit && audit.competition;
  const rows = comp && Array.isArray(comp.comparables) ? comp.comparables.filter((c) => c && (c.title || c.name)) : [];
  if (!rows.length) return null;
  return (
    <PremiumSection eyebrow="Competencia en tu zona" title="Cómo te comparas con 5 listings similares.">
      <div style={{background:'var(--bg)', border:'1px solid var(--line)', borderRadius: 12, padding: 20}}>
        <table style={{width:'100%', borderCollapse:'collapse', fontSize: 13.5}}>
          <thead>
            <tr>
              <th style={{padding: '8px 0', textAlign:'left', fontSize: 11, color:'var(--muted)', textTransform:'uppercase', letterSpacing:'0.04em', fontWeight: 500}}>Listing</th>
              <th style={{padding: '8px 0', textAlign:'right', fontSize: 11, color:'var(--muted)', textTransform:'uppercase', letterSpacing:'0.04em', fontWeight: 500}}>Precio</th>
              <th style={{padding: '8px 0', textAlign:'right', fontSize: 11, color:'var(--muted)', textTransform:'uppercase', letterSpacing:'0.04em', fontWeight: 500}}>Rating</th>
            </tr>
          </thead>
          <tbody>
            {rows.slice(0, 5).map((c, i) => (
              <tr key={i} style={{borderTop:'1px solid var(--line)'}}>
                <td style={{padding: '10px 0'}}>{(c.title || c.name).slice(0, 48)}</td>
                <td className="mono" style={{padding: '10px 0', textAlign:'right'}}>{c.price ? `$${c.price} MXN` : '—'}</td>
                <td style={{padding: '10px 0', textAlign:'right', color:'var(--muted)', fontSize: 12.5}}>
                  {c.rating ? `★ ${c.rating}` : '—'}
                  {c.reviews_count ? ` · ${c.reviews_count}` : ''}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      {typeof audit.competencia_analisis === 'string' && audit.competencia_analisis.trim() && (
        <div style={{marginTop: 16, fontSize: 14, color:'var(--ink-2)', lineHeight: 1.6}}>
          {audit.competencia_analisis}
        </div>
      )}
    </PremiumSection>
  );
};

const PremiumRoadmap = ({ audit }) => {
  const rm = audit && audit.roadmap;
  if (!rm || typeof rm !== 'object') return null;
  const phases = [
    { key: 'semana_1', label: 'Semana 1', desc: 'Quick wins' },
    { key: 'mes_1', label: 'Mes 1', desc: 'Optimización' },
    { key: 'mes_3', label: 'Mes 3', desc: 'Escalamiento' },
  ].map((p) => ({ ...p, items: Array.isArray(rm[p.key]) ? rm[p.key] : [] })).filter((p) => p.items.length);
  if (!phases.length) return null;
  return (
    <PremiumSection eyebrow="Roadmap 90 días" title="Del día 1 al mes 3.">
      <div style={{display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap: 14}}>
        {phases.map((p) => (
          <div key={p.key} style={{background:'var(--bg)', border:'1px solid var(--line)', borderRadius: 12, padding: 20}}>
            <div style={{display:'inline-block', padding: '4px 12px', borderRadius: 999, fontSize: 11.5, fontWeight: 600, letterSpacing:'0.04em', background:'var(--accent-soft)', color:'var(--accent-ink)', marginBottom: 12}}>
              {p.label}
            </div>
            <div className="serif" style={{fontSize: 20, letterSpacing:'-0.015em', marginBottom: 10}}>{p.desc}</div>
            <ul style={{margin: 0, paddingLeft: 18, fontSize: 13, color:'var(--ink-2)', lineHeight: 1.55}}>
              {p.items.map((it, i) => <li key={i} style={{marginBottom: 5}}>{it}</li>)}
            </ul>
          </div>
        ))}
      </div>
    </PremiumSection>
  );
};

Object.assign(window, { DashHeader, ScoreCard, KPICards, CategoryBreakdown, Improvements, PricingChart, Competitors, UpgradeBanner, DashboardRoot, PremiumResumen, PremiumQuickWins, PremiumTitulos, PremiumDescripcion, PremiumPricing, PremiumComparables, PremiumRoadmap });
