#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
RICOSTRUTTORE tracciato6.php con fasce pressione
Legge il backup originale, estrae i dati, applica TUTTE le modifiche.

USO: python3 rebuild_tracciato6.py
     (deve stare nella stessa cartella di tracciato6.php)
"""
import re, os, shutil, glob

# Find the backup file
backups = sorted(glob.glob('tracciato6.php.bak_*'))
if not backups:
    # try the patched file as source
    if os.path.exists('tracciato6.php'):
        src = 'tracciato6.php'
        print(f"⚠️  Nessun backup trovato, uso {src} come sorgente")
    else:
        print("❌ Nessun file sorgente trovato!")
        exit(1)
else:
    src = backups[0]  # oldest backup = original
    print(f"📂 Uso backup originale: {src}")

with open(src, 'r', encoding='utf-8') as f:
    original = f.read()

print(f"   Dimensione: {len(original):,} bytes")

# ============================================================
# STRATEGY: Find-and-replace with exact string matching
# Much more reliable than sed/perl regex
# ============================================================

c = original  # working copy
changes = 0

def do_replace(old, new, label, count=1):
    global c, changes
    if old not in c:
        print(f"  ⚠️  [{label}] NON TROVATO")
        return False
    if count == 0:
        n = c.count(old)
        c = c.replace(old, new)
        print(f"  ✅ [{label}] ({n}x)")
        changes += n
    else:
        c = c.replace(old, new, count)
        print(f"  ✅ [{label}]")
        changes += 1
    return True

print("\n🔧 Applicazione modifiche fasce pressione...\n")

# ============================================================
# 1. PN_COLORS
# ============================================================
do_replace(
    "var PN_COLORS = {PN6:'#4caf50', PN10:'#2196f3', PN16:'#ff9800', PN25:'#e53935', PN40:'#9c27b0'};",
    "var PN_COLORS = {'0\u201315':'#4caf50', '16\u201318':'#2196f3', '18\u201320':'#ff9800', '20\u201322':'#e53935', '23\u201326':'#9c27b0'};",
    "1. PN_COLORS")

# ============================================================
# 2. PN_LIMITS
# ============================================================
do_replace(
    "var PN_LIMITS = [{name:'PN6',max:6},{name:'PN10',max:10},{name:'PN16',max:16},{name:'PN25',max:25},{name:'PN40',max:40}];",
    "var PN_LIMITS = [{name:'0\u201315',min:0,max:15},{name:'16\u201318',min:16,max:18},{name:'18\u201320',min:18,max:20},{name:'20\u201322',min:20,max:22},{name:'23\u201326',min:23,max:26}];",
    "2. PN_LIMITS")

# ============================================================
# 3. getPN function
# ============================================================
do_replace(
    """function getPN(bar) {
  for (var i = 0; i < PN_LIMITS.length; i++) { if (bar <= PN_LIMITS[i].max) return PN_LIMITS[i].name; }
  return 'PN40';
}""",
    """function getPN(bar) {
  if (bar <= 15) return '0\u201315';
  if (bar <= 18) return '16\u201318';
  if (bar <= 20) return '18\u201320';
  if (bar <= 22) return '20\u201322';
  return '23\u201326';
}""",
    "3. getPN()")

# ============================================================
# 4. zones in drawPNFull
# ============================================================
do_replace(
    """  var zones = [
    {name: 'PN6',  from: 0,  to: 6,  c: 'rgba(76,175,80,.05)'},
    {name: 'PN10', from: 6,  to: 10, c: 'rgba(33,150,243,.05)'},
    {name: 'PN16', from: 10, to: 16, c: 'rgba(255,152,0,.05)'},
    {name: 'PN25', from: 16, to: 25, c: 'rgba(229,57,53,.05)'},
    {name: 'PN40', from: 25, to: 40, c: 'rgba(156,39,176,.05)'}
  ];""",
    """  var zones = [
    {name: '0\u201315',  from: 0,  to: 15, c: 'rgba(76,175,80,.05)'},
    {name: '16\u201318', from: 15, to: 18, c: 'rgba(33,150,243,.07)'},
    {name: '18\u201320', from: 18, to: 20, c: 'rgba(255,152,0,.07)'},
    {name: '20\u201322', from: 20, to: 22, c: 'rgba(229,57,53,.07)'},
    {name: '23\u201326', from: 22, to: 26, c: 'rgba(156,39,176,.07)'}
  ];""",
    "4. zones")

# ============================================================
# 5. pnOrder (ALL occurrences)
# ============================================================
do_replace(
    "var pnOrder = ['PN6', 'PN10', 'PN16', 'PN25', 'PN40'];",
    "var pnOrder = ['0\u201315', '16\u201318', '18\u201320', '20\u201322', '23\u201326'];",
    "5. pnOrder", count=0)

# ============================================================
# 6. maxBar
# ============================================================
do_replace(
    "var maxBar = 32;",
    "var maxBar = 28;",
    "6. maxBar")

# ============================================================
# 7. Chart.js pressure limit lines
# ============================================================
do_replace(
    """        // PN limit lines \u2014 more visible
        {label: 'PN25 (25 bar)', data: [{x:0,y:25},{x:185,y:25}], borderColor: '#ff3d57', borderWidth: 1.5, borderDash: [6,3], pointRadius: 0, yAxisID: 'y'},
        {label: 'PN16 (16 bar)', data: [{x:0,y:16},{x:185,y:16}], borderColor: '#2196f3', borderWidth: 1.5, borderDash: [6,3], pointRadius: 0, yAxisID: 'y'},
        // PN16 safe zone fill
        {label: '_pn16zone', data: [{x:0,y:16},{x:185,y:16}], borderWidth: 0, pointRadius: 0, fill: {target: {value: 0}, above: 'rgba(76,175,80,.04)'}, yAxisID: 'y'},
        // PN16-PN25 warning zone
        {label: '_pn25zone', data: [{x:0,y:25},{x:185,y:25}], borderWidth: 0, pointRadius: 0, fill: {target: {value: 16}, above: 'rgba(255,152,0,.06)'}, yAxisID: 'y'},""",
    """        // Fasce pressione (d'Andria 26/03/26): 0-15, 16-18, 18-20, 20-22, 23-26 bar
        {label: '15 bar', data: [{x:0,y:15},{x:185,y:15}], borderColor: '#4caf50', borderWidth: 1.2, borderDash: [6,3], pointRadius: 0, yAxisID: 'y'},
        {label: '18 bar', data: [{x:0,y:18},{x:185,y:18}], borderColor: '#2196f3', borderWidth: 1.2, borderDash: [6,3], pointRadius: 0, yAxisID: 'y'},
        {label: '20 bar', data: [{x:0,y:20},{x:185,y:20}], borderColor: '#ff9800', borderWidth: 1.2, borderDash: [6,3], pointRadius: 0, yAxisID: 'y'},
        {label: '22 bar', data: [{x:0,y:22},{x:185,y:22}], borderColor: '#e53935', borderWidth: 1.2, borderDash: [6,3], pointRadius: 0, yAxisID: 'y'},
        {label: '26 bar', data: [{x:0,y:26},{x:185,y:26}], borderColor: '#9c27b0', borderWidth: 1, borderDash: [4,4], pointRadius: 0, yAxisID: 'y'},
        // Zone fill
        {label: '_z015', data: [{x:0,y:15},{x:185,y:15}], borderWidth: 0, pointRadius: 0, fill: {target: {value: 0}, above: 'rgba(76,175,80,.03)'}, yAxisID: 'y'},
        {label: '_z1618', data: [{x:0,y:18},{x:185,y:18}], borderWidth: 0, pointRadius: 0, fill: {target: {value: 15}, above: 'rgba(33,150,243,.03)'}, yAxisID: 'y'},
        {label: '_z1822', data: [{x:0,y:22},{x:185,y:22}], borderWidth: 0, pointRadius: 0, fill: {target: {value: 18}, above: 'rgba(255,152,0,.04)'}, yAxisID: 'y'},""",
    "7. Chart limits")

# ============================================================
# 8. calcPiez w.pn
# ============================================================
do_replace(
    "w.pn = w.bar > 25 ? 'PN40' : w.bar > 16 ? 'PN25' : 'PN16';",
    "w.pn = getPN(w.bar);",
    "8. calcPiez")

# ============================================================
# 9. Chart.js tooltip (in drawCharts chBar section)
# ============================================================
do_replace(
    """            if (l === 'Pressione (bar)') {
                var b = c.parsed.y;
                var pn = b > 25 ? 'PN40' : b > 16 ? 'PN25' : 'PN16';
                return 'p = ' + b.toFixed(1) + ' bar (' + (b * 10.2).toFixed(0) + ' mH\u2082O) \u2192 ' + pn;
              }""",
    """            if (l === 'Pressione (bar)') {
                var b = c.parsed.y;
                var cls = getPN(b);
                return 'p = ' + b.toFixed(1) + ' bar (' + (b * 10.2).toFixed(0) + ' mH\u2082O) \u2192 Fascia ' + cls + ' bar';
              }""",
    "9. Chart tooltip")

# ============================================================
# 10. drawPNFull tooltip
# ============================================================
do_replace(
    """' bar</b> \\u2192 <b>' + pn + '</b>';""",
    """' bar</b> \\u2192 <b>Fascia ' + pn + ' bar</b>';""",
    "10. PN tooltip")

# ============================================================
# 11. Sidebar title
# ============================================================
do_replace(
    "ctx.fillText('Riepilogo per classe PN', sx, sy);",
    "ctx.fillText('Riepilogo per fascia pressione', sx, sy);",
    "11. Sidebar title")

# ============================================================
# 12. Nota Idraulica table header
# ============================================================
do_replace(
    "p<sub>stat</sub> max \\u2192 PN",
    "p<sub>stat</sub> max \\u2192 Fascia",
    "12. Nota header")

# ============================================================
# 13. Nota Idraulica row
# ============================================================
do_replace(
    "+ maxStat.toFixed(1) + ' bar \\u2192 ' + pnStat + '</td>'",
    "+ maxStat.toFixed(1) + ' bar \\u2192 Fascia ' + pnStat + ' bar</td>'",
    "13. Nota row")

# ============================================================
# 14. Distinta title
# ============================================================
do_replace(
    "Classificazione PN per pressione statica: p = (HGL \\u2212 DEM) / 10.2 bar",
    "Classificazione per fasce di pressione: p = (HGL \\u2212 DEM) / 10.2 bar \\u2014 Intervalli: 0-15, 16-18, 18-20, 20-22, 23-26 bar",
    "14. Distinta title")

# ============================================================
# 15. Distinta column header
# ============================================================
do_replace(
    "Classe PN</th>",
    "Fascia pressione</th>",
    "15. Distinta col")

# ============================================================
# 16. Tratta pills
# ============================================================
do_replace(
    "ctx.fillText('TR' + (ti + 1) + ' ' + tr.dn + ' ' + pn + ' (max ' + mxB.toFixed(0) + ' bar)', (x1 + x2) / 2, mt + 8);",
    "ctx.fillText('TR' + (ti + 1) + ' ' + tr.dn + ' [' + pn + '] (max ' + mxB.toFixed(1) + ' bar)', (x1 + x2) / 2, mt + 8);",
    "16. Pills")

# ============================================================
# 17. Nota footer note
# ============================================================
do_replace(
    "<b>PN</b> = classificazione da pressione statica pura.",
    "<b>Fascia</b> = intervallo di pressione statica.",
    "17. Nota footer")

# ============================================================
# 18. Nota section 2
# ============================================================
do_replace(
    "Il grafico PN e la distinta materiali si basano sulla pressione statica.",
    "Il grafico pressioni e la distinta materiali si basano sulla pressione statica, suddivisa in 5 fasce (0\u201315, 16\u201318, 18\u201320, 20\u201322, 23\u201326 bar).",
    "18. Nota s2")

# ============================================================
# 19. PN panel HTML title
# ============================================================
do_replace(
    "CLASSIFICAZIONE PN &mdash; Pressione Nominale Condotte",
    "CLASSIFICAZIONE PRESSIONI &mdash; Fasce di Pressione Statica",
    "19. Panel title")

# ============================================================
# 20. Button label
# ============================================================
do_replace(
    ">\u2b1b PN</button>",
    ">\u2b1b Pressioni</button>",
    "20. Button")

# ============================================================
# 21. Export PNG header
# ============================================================
do_replace(
    "'CLASSIFICAZIONE PN \\u2014 GAA Grande Acquedotto Adriatico \\u2014 176.7 km'",
    "'FASCE DI PRESSIONE \\u2014 GAA Grande Acquedotto Adriatico \\u2014 ' + maxKm.toFixed(1) + ' km'",
    "21. Export header")

# ============================================================
# 22. Export PNG footer
# ============================================================
do_replace(
    "'CAPEX \\u20ac843M | Pressione statica (HGL-DEM)/10.2 | \\u00a9 2026 WeProject / Bangherang Studio'",
    "'p=(HGL-DEM)/10.2 | Fasce: 0-15, 16-18, 18-20, 20-22, 23-26 bar | \\u00a9 2026 WeProject / Bangherang Studio'",
    "22. Export footer")

# ============================================================
# 23. Export filename
# ============================================================
do_replace(
    "'GAA_PN_Classification_v13.png'",
    "'GAA_Pressioni_Fasce_v13.png'",
    "23. Export filename")

# ============================================================
# 24. PN panel info text
# ============================================================
do_replace(
    "p_stat = (HGL&minus;DEM)/10.2 | Pressione statica pura | Scroll=zoom, Drag=pan, DblClick=reset",
    "p=(HGL&minus;DEM)/10.2 | Fasce: 0-15, 16-18, 18-20, 20-22, 23-26 bar | Scroll=zoom, Drag=pan, DblClick=reset",
    "24. Panel info")

# ============================================================
# 25. Sidebar canvas header
# ============================================================
do_replace(
    "ctx.fillText('\\ud83d\\udce6 Distinta Materiali', sx, sy + 10);",
    "ctx.fillText('\\ud83d\\udce6 Riepilogo Fasce', sx, sy + 10);",
    "25. Sidebar header")

# ============================================================
# 26. Distinta grand total
# ============================================================
do_replace(
    "'Riepilogo globale \\u2014 '",
    "'Riepilogo per fasce \\u2014 '",
    "26. Grand total")

# ============================================================
# WRITE OUTPUT
# ============================================================
outfile = 'tracciato6.php'
# Extra backup of current state
if os.path.exists(outfile) and src != outfile:
    shutil.copy2(outfile, outfile + '.pre_rebuild')

with open(outfile, 'w', encoding='utf-8') as f:
    f.write(c)

print(f"\n{'='*50}")
print(f"✅ {changes} modifiche applicate")
print(f"📦 Output: {outfile} ({len(c):,} bytes)")

# Final check for old PN references
print(f"\nVerifica residui:")
for old in ["'PN6'", "'PN10'", "'PN16'", "'PN25'", "'PN40'"]:
    n = c.count(old)
    if n:
        # Find line numbers
        lines = c.split('\n')
        for i, line in enumerate(lines, 1):
            if old in line:
                print(f"  ⚠️  {old} riga {i}: {line.strip()[:80]}")
    else:
        print(f"  ✅ {old} — pulito")

print(f"\n🎉 Fatto! Ricarica https://gaa.wpeitalia.eu/ e testa il pannello Pressioni")
