#!/usr/bin/env python3
"""Genera dashboard FAK — multi-carrier con richieste integrate"""
import json, os
from datetime import datetime

BASE = os.path.expanduser("~/.hermes/fak-comparison")
DATA_FILE = os.path.join(BASE, "comparison_data.json")
OUTPUT_FILE = os.path.join(BASE, "fak_dashboard.html")

def load_data():
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE) as f:
            return json.load(f)
    return {"rates": {}, "surcharges": {}, "metadata": {}}

def main():
    data = load_data()
    carriers = list(data.get("rates", {}).keys())
    
    # Raccogli tutte le rotte
    all_routes = {}
    for carrier in carriers:
        routes = data["rates"].get(carrier, {})
        if not isinstance(routes, dict):
            continue
        for key, rate in routes.items():
            if key not in all_routes:
                all_routes[key] = {"pol": rate.get("pol",""), "pol_name": rate.get("pol_name",""), "pod": rate.get("pod","")}
            if carrier not in all_routes[key]:
                all_routes[key][carrier] = {}
            all_routes[key][carrier] = {"20": rate.get("20"), "40": rate.get("40"), "40h": rate.get("40h")}
    
    now = datetime.now().strftime("%d/%m/%Y %H:%M")
    routes_json = json.dumps(all_routes)
    carriers_json = json.dumps(carriers)
    surcharges_json = json.dumps(data.get("surcharges", {}))
    
    # Costruisci HTML come stringa semplice (non f-string multilinea per evitare troncamenti)
    html = '<!DOCTYPE html>\n'
    html += '<html lang="it">\n<head>\n<meta charset="UTF-8">\n'
    html += '<meta name="viewport" content="width=device-width,initial-scale=1.0">\n'
    html += '<title>FAK Confronto — Cippà Trasporti</title>\n'
    html += '<style>\n'
    html += '*{margin:0;padding:0;box-sizing:border-box;}\n'
    html += 'body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:#0d1117;color:#c9d1d9;}\n'
    html += '.header{background:linear-gradient(135deg,#161b22,#0d1117);border-bottom:1px solid #30363d;padding:16px 24px;}\n'
    html += '.header h1{color:#58a6ff;font-size:22px;}\n'
    html += '.header h1 span{color:#8b949e;font-weight:400;font-size:13px;}\n'
    html += '.header .sub{color:#8b949e;font-size:12px;margin-top:4px;}\n'
    html += '.qs{background:linear-gradient(135deg,#1a2332,#0d1117);border:2px solid #d29922;border-radius:12px;margin:16px 24px;padding:20px;}\n'
    html += '.qs .qt{color:#d29922;font-size:18px;font-weight:700;margin-bottom:14px;}\n'
    html += '.qs .qt small{color:#8b949e;font-weight:400;font-size:12px;}\n'
    html += '.qg{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;align-items:end;}\n'
    html += '.qf label{display:block;color:#8b949e;font-size:11px;margin-bottom:3px;text-transform:uppercase;}\n'
    html += '.qf input,.qf select{width:100%;background:#0d1117;border:1px solid #30363d;color:#c9d1d9;padding:8px 10px;border-radius:6px;font-size:14px;outline:none;}\n'
    html += '.qf input:focus,.qf select:focus{border-color:#d29922;}\n'
    html += '.qb{background:#d29922;color:#0d1117;font-weight:700;border:none;padding:8px 20px;border-radius:6px;cursor:pointer;font-size:14px;height:38px;}\n'
    html += '.qb:hover{background:#e3b341;}\n'
    html += '.qb2{background:#21262d;color:#c9d1d9;border:1px solid #30363d;padding:8px 16px;border-radius:6px;cursor:pointer;font-size:13px;height:38px;}\n'
    html += '.qb2:hover{border-color:#8b949e;}\n'
    html += '.rp{background:#161b22;border:1px solid #30363d;border-radius:10px;margin:0 24px 14px;padding:18px 22px;display:none;}\n'
    html += '.rp.show{display:block;}\n'
    html += '.rp .rw{display:flex;flex-wrap:wrap;gap:16px;align-items:center;}\n'
    html += '.rp .wn{font-size:24px;font-weight:700;color:#3fb950;flex:1;min-width:200px;}\n'
    html += '.rp .wn small{font-size:14px;color:#8b949e;}\n'
    html += '.rp .pr{text-align:right;}\n'
    html += '.rp .pr .it{display:inline-block;margin:0 6px;padding:4px 10px;border-radius:6px;font-size:13px;}\n'
    html += '.rp .pr .it.best{background:#23863622;color:#3fb950;font-weight:700;}\n'
    html += '.rp .pr .it.oth{background:#21262d;color:#8b949e;}\n'
    html += '.rp .sv{color:#d29922;font-weight:600;font-size:15px;margin-top:6px;}\n'
    html += '.co{padding:0 24px 16px;}\n'
    html += '.st{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:12px;}\n'
    html += '.sc{background:#161b22;border:1px solid #30363d;border-radius:8px;padding:10px 14px;flex:1;min-width:80px;text-align:center;}\n'
    html += '.sc .n{font-size:20px;font-weight:700;color:#58a6ff;}\n'
    html += '.sc .l{font-size:10px;color:#8b949e;text-transform:uppercase;}\n'
    html += '.tb{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:12px;}\n'
    html += '.tb input,.tb select{background:#21262d;border:1px solid #30363d;color:#c9d1d9;padding:5px 10px;border-radius:6px;font-size:12px;outline:none;}\n'
    html += '.tb input:focus,.tb select:focus{border-color:#58a6ff;}\n'
    html += '.tb label{color:#8b949e;font-size:11px;}\n'
    html += '.tb .btn{background:#238636;color:#fff;border:none;padding:5px 12px;border-radius:6px;cursor:pointer;font-size:12px;}\n'
    html += '.tb .btn:hover{background:#2ea043;}\n'
    html += '.tb .b2{background:transparent;border:1px solid #30363d;color:#c9d1d9;}\n'
    html += '.tb .b2:hover{border-color:#58a6ff;color:#58a6ff;}\n'
    html += '.tb .cnt{color:#8b949e;font-size:12px;flex:1;text-align:right;}\n'
    html += '.pl{display:flex;gap:4px;flex-wrap:wrap;margin-bottom:10px;}\n'
    html += '.pl .pi{background:#21262d;border:1px solid #30363d;color:#8b949e;padding:3px 12px;border-radius:16px;cursor:pointer;font-size:11px;user-select:none;}\n'
    html += '.pl .pi.act{background:#1f6feb33;border-color:#58a6ff;color:#58a6ff;}\n'
    html += '.tw{overflow-x:auto;}\n'
    html += 'table{width:100%;border-collapse:collapse;font-size:12px;}\n'
    html += 'th{background:#1c2333;color:#58a6ff;padding:6px 8px;text-align:left;border-bottom:2px solid #30363d;position:sticky;top:0;z-index:10;white-space:nowrap;}\n'
    html += 'td{padding:4px 8px;border-bottom:1px solid #21262d;}\n'
    html += 'tr:hover{background:#1c233322;}\n'
    html += '.bp{color:#3fb950;font-weight:700;}\n'
    html += '.bb{display:inline-block;background:#23863622;color:#3fb950;padding:2px 6px;border-radius:4px;font-size:11px;font-weight:600;}\n'
    html += '.em{text-align:center;padding:30px;color:#484f58;}\n'
    html += '.dt{background:#161b22;border:1px solid #30363d;border-radius:8px;padding:14px;margin-top:14px;}\n'
    html += '.dt h3{color:#f0883e;font-size:15px;margin-bottom:8px;}\n'
    html += '.sg{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:8px;}\n'
    html += '.sk{background:#21262d;border-radius:6px;padding:10px;}\n'
    html += '.sk h4{color:#58a6ff;font-size:12px;margin-bottom:4px;}\n'
    html += '.sk .v{font-size:11px;}\n'
    html += '.sk .n{color:#8b949e;font-size:10px;font-style:italic;}\n'
    html += '.ft{text-align:center;color:#484f58;font-size:10px;border-top:1px solid #21262d;padding:10px;margin-top:14px;}\n'
    html += '@media(max-width:700px){.qg{grid-template-columns:1fr 1fr;}}\n'
    html += '</style>\n</head>\n<body>\n'
    
    # Header
    html += '<div class="header"><h1>&#128674; FAK Confronto Tariffe <span>Cipp&agrave; Trasporti</span></h1>'
    html += '<div class="sub">Far East &rarr; Italia &middot; '+now+'</div></div>\n'
    
    # Quote section
    html += '<div class="qs"><div class="qt">&#127942; Richiedi il miglior prezzo <small>su tutti i carrier</small></div>'
    html += '<div class="qg">'
    html += '<div class="qf"><label>POL (Partenza)</label><input type="text" id="rq-pol" list="pol-list" placeholder="es. Shanghai"></div>'
    html += '<datalist id="pol-list"></datalist>'
    html += '<div class="qf"><label>POD (Destinazione)</label><input type="text" id="rq-pod" list="pod-list" placeholder="es. Genova"></div>'
    html += '<datalist id="pod-list"></datalist>'
    html += '<div class="qf"><label>Tipo</label><select id="rq-type"><option value="20">20\'</option><option value="40" selected>40\'</option><option value="40h">40HC</option></select></div>'
    html += '<div style="display:flex;gap:6px;"><button class="qb" onclick="findBestPrice()">&#128269; Trova</button>'
    html += '<button class="qb2" onclick="clearQuote()">&#10005;</button></div>'
    html += '</div></div>\n'
    
    # Result panel
    html += '<div class="rp" id="rp"><div id="rc"></div></div>\n'
    
    # Container
    html += '<div class="co">'
    html += '<div class="st" id="st"></div>'
    html += '<div class="pl" id="pl"></div>'
    html += '<div class="tb">'
    html += '<label>POL</label><input type="text" id="f-pol" placeholder="es. Shanghai" oninput="fr()">'
    html += '<label>POD</label><input type="text" id="f-pod" placeholder="es. Genova" oninput="fr()">'
    html += '<label>Tipo</label><select id="f-type" onchange="fr()"><option value="20">20\'</option><option value="40" selected>40\'</option><option value="40h">40HC</option></select>'
    html += '<button class="btn b2" onclick="rf()">&#10005; Reset</button>'
    html += '<span class="cnt" id="cnt"></span>'
    html += '</div>'
    html += '<div class="tw"><table id="rt"><thead id="rh"></thead><tbody id="rb"></tbody></table></div>'
    html += '<div class="dt"><h3>&#128176; Soprattasse per Carrier</h3><div class="sg" id="sg"></div></div>'
    html += '</div>\n'
    
    html += '<div class="ft">FAK Comparison System v3.0 &middot; Multi-Carrier &middot; Circuito Privato Cipp&agrave; Trasporti &middot; &#129426; Emma</div>\n'
    
    # JavaScript
    html += '<script>\n'
    html += 'var R='+routes_json+';\n'
    html += 'var C='+carriers_json+';\n'
    html += 'var SC='+surcharges_json+';\n'
    html += 'var AP=new Set(C);\n'
    html += 'function fl(){var ps={},ds={};Object.values(R).forEach(function(r){if(r.pol_name)ps[r.pol_name]=1;if(r.pol)ps[r.pol]=1;if(r.pod)ds[r.pod]=1;});'
    html += "document.getElementById('pol-list').innerHTML=Object.keys(ps).sort().map(function(p){return '<option value=\"'+p+'\">';}).join('');"
    html += "document.getElementById('pod-list').innerHTML=Object.keys(ds).sort().map(function(p){return '<option value=\"'+p+'\">';}).join('');}\n"
    html += "function fm(v){return v!=null?'$'+Number(v).toLocaleString():'&mdash;';}\n"
    html += 'function fbp(){var po=document.getElementById("rq-pol").value.trim().toUpperCase();'
    html += 'var pd=document.getElementById("rq-pod").value.trim().toUpperCase();'
    html += 'var ct=document.getElementById("rq-type").value;'
    html += 'if(!po||!pd){alert("Inserisci POL e POD");return;}'
    html += 'var ms=[];'
    html += 'Object.entries(R).forEach(function(e){var r=e[1];'
    html += 'var pm=(r.pol_name||"").toUpperCase().includes(po)||(r.pol||"").toUpperCase().includes(po);'
    html += 'var dm=(r.pod||"").toUpperCase().includes(pd);'
    html += 'if(pm&&dm)C.forEach(function(c){var v=r[c]?r[c][ct]:null;if(v)ms.push({carrier:c,price:v,pol:r.pol_name||r.pol,pod:r.pod});});});'
    html += 'var rp=document.getElementById("rp");var rc=document.getElementById("rc");'
    html += 'if(!ms.length){rc.innerHTML="<div style=\\"color:#f85149;font-weight:600;\\">Nessuna tariffa trovata</div>";rp.classList.add("show");return;}'
    html += 'ms.sort(function(a,b){return a.price-b.price;});'
    html += 'var best=ms[0];var worst=ms[ms.length-1];var sv=worst.price-best.price;'
    html += 'var h="<div class=\\"rw\\"><div class=\\"wn\\">&#127942; "+best.carrier.toUpperCase()+" &mdash; "+fm(best.price)+"<br><small>"+best.pol+" &rarr; "+best.pod+" &middot; "+ct+"\'</small></div><div class=\\"pr\\">";'
    html += 'ms.forEach(function(p){var cls=p.price===best.price?"best":"oth";h+="<span class=\\"it "+cls+"\\">"+p.carrier.toUpperCase()+" "+fm(p.price)+(p.price===best.price?" &#10004;":"")+"</span>";});'
    html += 'if(sv>0)h+="<div class=\\"sv\\">&#128176; Risparmio: "+fm(sv)+"</div>";'
    html += 'h+="</div></div>";rc.innerHTML=h;rp.classList.add("show");rp.scrollIntoView({behavior:"smooth",block:"center"});}\n'
    html += 'function cq(){document.getElementById("rq-pol").value="";document.getElementById("rq-pod").value="";document.getElementById("rp").classList.remove("show");}\n'
    
    # Stats
    html += 'function rs(){var t=Object.keys(R).length;var cn={};C.forEach(function(c){cn[c]=0;});'
    html += 'Object.values(R).forEach(function(r){C.forEach(function(c){if(r[c])cn[c]++;});});'
    html += 'var h="<div class=\\"sc\\"><div class=\\"n\\">"+t+"</div><div class=\\"l\\">Rotte totali</div></div>";'
    html += 'C.forEach(function(c){h+="<div class=\\"sc\\"><div class=\\"n\\" style=\\"color:#3fb950\\">"+(cn[c]||0)+"</div><div class=\\"l\\">"+c.toUpperCase()+"</div></div>";});'
    html += 'document.getElementById("st").innerHTML=h;}\n'
    
    # Pills
    html += 'function rpills(){var h="";'
    html += 'h+="<span class=\\"pi"+(AP.size===C.length?" act":"")+"\\" onclick=\\"tap()\\">Tutti</span>";'
    html += 'C.forEach(function(c){h+="<span class=\\"pi"+(AP.has(c)?" act":"")+"\\" onclick=\\"tp(\\""+c+"\\")\\">"+c.toUpperCase()+"</span>";});'
    html += 'document.getElementById("pl").innerHTML=h;}\n'
    html += 'function tp(c){if(AP.has(c))AP.delete(c);else AP.add(c);if(AP.size===0)AP=new Set(C);rpills();fr();}\n'
    html += 'function tap(){AP=AP.size===C.length?new Set():new Set(C);if(AP.size===0)AP=new Set(C);rpills();fr();}\n'
    
    # Filter
    html += 'function rf(){document.getElementById("f-pol").value="";document.getElementById("f-pod").value="";fr();}\n'
    html += 'function fr(){var po=document.getElementById("f-pol").value.toLowerCase().trim();'
    html += 'var pd=document.getElementById("f-pod").value.toLowerCase().trim();'
    html += 'var ct=document.getElementById("f-type").value;'
    html += 'var tg=Array.from(AP);'
    html += 'var en=Object.entries(R).filter(function(e){var r=e[1];'
    html += 'if(po&&!(r.pol_name||r.pol||"").toLowerCase().includes(po))return false;'
    html += 'if(pd&&!(r.pod||"").toLowerCase().includes(pd))return false;'
    html += 'return tg.some(function(c){return r[c]&&r[c][ct];});});'
    html += 'en.sort(function(a,b){return((a[1].pol_name||a[1].pol)||"").localeCompare((b[1].pol_name||b[1].pol)||"")||((a[1].pod||"")).localeCompare((b[1].pod||""));});'
    html += 'document.getElementById("cnt").textContent=en.length+" rotte";'
    html += 'var hh="<th>POL &rarr; POD</th>";'
    html += 'tg.forEach(function(c){hh+="<th>"+c.toUpperCase()+" "+ct+"\'</th>";});'
    html += 'hh+="<th>&#127942; Migliore</th><th>&#128176; Risparmio</th>";'
    html += 'document.getElementById("rh").innerHTML=hh;'
    html += 'var bd="";if(!en.length){bd="<tr><td colspan=\\""+(tg.length+3)+"\\" class=\\"em\\">Nessuna rotta</td></tr>";}else{'
    html += 'en.forEach(function(e){var r=e[1];var pn=r.pol_name||r.pol||"?";var dn=r.pod||"?";'
    html += 'bd+="<tr><td><strong>"+pn+"</strong> &rarr; "+dn+"</td>";'
    html += 'var pr=[];tg.forEach(function(c){var v=r[c]?r[c][ct]:null;if(v)pr.push({c:c,v:v});bd+="<td>"+fm(v)+"</td>";});'
    html += 'if(pr.length>1){var b=pr.reduce(function(a,b){return a.v<b.v?a:b;});var w=pr.reduce(function(a,b){return a.v>b.v?a:b;});'
    html += 'bd+="<td><span class=\\"bb\\">&#10004; "+b.c.toUpperCase()+" "+fm(b.v)+"</span></td><td class=\\"bp\\">"+fm(w.v-b.v)+"</td>";}'
    html += 'else if(pr.length===1){bd+="<td><span class=\\"bb\\">"+pr[0].c.toUpperCase()+" "+fm(pr[0].v)+"</span></td><td>&mdash;</td>";}'
    html += 'else{bd+="<td>&mdash;</td><td>&mdash;</td>";}'
    html += 'bd+="</tr>";});}'
    html += 'document.getElementById("rb").innerHTML=bd;}\n'
    
    # Surcharges
    html += 'function rsc(){var h="";Object.entries(SC).forEach(function(e){var ca=e[0],sc=e[1];'
    html += 'h+="<div class=\\"sk\\"><h4>"+ca.toUpperCase()+"</h4>";'
    html += 'Object.entries(sc).forEach(function(e2){var nm=e2[0],inf=e2[1];'
    html += 'if(typeof inf==="object"&&!Array.isArray(inf)){var a=inf.amount||"",n=inf.note||"",u=inf.unit||"",cu=inf.currency||"";'
    html += 'h+="<div class=\\"v\\">&bull; <strong>"+nm.toUpperCase()+"</strong>: "+a+(cu?" "+cu:"")+(u?"/"+u:"")+"</div>";if(n)h+="<div class=\\"n\\">"+n+"</div>";}'
    html += 'else if(Array.isArray(inf)){h+="<div class=\\"v\\">&bull; "+nm.toUpperCase()+": "+inf.join(", ")+"</div>";}'
    html += 'else{h+="<div class=\\"v\\">&bull; "+nm.toUpperCase()+": "+inf+"</div>";}});h+="</div>";});'
    html += 'document.getElementById("sg").innerHTML=h;}\n'
    
    # Init
    html += 'fl();rs();rpills();fr();rsc();\n'
    html += '</script>\n</body>\n</html>'
    
    with open(OUTPUT_FILE, "w") as f:
        f.write(html)
    
    size = os.path.getsize(OUTPUT_FILE)
    print(f"[OK] Dashboard generata: {OUTPUT_FILE} ({size} byte)")

if __name__ == "__main__":
    main()
