import subprocess, os, json

server_ip = '192.168.70.40'
login_sh  = '/usr/local/etc/chilli/www/login.chi.sh'

# ── Write portal_js.js ────────────────────────────────────────────────────────
js = r"""var lang='en';
function changeLang(l){if(!T||!T[l])return;lang=l;var t=T[l];var rtl=(l==='ar'||l==='he');document.body.setAttribute('dir',rtl?'rtl':'ltr');function ss(id,v){var e=document.getElementById(id);if(e&&v)e.innerHTML=v;}function sp(id,v){var e=document.getElementById(id);if(e&&v)e.placeholder=v;}ss('page-title',t.title);ss('page-subtitle',t.subtitle);ss('connected-text',t.connected);ss('enjoy-text',t.enjoy);ss('disconnect-btn',t.disconnect);ss('lbl-uuser',t.userLabel);ss('lbl-upass',t.passLabel);ss('user-btn',t.connectBtn);sp('u-user',t.userPH);sp('u-pass',t.passPH);applyPmsLang();try{localStorage.setItem('portalLang',l);}catch(e){}}
function applyPmsLang(){if(!T)return;var t=T[lang]||T['en'];var rtl=(lang==='ar'||lang==='he');var fm={room:{label:t.roomLabel,ph:t.roomPH},first_name:{label:t.firstNameLabel,ph:t.firstNamePH},last_name:{label:t.lastNameLabel,ph:t.lastNamePH},email:{label:t.emailLabel,ph:t.emailPH},phone:{label:t.phoneLabel,ph:t.phonePH},arrival:{label:t.arrivalLabel},departure:{label:t.departureLabel},resv_id:{label:t.resvIdLabel,ph:t.resvIdPH}};document.querySelectorAll('.pms-form-section').forEach(function(form,idx){var btn=document.getElementById('pms-btn-'+idx);if(btn&&t.connectBtn)btn.textContent=t.connectBtn;form.querySelectorAll('.inp-field').forEach(function(inp){var fi=inp.dataset.field;if(!fi||!fm[fi])return;var m=fm[fi];var wrap=inp.closest('.inp-wrap');var lbl=wrap?wrap.querySelector('.inp-label'):null;if(lbl&&m.label)lbl.textContent=m.label;if(inp.type!=='date'&&m.ph)inp.placeholder=m.ph;inp.dir=rtl?'rtl':'ltr';});});}
function switchPmsTab(i){document.querySelectorAll('.pms-tab-btn').forEach(function(b,j){b.classList.toggle('active',j===i);});document.querySelectorAll('.pms-form-section').forEach(function(f,j){f.classList.toggle('active',j===i);});}
function connectPms(idx){var form=document.getElementById('pms-form-'+idx);var btn=document.getElementById('pms-btn-'+idx);var msgEl=document.getElementById('pms-status-'+idx);var t=(T&&T[lang])||{};if(!form||!btn)return;var fields={};var valid=true;form.querySelectorAll('.inp-field').forEach(function(inp){var val=inp.value.trim();if(!val&&inp.required){inp.style.borderColor='#e53e3e';valid=false;}else{inp.style.borderColor='';}fields[inp.dataset.field]=val;});if(!valid){if(msgEl){msgEl.textContent=t.roomErr||'Please fill all fields.';msgEl.className='pms-msg error';msgEl.style.display='block';}return;}btn.disabled=true;if(msgEl){msgEl.textContent=t.pmsVerifying||'Verifying...';msgEl.className='pms-msg info';msgEl.style.display='block';}var cbName='__pmsCb'+idx+'_'+Date.now();var params='callback='+cbName;Object.keys(fields).forEach(function(k){params+='&'+encodeURIComponent(k)+'='+encodeURIComponent(fields[k]);});var timer=setTimeout(function(){delete window[cbName];btn.disabled=false;if(msgEl){msgEl.textContent=t.pmsError||'Timeout';msgEl.className='pms-msg error';}},12000);window[cbName]=function(data){clearTimeout(timer);delete window[cbName];if(data&&data.ok){if(msgEl){msgEl.textContent=t.connecting||'Connecting...';msgEl.className='pms-msg info';}authenticate(data.username,data.password,'pms-btn-'+idx);}else{btn.disabled=false;var msg=(data&&data.message)||(t.pmsNotFound||'Guest not found.');if(msgEl){msgEl.textContent=msg;msgEl.className='pms-msg error';}}};var s=document.createElement('script');s.src='/daloradius/pms-verify.php?'+params;document.head.appendChild(s);}
function showStatus(msg,type){var el=document.getElementById('statusMsg');el.innerHTML=msg;el.className=type;el.style.display='block';}
function safeEncode(s){return encodeURIComponent(s).replace(/%40/g,'@');}
function getParam(name){var m=RegExp('[?&]'+name+'=([^&]*)').exec(window.location.search);return m&&decodeURIComponent(m[1]);}
var clientIP=getParam('ip')||getParam('uamip')||'';
function submitUser(){var user=document.getElementById('u-user').value.trim();var pass=document.getElementById('u-pass').value;var t=(T&&T[lang])||{};if(!user||!pass){showStatus(t.userErr||'Please fill all fields.','error-msg');return;}document.getElementById('user-btn').disabled=true;showStatus(t.connecting||'Connecting...','info-msg');authenticate(user,pass,'user-btn');}
function authenticate(username,password,btnId){if(!clientIP){getClientIP(function(ip){clientIP=ip;callAuth(username,password,ip,btnId);});}else{callAuth(username,password,clientIP,btnId);}}
function getClientIP(cb){var cbName='_ipcb'+Math.floor(Math.random()*1000000);window[cbName]=function(data){delete window[cbName];cb(data&&data.session?data.session.ipAddress:'');};var s=document.createElement('script');s.src='http://'+uamIP+':'+uamPort+'/json/status?callback='+cbName;s.onerror=function(){cb('');};document.head.appendChild(s);setTimeout(function(){if(window[cbName]){delete window[cbName];cb('');}},3000);}
function callAuth(username,password,ip,btnId){var t=(T&&T[lang])||{};var cbName='_authcb'+Math.floor(Math.random()*1000000);var timer=setTimeout(function(){if(window[cbName]){delete window[cbName];showStatus(t.timedOut||'Timed out','error-msg');var b=document.getElementById(btnId);if(b)b.disabled=false;}},15000);window[cbName]=function(data){clearTimeout(timer);delete window[cbName];if(data&&data.result==='success'){showStatus(t.connectedMsg||'Connected!','success-msg');document.getElementById('loginSection').style.display='none';document.getElementById('logoutSection').style.display='block';setTimeout(function(){window.location.href=redirectUrl||'';},2000);}else if(data&&data.result==='fail'){showStatus(data.message||t.invalidCreds||'Invalid credentials','error-msg');var b=document.getElementById(btnId);if(b)b.disabled=false;}else{showStatus(t.connError||'Connection error','error-msg');var b=document.getElementById(btnId);if(b)b.disabled=false;}};var s=document.createElement('script');s.src='http://'+uamIP+':'+uiPort+'/www/auth.chi?username='+safeEncode(username)+'&password='+safeEncode(password)+'&ip='+encodeURIComponent(ip)+'&callback='+cbName;s.onerror=function(){clearTimeout(timer);showStatus(t.connError||'Error','error-msg');var b=document.getElementById(btnId);if(b)b.disabled=false;};document.head.appendChild(s);}
function doLogout(){var t=(T&&T[lang])||{};var cbName='_locb'+Math.floor(Math.random()*1000000);window[cbName]=function(){delete window[cbName];};var s=document.createElement('script');s.src='http://'+uamIP+':'+uamPort+'/json/logoff?callback='+cbName;document.head.appendChild(s);document.getElementById('loginSection').style.display='block';document.getElementById('logoutSection').style.display='none';showStatus(t.disconnected||'Disconnected','info-msg');}
window.addEventListener('load',function(){var saved='en';try{saved=localStorage.getItem('portalLang')||'en';}catch(e){}changeLang(saved);});
"""

