import re, sys

path = '/home/szymon/projects/tfb/app/panel/views/analysis/revenue_dashboard.twig'
with open(path, 'r', encoding='utf-8') as f:
    content = f.read()

original_len = len(content)

# ─── 1. HTML: zastap <div class="table-responsive"> + <table> ─────────────────
pattern_html = r'        <div class="table-responsive">\s*\n.*?</table>\s*\n        </div>'
replacement_html = (
    '        <table class="table table-bordered table-sm" id="rd-table">\n'
    '                <thead>\n'
    '                    <tr>\n'
    '                        <th>Okres</th>\n'
    '                        <th>Txn</th>\n'
    '                        <th>\u015ar/d</th>\n'
    '                        <th>Przych\u00f3d<br><span style="font-weight:400;opacity:.7">\u0394 m/m</span></th>\n'
    '                        <th>\u015ar.<br>paragon</th>\n'
    '                        <th>P/t</th>\n'
    '                        <th>Food<br>%</th>\n'
    '                        <th>Labor<br>%</th>\n'
    '                        <th>Shop<br>%</th>\n'
    '                        <th>Wynik netto<br><span style="font-weight:400;opacity:.7">mar\u017ca</span></th>\n'
    '                        <th>Status</th>\n'
    '                    </tr>\n'
    '                </thead>\n'
    '                <tbody id="rd-tbody">\n'
    '                    <tr>\n'
    '                        <td colspan="11" class="text-center text-muted py-4">\n'
    '                            <div class="spinner-border spinner-border-sm me-2"></div>\n'
    "                            {{ translations.loading ?? '\u0141adowanie danych\u2026' }}\n"
    '                        </td>\n'
    '                    </tr>\n'
    '                </tbody>\n'
    '            </table>'
)
m = re.search(pattern_html, content, re.DOTALL)
if not m:
    sys.exit("ERROR: table-responsive pattern not found")
content = content[:m.start()] + replacement_html + content[m.end():]
print("Step 1 (HTML table-responsive -> compact table) OK")

# ─── 2. JS: empty-state colspan 12 -> 11 ─────────────────────────────────────
content = content.replace(
    'colspan="12" class="text-center text-muted py-4">Brak danych dla wybranego okresu.',
    'colspan="11" class="text-center text-muted py-4">Brak danych dla wybranego okresu.',
    1
)
print("Step 2 (empty state colspan) OK")

# ─── 3. JS: noData row colspan 11 -> 10 ──────────────────────────────────────
content = content.replace(
    '<td colspan="11" class="text-center text-muted">',
    '<td colspan="10" class="text-center text-muted">',
    1
)
print("Step 3 (noData colspan) OK")

# ─── 4. JS: costBar -> costInline ────────────────────────────────────────────
pat_cost = r'function costBar\(pct, threshold\) \{.*?\n\}'
m2 = re.search(pat_cost, content, re.DOTALL)
if not m2:
    sys.exit("ERROR: costBar function not found")
new_cost_fn = (
    'function costInline(pct, threshold, amtStr) {\n'
    '    const over = pct > threshold;\n'
    '    const warn = over && pct <= threshold + 4;\n'
    "    const c = over ? (warn ? 'var(--rd-wn)' : 'var(--rd-dg)') : 'var(--rd-ok)';\n"
    '    const barW = clamp(pct / (threshold * 1.8) * 30, 1, 30);\n'
    '    return `<div class="rd-cost-inline">` +\n'
    "           `<div class=\"rd-bar\" style=\"width:${barW}px;background:${c};opacity:.7\"></div>` +\n"
    "           `<span style=\"color:${over ? c : 'inherit'};font-weight:${over ? 600 : 400}\">${pct.toFixed(1)}%</span>` +\n"
    '           `</div><span class="rd-sub" style="display:block;text-align:right">${amtStr}</span>`;\n'
    '}'
)
content = content[:m2.start()] + new_cost_fn + content[m2.end():]
print("Step 4 (costBar -> costInline) OK")

# ─── 5. JS: glowny wiersz danych ─────────────────────────────────────────────
pat_row = r'        return `<tr>\s*\n.*?</tr>`;\s*\n'
m3 = re.search(pat_row, content, re.DOTALL)
if not m3:
    sys.exit("ERROR: data row pattern not found")
