`; const w = window.open('', '_blank'); if (w && w.document) { w.document.write(reportHtml); w.document.close(); return; } document.open(); document.write(reportHtml); document.close(); } function buildReportHtml(report, data) { const a = (report && report.analysis) || {}; const isStructured = a && typeof a === 'object' && !a.raw; const baseline = a.baseline || {}; const findings = Array.isArray(a.findings) ? a.findings : []; const scenarios = Array.isArray(a.scenarios) ? a.scenarios : []; const hypothetical = Array.isArray(a.hypothetical) ? a.hypothetical : []; // Data kommer från profile.extract() → { profileId, fields:{...}, fulltext, warnings } const fields = (data && data.fields) || {}; const esc = (s) => String(s ?? '').replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); const kr = (n) => n == null || Number.isNaN(Number(n)) ? '—' : Number(n).toLocaleString('sv-SE') + ' kr'; const pct = (n) => n == null ? '—' : (typeof n === 'number' ? n.toFixed(1) : n) + ' %'; const riskLabel = { low: 'Låg risk', med: 'Medel risk', high: 'Hög risk' }; const riskColor = { low: '#4a7a4a', med: '#b8762a', high: '#a8442a' }; const findingsHtml = findings.map((f, i) => `
${i + 1}

${esc(f.title || 'Optimeringsmöjlighet')}

${f.risk ? `${riskLabel[f.risk] || esc(f.risk)}` : ''}
${kr(f.savings_kr)}
${f.description ? `

${esc(f.description)}

` : ''} ${f.blankett_rad ? `

Blankettrad: ${esc(f.blankett_rad)}

` : ''} ${Array.isArray(f.underlag) && f.underlag.length ? `

Underlag som krävs:

` : ''}
`).join(''); const scenariosHtml = scenarios.map((s) => `
Scenario ${esc(s.label || '')}

${esc(s.title || '')}

${kr(s.savings_kr)}
${Array.isArray(s.actions) && s.actions.length ? ` ` : ''}
`).join(''); const hypoHtml = hypothetical.map((h) => `
${esc(h.title || '')} ${kr(h.before_kr)} → ${kr(h.after_kr)} ${h.situation ? `

${esc(h.situation)}

` : ''} ${Array.isArray(h.underlag) && h.underlag.length ? `

Underlag:

` : ''} ${h.warning ? `

⚠ ${esc(h.warning)}

` : ''}
`).join(''); const rawFallback = !isStructured ? `

Claude returnerade inte strukturerad JSON.

${a.parseError ? `

Parse-fel: ${esc(a.parseError)}

` : ''} ${a.stop_reason && a.stop_reason !== 'end_turn' ? `

Stop reason: ${esc(a.stop_reason)} ${a.stop_reason === 'max_tokens' ? '(svaret klipptes — höj max_tokens i workern)' : ''}

` : ''}

Rå text från Claude:

${esc(a.raw || JSON.stringify(report.analysis ?? report, null, 2))}
` : ''; const totalFindings = findings.reduce((sum, f) => sum + (Number(f.savings_kr) || 0), 0); return ` Din skatterapport — ${esc(report.user || '')}
Skatterapport · Inkomstår ${esc(fields.inkomstar || '2025')}

Din skatt, omräknad.

Genererad ${new Date().toLocaleString('sv-SE')}${report.user ? ' · ' + esc(report.user) : ''}

Baseline

${kr(baseline.total_skatt ?? fields.slutlig_skatt)}
Nuvarande skatt
${pct(baseline.effektiv_skatt_procent)}
Effektiv skattesats
${kr(totalFindings)}
Potentiell besparing
${findings.length ? `

Optimeringsmöjligheter

${findingsHtml}` : ''} ${scenarios.length ? `

Scenarier

${scenariosHtml}` : ''} ${hypothetical.length ? `

Hypotetiska livssituationer

${hypoHtml}` : ''} ${rawFallback}
Viktigt: Detta är en automatiserad analys baserad på Skatteverkets regler för inkomstår ${esc(fields.inkomstar || '2025')}. Verifiera alltid med revisor eller Skatteverket innan du fattar ekonomiska beslut.
Visa extraherad data från deklarationen
${esc(JSON.stringify(data, null, 2))}
`; }