# ── Read DB config ────────────────────────────────────────────────────────────
r = subprocess.run(['php','-r',"""
$pdo=new PDO('mysql:host=localhost;dbname=radius','radius','radpass123');
$row=$pdo->query('SELECT config_json FROM login_form_config LIMIT 1')->fetch();
echo $row['config_json']??'{}';
"""], capture_output=True, text=True)

config  = json.loads(r.stdout) if r.stdout.strip() else {}
style   = config.get('style', {})
forms   = config.get('forms', [{'combination':2,'tab_name':'Guest Login'}])
primary = style.get('primary_color','#cc0000')
btn_clr = style.get('btn_color','#610000')
bg      = style.get('bg_color','#ffffff')
font    = style.get('font','Lato')
bg_img  = style.get('bg_image','')
logo    = style.get('logo_image','')
print(f"Config: {len(forms)} forms, primary={primary}, font={font}")

COMBINATIONS = {
    0:['__users__'],1:['room','first_name','email'],2:['room','first_name'],
    3:['room','last_name'],4:['room','last_name','email'],5:['room','arrival','email'],
    6:['room','arrival'],7:['room','departure','email'],8:['room','departure'],
    9:['room','resv_id'],10:['room','resv_id','email'],11:['room','resv_id','first_name'],
    12:['room','resv_id','last_name'],13:['room','arrival','departure','email'],
    14:['room','first_name','phone'],15:['room','last_name','phone'],
    16:['room','first_name','last_name'],17:['room','first_name','last_name','email'],
    18:['room','first_name','last_name','phone'],19:['room','arrival','phone'],
    20:['room','resv_id','phone'],
}
FIELD_META = {
    '__users__':('Username + Password','text',''),
    'room':('Room Number','text','e.g. 204'),
    'first_name':('First Name','text','e.g. Ahmed'),
    'last_name':('Last Name','text','e.g. Smith'),
    'arrival':('Arrival Date','date',''),
    'departure':('Departure Date','date',''),
    'resv_id':('Reservation ID','text','e.g. 63483'),
    'email':('Email Address','email','e.g. you@email.com'),
    'phone':('Phone Number','tel','e.g. +20100...'),
}