new_row = (
    '        const delta = deltaTag(Number(r.total_sales), prev ? Number(prev.total_sales) : null);\n'
    '        return `<tr>\n'
    '            <td><strong>${r.period}</strong></td>\n'
    "            <td class=\"text-end\">${Number(r.transactions_count).toLocaleString('pl-PL')}</td>\n"
    '            <td class="text-end">${Math.round(Number(r.avg_transactions_count))}</td>\n'
    '            <td class="text-end"><strong>${fmtK(r.total_sales)}</strong><br><span class="rd-sub">${delta}</span></td>\n'
    '            <td class="text-end">${fmtK(r.avg_ticket_value)}</td>\n'
    '            <td class="text-end">${Number(r.avg_products_per_transaction).toFixed(1)}</td>\n'
    '            <td class="text-end">${costInline(foodPct, RD.foodThreshold, fmtK(r.material_cost))}</td>\n'
    '            <td class="text-end">${costInline(labourPct, RD.labourThreshold, fmtK(r.employee_cost))}</td>\n'
    '            <td class="text-end"><span style="color:var(--rd-t3)">${shopPct.toFixed(1)}%</span><br><span class="rd-sub">${fmtK(r.shop_cost)}</span></td>\n'
    "            <td class=\"text-end\"><strong class=\"${netClass}\">${netVal >= 0 ? '+' : ''}${fmtK(netVal)}</strong><br><span class=\"rd-sub ${netClass}\">${margin >= 0 ? '+' : ''}${margin.toFixed(1)}%</span></td>\n"
    '            <td class="text-center">${statusBadge(foodPct, labourPct)}</td>\n'
    '        </tr>`;\n'
)
content = content[:m3.start()] + new_row + content[m3.end():]
print("Step 5 (data row) OK")

# ─── 6. JS: wiersz sumaryczny ────────────────────────────────────────────────
pat_total = r'        html\.push\(`<tr class="rd-row-total">.*?</tr>`\);'
m4 = re.search(pat_total, content, re.DOTALL)
if not m4:
    sys.exit("ERROR: total row pattern not found")
new_total = (
    '        html.push(`<tr class="rd-row-total">\n'
    '            <td>\u03a3 ${full.length} mies.</td>\n'
    "            <td class=\"text-end\">${tTxn.toLocaleString('pl-PL')}</td>\n"
    '            <td class="text-end">\u2014</td>\n'
    '            <td class="text-end"><strong>${fmtK(tRev)}</strong></td>\n'
    '            <td class="text-end">\u2014</td>\n'
    '            <td class="text-end">\u2014</td>\n'
    '            <td class="text-end">${costInline(tFP, RD.foodThreshold, fmtK(tMat))}</td>\n'
    '            <td class="text-end">${costInline(tLP, RD.labourThreshold, fmtK(tEmp))}</td>\n'
    '            <td class="text-end"><span style="color:var(--rd-t3)">${tSP.toFixed(1)}%</span><br><span class="rd-sub">${fmtK(tShop)}</span></td>\n'
    "            <td class=\"text-end\"><strong class=\"${tNet >= 0 ? 'rd-pos' : 'rd-neg'}\">${tNet >= 0 ? '+' : ''}${fmtK(tNet)}</strong><br><span class=\"rd-sub ${tNet >= 0 ? 'rd-pos' : 'rd-neg'}\">${tNP >= 0 ? '+' : ''}${tNP.toFixed(1)}%</span></td>\n"
    '            <td class="text-center">${statusBadge(tFP, tLP)}</td>\n'
    '        </tr>`);'
)
content = content[:m4.start()] + new_total + content[m4.end():]
print("Step 6 (total row) OK")

# ─── 7. JS: dodaj fmtK po funkcji fmt ────────────────────────────────────────
fmtk_def = (
    'const fmtK = (v, d = 1) => {\n'
    '    v = Number(v ?? 0);\n'
    "    if (Math.abs(v) >= 1000) return (v / 1000).toFixed(d) + 'k';\n"
    '    return v.toFixed(0);\n'
    '};\n'
)
fmt_pattern = r"(const fmt = [^\n]+\n[^\n]+\n[^\n]+\n)"
m5 = re.search(fmt_pattern, content)
if m5:
    content = content[:m5.end()] + fmtk_def + content[m5.end():]
    print("Step 7 (fmtK helper) OK")
else:
    print("WARN: fmtK not auto-inserted")

with open(path, 'w', encoding='utf-8') as f:
    f.write(content)

print(f"ALL DONE. File size: {original_len} -> {len(content)} bytes")