tab_btns = ''
form_secs = ''
for i, form in enumerate(forms):
    cid    = int(form.get('combination',1))
    fields = COMBINATIONS.get(cid, COMBINATIONS[1])
    tname  = form.get('tab_name','Guest Login')
    act    = ' active' if i==0 else ''
    tab_btns += f'<button class="pms-tab-btn{act}" onclick="switchPmsTab({i})">{tname}</button>\n'
    inputs = ''
    for field in fields:
        if field not in FIELD_META: continue
        label,ftype,ph = FIELD_META[field]
        if ftype=='date':
            inputs += f'<div class="inp-wrap"><label class="inp-label">{label}</label><input type="date" class="inp-field" data-field="{field}" required/></div>\n'
        else:
            inputs += f'<div class="inp-wrap"><label class="inp-label">{label}</label><input type="{ftype}" class="inp-field" placeholder="{ph}" data-field="{field}" required/></div>\n'
    form_secs += f'<div class="pms-form-section{act}" id="pms-form-{i}">\n{inputs}<div id="pms-status-{i}" class="pms-status" style="display:none"></div>\n<button class="connect-btn" onclick="connectPms({i})" id="pms-btn-{i}">Connect</button></div>\n'

tabs_h = f'<div class="pms-tabs">\n{tab_btns}</div>' if len(forms)>1 else ''
pms_h  = f'<!-- PMS_FORMS_START -->\n<div class="pms-container">{tabs_h}{form_secs}</div>\n<!-- PMS_FORMS_END -->'
bg_css = f'background:url("{bg_img}") center center/cover no-repeat fixed;' if bg_img else f'background:{bg};'
logo_h = f'<div class="hello-emoji"><img src="{logo}" style="max-width:120px;max-height:80px;object-fit:contain;"/></div>' if logo else '<div class="hello-emoji">&#127760;</div>'

# ── Write login.chi.sh ────────────────────────────────────────────────────────
lines = []
lines.append('#!/bin/bash\n')
lines.append('. ./config.sh\n')
lines.append("REDIRECT_URL=$(cat /usr/local/etc/chilli/www/redirect.conf 2>/dev/null | tr -d '\\n\\r')\n\n")
lines.append("cat << 'HTMLEOF'\n")
lines.append("HTTP/1.0 200 OK\nContent-Type: text/html; charset=utf-8\nCache: none\n\n")
lines.append('<!DOCTYPE html>\n<html lang="en">\n<head>\n')
lines.append('<meta charset="UTF-8">\n<meta name="viewport" content="width=device-width,initial-scale=1.0">\n')
lines.append('<title>Welcome</title>\n')
lines.append(f'<script src="http://{server_ip}/daloradius/langs-serve.php"></script>\n')
lines.append(f'<link rel="stylesheet" href="http://{server_ip}/daloradius/portal.css"/>\n')
lines.append(f'<style>:root{{--primary:{primary};--btn-color:{btn_clr};--font:"{font}",sans-serif;}}body{{{bg_css}font-family:var(--font);}}</style>\n')
lines.append('</head>\n<body>\n<div class="container">\n')
lines.append('<div class="lang-switcher"><select onchange="changeLang(this.value)" id="lang-select">\n')
lines.append('<option value="en">&#127468;&#127463; English</option>\n<option value="ar">&#127466;&#127468; &#1575;&#1604;&#1593;&#1585;&#1576;&#1610;&#1577;</option>\n')
lines.append('<option value="fr">&#127467;&#127479; Fran&#231;ais</option>\n<option value="de">&#127465;&#127466; Deutsch</option>\n')
lines.append('<option value="es">&#127466;&#127480; Espa&#241;ol</option>\n<option value="it">&#127470;&#127481; Italiano</option>\n')
lines.append('<option value="ru">&#127479;&#127482; &#1056;&#1091;&#1089;&#1089;&#1082;&#1080;&#1081;</option>\n<option value="zh">&#127464;&#127475; &#20013;&#25991;</option>\n')
lines.append('<option value="tr">&#127481;&#127479; T&#252;rk&#231;e</option>\n<option value="he">&#127470;&#127473; &#1506;&#1489;&#1512;&#1497;&#1514;</option>\n')
lines.append('<option value="pt">&#127477;&#127481; Portugu&#234;s</option>\n</select></div>\n')
lines.append(logo_h + '\n')
lines.append('<h1 id="page-title">Welcome!</h1>\n<p class="subtitle" id="page-subtitle">Connect to the internet using your account.</p>\n')
lines.append('<div id="loginSection">\n')
lines.append('<div class="toggle-wrap" style="display:none!important"><button class="toggle-btn active" id="btn-guest">Guest</button><button class="toggle-btn" id="btn-user">Users</button></div>\n')
lines.append('<div class="form-section active" id="form-guest">\n' + pms_h + '\n</div>\n')
lines.append('<div class="form-section" id="form-user" style="display:none!important">\n')
lines.append('<div class="form-group"><label id="lbl-uuser">Username</label><input type="text" id="u-user" placeholder="Enter username"></div>\n')
lines.append('<div class="form-group"><label id="lbl-upass">Password</label><input type="password" id="u-pass" placeholder="Enter password"></div>\n')
lines.append('<button class="submit-btn" id="user-btn" onclick="submitUser()">Connect</button>\n</div>\n</div>\n')
lines.append('<div id="logoutSection" style="display:none"><p id="connected-text">&#9989; You are connected!</p><p id="enjoy-text">Enjoy your internet access.</p><button class="disconnect-btn" onclick="doLogout()" id="disconnect-btn">Disconnect</button></div>\n')
lines.append('<div id="statusMsg"></div>\n</div>\nHTMLEOF\n\n')
lines.append('cat << EOF\n<script>\nvar uamIP="${HS_UAMLISTEN}";\nvar uamPort=${HS_UAMPORT};\nvar uiPort=${HS_UAMUIPORT};\nvar redirectUrl="${REDIRECT_URL:-}";\nEOF\n\n')
lines.append("cat << 'SCRIPTEOF'\n")
lines.append(js)
lines.append('SCRIPTEOF\n')

with open(login_sh,'w') as f:
    f.writelines(lines)

os.chmod(login_sh, 0o755)

r = subprocess.run(['bash',login_sh], capture_output=True, text=True, cwd='/usr/local/etc/chilli/www')
out = r.stdout
ends_ok = out.strip().endswith('</html>')
syntax  = subprocess.run(['bash','-n',login_sh], capture_output=True).returncode==0
print(f"Output: {len(out)} bytes | ends </html>: {ends_ok} | syntax: {'OK' if syntax else 'ERR'}")

if ends_ok and syntax:
    subprocess.run(['systemctl','restart','chilli'])
    import time; time.sleep(3)
    print("🎉 Done! Test on mobile.")
else:
    print(r.stdout[-300:])
    if r.stderr: print("STDERR:", r.stderr[:200])

# ── Also rebuild the inline login page ────────────────────────────────────────
import subprocess as _sp
_sp.run(['python3', '/usr/local/etc/chilli/www/build_login.py'])

