#!/usr/bin/env python3
# ============================================================
# patch_scripts.py — Tambah panel Script Templates ke dashboard
# Jalankan di: /home/caracuanbiz/public_html/ict.offshoreai.biz.id/fgdash/
# ============================================================

with open('index.php', 'r') as f:
    content = f.read()

# ── 1. Tambah tab button ─────────────────────────────────────
old_tabs = """      <button class="ntab" onclick="showPanel('ai',this)">🤖 AI Assist</button>"""
new_tabs = """      <button class="ntab" onclick="showPanel('ai',this)">🤖 AI Assist</button>
      <button class="ntab" onclick="showPanel('scripts',this)">📜 Script Templates</button>"""

# ── 2. Tambah CSS untuk script panel ────────────────────────
old_css = """/* topo svg */
.topo-wrap{overflow-x:auto}
.topo-svg{min-width:580px;width:100%}"""

new_css = """/* topo svg */
.topo-wrap{overflow-x:auto}
.topo-svg{min-width:580px;width:100%}
/* script templates */
.script-cat{margin-bottom:24px}
.script-cat-title{font-size:11px;font-weight:600;color:var(--text3);text-transform:uppercase;letter-spacing:.08em;margin-bottom:8px;display:flex;align-items:center;gap:6px}
.script-card{background:var(--bg2);border:1px solid var(--border);border-radius:10px;margin-bottom:8px;overflow:hidden;transition:.15s}
.script-card:hover{border-color:var(--border2)}
.script-header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;cursor:pointer}
.script-header-left{display:flex;align-items:center;gap:8px}
.script-title{font-size:13px;font-weight:500;color:var(--text)}
.script-desc{font-size:11px;color:var(--text3);margin-top:1px}
.script-body{display:none;border-top:1px solid var(--border);padding:12px 14px}
.script-body.open{display:block}
.script-code{background:var(--bg);border:1px solid var(--border2);border-radius:6px;padding:10px 12px;font-family:'JetBrains Mono',monospace;font-size:12px;color:#93C5FD;white-space:pre;overflow-x:auto;position:relative;line-height:1.6}
.script-actions{display:flex;gap:6px;margin-top:8px}
.script-btn{padding:5px 12px;border:1px solid var(--border2);border-radius:5px;font-size:12px;cursor:pointer;font-family:inherit;transition:.15s}
.script-btn-copy{background:var(--bg3);color:var(--text2)}
.script-btn-copy:hover{background:#1E3A5F;color:#93C5FD;border-color:#1D4ED8}
.script-btn-ai{background:#1E2A1E;color:#34D399;border-color:#065F46}
.script-btn-ai:hover{background:#022C22}
.script-tag{font-size:10px;padding:2px 7px;border-radius:3px;font-weight:500}
.tag-diag{background:#1E3A5F;color:#93C5FD}
.tag-user{background:#2E1065;color:#C4B5FD}
.tag-sec{background:#3B0606;color:#FCA5A5}
.tag-net{background:#022C22;color:#34D399}
.tag-sys{background:#422006;color:#FDBA74}
.script-search{width:100%;background:var(--bg2);border:1px solid var(--border2);border-radius:8px;padding:9px 14px;font-size:13px;color:var(--text);font-family:inherit;margin-bottom:16px}
.script-search:focus{outline:none;border-color:var(--accent)}
.script-filter{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px}
.filter-btn{padding:5px 12px;border:1px solid var(--border2);border-radius:6px;font-size:12px;cursor:pointer;background:var(--bg2);color:var(--text2);font-family:inherit}
.filter-btn.active{background:#1E3A5F;color:#93C5FD;border-color:#1D4ED8}
.copy-toast{position:fixed;bottom:20px;right:20px;background:#022C22;border:1px solid #065F46;color:#34D399;padding:10px 16px;border-radius:8px;font-size:13px;z-index:999;display:none}"""

# ── 3. Tambah panel HTML sebelum </div><!-- /content --> ─────
old_content_end = """  </div><!-- /content -->
</div><!-- /app -->"""

new_scripts_panel = """  </div><!-- /content -->
</div><!-- /app -->
<div class="copy-toast" id="copy-toast">✅ Tersalin ke clipboard</div>"""

# ── 4. Panel HTML lengkap ────────────────────────────────────
old_ai_panel_end = """    <!-- AI ASSIST -->"""

new_scripts_before_ai = """    <!-- SCRIPT TEMPLATES -->
    <div class="panel" id="p-scripts">
      <div class="section-h">Script Templates — FortiGate CLI</div>
      <p style="font-size:13px;color:var(--text3);margin-bottom:12px">Koleksi script CLI siap pakai untuk troubleshoot, manage user, dan monitoring FortiGate mermaid-mrl.</p>

      <input class="script-search" type="text" id="script-search" placeholder="🔍 Cari script... (contoh: session, user, routing, wan)" oninput="filterScripts()">

      <div class="script-filter">
        <button class="filter-btn active" onclick="filterCat('all',this)">Semua</button>
        <button class="filter-btn" onclick="filterCat('diag',this)">🔍 Diagnostik</button>
        <button class="filter-btn" onclick="filterCat('user',this)">👥 User Mgmt</button>
        <button class="filter-btn" onclick="filterCat('sec',this)">🔐 Security</button>
        <button class="filter-btn" onclick="filterCat('net',this)">🌐 Network</button>
        <button class="filter-btn" onclick="filterCat('sys',this)">⚙️ System</button>
      </div>

      <div id="scripts-container"></div>
    </div>

    <!-- AI ASSIST -->"""

# ── 5. JavaScript untuk script templates ─────────────────────
old_script_end = """</script>
</body>
</html>"""

new_script_js = """
// ── Script Templates ──────────────────────────────────────
const SCRIPTS = [
  // ── DIAGNOSTIK ──
  {cat:'diag', icon:'🔍', title:'Status semua interface', desc:'Tampilkan status, IP, dan statistik semua interface',
   code:`get system interface physical`,
   note:'Output: nama interface, status up/down, IP address, speed, duplex'},

  {cat:'diag', icon:'🔍', title:'Cek WAN link detail', desc:'Diagnosa link WAN1 (VSAT), WAN2 (Starlink2), port2 (Starlink1)',
   code:`# Cek WAN1 - VSAT2
diagnose netlink interface list wan1

# Cek WAN2 - Starlink2
diagnose netlink interface list wan2

# Cek port2 - Starlink1
diagnose netlink interface list port2`,
   note:'Cek speed, duplex, error counter, RX/TX bytes'},

  {cat:'diag', icon:'🔍', title:'Ping test dari FortiGate', desc:'Test konektivitas dari setiap WAN interface',
   code:`# Ping via WAN1 (VSAT)
execute ping-options source wan1
execute ping 8.8.8.8

# Ping via WAN2 (Starlink2)
execute ping-options source wan2
execute ping 8.8.8.8

# Ping via port2 (Starlink1)
execute ping-options source port2
execute ping 8.8.8.8`,
   note:'Gunakan untuk verifikasi konektivitas per WAN link'},

  {cat:'diag', icon:'🔍', title:'Statistik session aktif', desc:'Lihat jumlah session dan statistik trafik',
   code:`# Statistik ringkas
diagnose sys session stat

# Daftar session (filter by source IP)
diagnose sys session filter src 10.20.11.100
diagnose sys session list

# Clear filter
diagnose sys session filter clear`,
   note:'Ganti 10.20.11.100 dengan IP yang ingin dicek'},

  {cat:'diag', icon:'🔍', title:'Debug trafik real-time', desc:'Capture dan debug paket trafik',
   code:`# Enable debug flow
diagnose debug enable
diagnose debug flow filter addr 10.20.11.100
diagnose debug flow filter port 443
diagnose debug flow show function-name enable
diagnose debug flow trace start 100

# Setelah selesai debug — WAJIB matikan
diagnose debug flow trace stop
diagnose debug reset
diagnose debug disable`,
   note:'⚠️ Matikan debug setelah selesai — bisa membebani CPU'},

  {cat:'diag', icon:'🔍', title:'Traceroute', desc:'Trace jalur routing ke destination',
   code:`# Traceroute ke internet
execute traceroute 8.8.8.8

# Traceroute dengan source interface
execute ping-options source wan1
execute traceroute 8.8.8.8`,
   note:'Identifikasi hop dan latency di setiap jalur'},

  {cat:'diag', icon:'🔍', title:'Policy lookup (packet test)', desc:'Simulasi paket untuk cek policy yang akan dipakai',
   code:`# Format: diagnose firewall iprope lookup [src] [dst] [proto] [sport] [dport]
# Proto: 6=TCP, 17=UDP, 1=ICMP

# Test HTTP dari LAN ke internet
diagnose firewall iprope lookup 10.20.11.100 8.8.8.8 6 1024 80

# Test HTTPS dari MarineCrewWifi ke internet
diagnose firewall iprope lookup 10.30.11.10 8.8.8.8 6 1024 443

# Test dari DMZ
diagnose firewall iprope lookup 10.10.10.10 8.8.8.8 6 1024 443`,
   note:'Menampilkan policy ID yang akan digunakan untuk paket tersebut'},

  {cat:'diag', icon:'🔍', title:'CPU & Memory monitor', desc:'Pantau penggunaan resource sistem',
   code:`# Status performa sistem
get system performance status

# Monitor real-time (5 detik)
diagnose sys top 5

# CPU per-core
diagnose hardware sysinfo cpu

# Memory detail
diagnose hardware sysinfo mem`,
   note:'CPU ideal < 70%, Memory < 80%'},

  // ── USER MANAGEMENT ──
  {cat:'user', icon:'👥', title:'Lihat user yang sedang aktif', desc:'Tampilkan semua user yang terautentikasi di firewall',
   code:`# Semua user aktif
diagnose firewall auth list

# Filter per IP
diagnose firewall auth filter src 10.20.11.100
diagnose firewall auth list`,
   note:'Menampilkan username, IP, waktu login, policy yang diizinkan'},

  {cat:'user', icon:'👥', title:'Logout / clear user session', desc:'Force logout user tertentu',
   code:`# Clear auth session berdasarkan IP
diagnose firewall auth clear-by-ip 10.20.11.100

# Clear semua user aktif
diagnose firewall auth clear

# Clear user berdasarkan username
diagnose firewall auth clear-by-user marine001`,
   note:'Ganti IP/username sesuai user yang ingin di-logout'},

  {cat:'user', icon:'👥', title:'Tambah user local baru', desc:'Buat user baru marine di FortiGate',
   code:`config user local
    edit "marine082"
        set type password
        set passwd "Password@2025"
        set two-factor disable
    next
end`,
   note:'Ganti marine082 dan password sesuai kebutuhan'},

  {cat:'user', icon:'👥', title:'Reset password user', desc:'Ganti password user yang sudah ada',
   code:`config user local
    edit "marine001"
        set passwd "NewPassword@2025"
    next
end`,
   note:'Ganti marine001 dan password baru'},

  {cat:'user', icon:'👥', title:'Enable 2FA FortiToken untuk user', desc:'Aktifkan two-factor authentication per user',
   code:`# Cek token yang tersedia
diagnose fortitoken status

# Assign token ke user
config user local
    edit "marine001"
        set two-factor fortitoken-cloud
        set email-to "marine001@vessel.com"
    next
end

# Test kirim token
execute fortitoken-cloud provision marine001`,
   note:'Pastikan FortiToken Cloud sudah aktif dan email valid'},

  {cat:'user', icon:'👥', title:'Lihat semua user local', desc:'Tampilkan daftar semua user yang terdaftar',
   code:`# Semua user
show user local

# User tertentu
show user local marine001

# Total user count
get user local | grep -c "=="`,
   note:'Menampilkan username, tipe, status 2FA'},

  {cat:'user', icon:'👥', title:'Buat user group WiFi crew', desc:'Assign user ke group untuk policy WiFi',
   code:`# Lihat group yang ada
show user group

# Edit group marine-crew
config user group
    edit "marine-crew"
        set member "marine001" "marine002" "marine003"
    next
end`,
   note:'Ganti nama group dan member sesuai kebutuhan'},

  // ── SECURITY ──
  {cat:'sec', icon:'🔐', title:'Disable Telnet (RISK FIX)', desc:'Matikan akses Telnet yang tidak aman — WAJIB dilakukan',
   code:`config system global
    set admin-telnet disable
end

# Verifikasi
show system global | grep telnet`,
   note:'⚠️ SEGERA lakukan — Telnet tidak terenkripsi, rawan sniffing'},

  {cat:'sec', icon:'🔐', title:'Disable HTTP admin port 80 (RISK FIX)', desc:'Matikan akses admin via HTTP plaintext',
   code:`config system global
    set admin-port 0
    set admin-sport 3443
end

# Verifikasi — akses admin hanya via HTTPS port 3443
show system global | grep admin-port`,
   note:'⚠️ Setelah ini, akses admin hanya via https://192.168.1.99:3443'},

  {cat:'sec', icon:'🔐', title:'Cek admin login attempt', desc:'Lihat log percobaan login admin',
   code:`# Log event admin login
execute log filter category event
execute log filter field user admin
execute log display`,
   note:'Deteksi brute force atau akses tidak sah'},

  {cat:'sec', icon:'🔐', title:'Lihat firewall policy aktif', desc:'Tampilkan semua policy yang terkonfigurasi',
   code:`# Semua policy
show firewall policy

# Policy dengan hitungan trafik
get firewall policy

# Policy tertentu by ID
show firewall policy 1`,
   note:'Verifikasi policy sesuai kebutuhan keamanan'},

  {cat:'sec', icon:'🔐', title:'Cek IPS sensor status', desc:'Verifikasi IPS aktif dan signature update',
   code:`# Status IPS
diagnose ips signature status

# Cek update terakhir
diagnose autoupdate versions | grep -A3 "IPS"

# Force update signature
execute update-now`,
   note:'Update signature IPS secara berkala untuk proteksi optimal'},

  {cat:'sec', icon:'🔐', title:'Blocked IP list', desc:'Lihat IP yang sedang diblokir',
   code:`# Banned IP list
diagnose user banned-ip list

# Tambah banned IP manual
diagnose user banned-ip add 1.2.3.4 3600

# Hapus banned IP
diagnose user banned-ip delete 1.2.3.4`,
   note:'Ganti 3600 dengan durasi ban dalam detik'},

  // ── NETWORK ──
  {cat:'net', icon:'🌐', title:'Tabel routing lengkap', desc:'Lihat semua routing yang aktif',
   code:`# Routing table aktif
get router info routing-table all

# Routing detail per prefix
get router info routing-table details 0.0.0.0/0

# Static route config
show router static`,
   note:'Verifikasi default route dan routing antar VLAN'},

  {cat:'net', icon:'🌐', title:'Setup SD-WAN basic (VSAT + Starlink)', desc:'Konfigurasi SD-WAN untuk failover otomatis 3 WAN',
   code:`# Step 1: Enable SD-WAN
config system sdwan
    set status enable
    config members
        edit 1
            set interface "wan1"
            set gateway 0.0.0.0
        next
        edit 2
            set interface "wan2"
            set gateway 0.0.0.0
        next
        edit 3
            set interface "port2"
            set gateway 0.0.0.0
        next
    end
    config health-check
        edit "ping-check"
            set server "8.8.8.8"
            set members 1 2 3
        next
    end
    config service
        edit 1
            set name "default-route"
            set mode priority
            set dst "0.0.0.0/0"
            set priority-members 1 2 3
        next
    end
end`,
   note:'⚠️ Backup konfigurasi dulu sebelum enable SD-WAN. Ganti gateway sesuai ISP'},

  {cat:'net', icon:'🌐', title:'DNS troubleshoot', desc:'Diagnosa masalah resolusi DNS',
   code:`# Test DNS resolution
diagnose test application dnsproxy 6

# Cek DNS server yang dipakai
diagnose ip dnsproxy-server status

# Flush DNS cache
diagnose test application dnsproxy 1

# DNS lookup manual
execute nslookup google.com`,
   note:'DNS menggunakan FortiGuard (96.45.45.45) via port2'},

  {cat:'net', icon:'🌐', title:'ARP table', desc:'Lihat tabel ARP untuk troubleshoot L2',
   code:`# ARP table semua interface
get system arp

# ARP per interface
diagnose ip arp list

# Flush ARP cache
diagnose ip arp flush`,
   note:'Berguna untuk troubleshoot IP conflict atau gateway unreachable'},

  {cat:'net', icon:'🌐', title:'DHCP lease monitor', desc:'Lihat IP yang dibagikan DHCP server',
   code:`# Semua DHCP lease
diagnose firewall iprope lookup

# DHCP lease per VLAN
get system dhcp server

# Lease aktif
diagnose netlink interface list`,
   note:'Monitor alokasi IP di setiap segmen jaringan'},

  {cat:'net', icon:'🌐', title:'Bandwidth usage per interface', desc:'Monitor penggunaan bandwidth real-time',
   code:`# Traffic stat per interface
diagnose netlink interface list wan1
diagnose netlink interface list wan2
diagnose netlink interface list port2

# Reset counter
diagnose netlink interface clear wan1`,
   note:'Lihat RX/TX bytes dan error untuk setiap WAN link'},

  // ── SYSTEM ──
  {cat:'sys', icon:'⚙️', title:'System status lengkap', desc:'Informasi lengkap sistem dan uptime',
   code:`# Status sistem
get system status

# Uptime dan versi
get system performance status

# Hardware info
diagnose hardware sysinfo memory
diagnose hardware sysinfo cpu`,
   note:'Verifikasi firmware, serial number, lisensi, uptime'},

  {cat:'sys', icon:'⚙️', title:'Backup konfigurasi via CLI', desc:'Download backup konfigurasi FortiGate',
   code:`# Backup ke TFTP server
execute backup config tftp backup_$(date +%Y%m%d).conf 192.168.1.10

# Backup ke FTP
execute backup config ftp backup.conf 192.168.1.10 21 ftpuser ftppass

# Backup full (dengan private key)
execute backup full-config tftp backup_full.conf 192.168.1.10`,
   note:'Ganti IP TFTP/FTP sesuai server backup Anda. Lakukan sebelum setiap perubahan besar'},

  {cat:'sys', icon:'⚙️', title:'Update firmware / FortiGuard', desc:'Cek dan update signature FortiGuard',
   code:`# Cek status update
diagnose autoupdate versions

# Update semua service sekarang
execute update-now

# Cek lisensi
diagnose license list`,
   note:'Jadwalkan update di luar jam kerja untuk menghindari gangguan'},

  {cat:'sys', icon:'⚙️', title:'NTP sync manual', desc:'Sinkronisasi waktu dengan NTP server',
   code:`# Cek status NTP
diagnose sys ntp status

# Force sync NTP
execute date

# Konfigurasi NTP
show system ntp`,
   note:'Waktu yang akurat penting untuk log dan sertifikat SSL'},

  {cat:'sys', icon:'⚙️', title:'Reboot / shutdown', desc:'Restart atau matikan FortiGate dengan aman',
   code:`# Reboot FortiGate
execute reboot

# Shutdown FortiGate
execute shutdown

# Konfirmasi: ketik 'y' saat diminta`,
   note:'⚠️ Pastikan ada downtime window. Notifikasi user sebelum reboot'},

  {cat:'sys', icon:'⚙️', title:'Log & event viewer', desc:'Lihat log sistem dan event penting',
   code:`# Log trafik terbaru
execute log filter category traffic
execute log display

# Log event sistem
execute log filter category event
execute log display

# Log IPS/threat
execute log filter category attack
execute log display

# Reset filter
execute log filter reset`,
   note:'Monitor log secara berkala untuk deteksi anomali'},
];

let activeFilter = 'all';

function renderScripts(filter='all', search=''){
  const container = document.getElementById('scripts-container');
  if(!container) return;
  const filtered = SCRIPTS.filter(s => {
    const matchCat = filter==='all' || s.cat===filter;
    const matchSearch = !search || 
      s.title.toLowerCase().includes(search) || 
      s.desc.toLowerCase().includes(search) ||
      s.code.toLowerCase().includes(search);
    return matchCat && matchSearch;
  });

  // Group by category
  const cats = {
    diag:{icon:'🔍',label:'Diagnostik & Monitoring',items:[]},
    user:{icon:'👥',label:'User Management',items:[]},
    sec:{icon:'🔐',label:'Security',items:[]},
    net:{icon:'🌐',label:'Network & Routing',items:[]},
    sys:{icon:'⚙️',label:'System & Maintenance',items:[]},
  };
  filtered.forEach(s => cats[s.cat].items.push(s));

  let html = '';
  Object.entries(cats).forEach(([key,cat]) => {
    if(!cat.items.length) return;
    html += `<div class="script-cat" data-cat="${key}">
      <div class="script-cat-title">${cat.icon} ${cat.label} <span style="color:var(--accent);font-weight:400">(${cat.items.length})</span></div>`;
    cat.items.forEach((s,idx) => {
      const id = `sc-${key}-${idx}`;
      html += `<div class="script-card" data-cat="${s.cat}" data-title="${s.title.toLowerCase()}" data-desc="${s.desc.toLowerCase()}">
        <div class="script-header" onclick="toggleScript('${id}')">
          <div class="script-header-left">
            <span style="font-size:16px">${s.icon}</span>
            <div>
              <div class="script-title">${s.title}</div>
              <div class="script-desc">${s.desc}</div>
            </div>
          </div>
          <div style="display:flex;align-items:center;gap:6px">
            <span class="script-tag tag-${s.cat}">${{diag:'DIAG',user:'USER',sec:'SEC',net:'NET',sys:'SYS'}[s.cat]}</span>
            <span style="font-size:14px;color:var(--text3)" id="arr-${id}">›</span>
          </div>
        </div>
        <div class="script-body" id="${id}">
          <div class="script-code">${escHtml(s.code)}</div>
          ${s.note ? `<div style="font-size:12px;color:var(--text3);margin-top:8px;padding:6px 10px;background:var(--bg3);border-radius:5px">💡 ${s.note}</div>` : ''}
          <div class="script-actions">
            <button class="script-btn script-btn-copy" onclick="copyScript(this,'${escAttr(s.code)}')">📋 Copy script</button>
            <button class="script-btn script-btn-ai" onclick="askAI('${escAttr(s.title)}','${escAttr(s.desc)}')">🤖 Tanya AI</button>
          </div>
        </div>
      </div>`;
    });
    html += '</div>';
  });

  if(!html) html = '<div style="text-align:center;padding:32px;color:var(--text3)">Tidak ada script yang cocok dengan pencarian.</div>';
  container.innerHTML = html;
}

function escHtml(str){ return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }
function escAttr(str){ return str.replace(/'/g,'&#39;').replace(/"/g,'&quot;').replace(/\n/g,'\\n'); }

function toggleScript(id){
  const body = document.getElementById(id);
  const arr = document.getElementById('arr-'+id);
  if(body.classList.contains('open')){
    body.classList.remove('open');
    arr.textContent='›';
    arr.style.transform='';
  } else {
    body.classList.add('open');
    arr.textContent='›';
    arr.style.transform='rotate(90deg)';
  }
}

function filterCat(cat, btn){
  activeFilter = cat;
  document.querySelectorAll('.filter-btn').forEach(b=>b.classList.remove('active'));
  btn.classList.add('active');
  renderScripts(cat, document.getElementById('script-search')?.value?.toLowerCase()||'');
}

function filterScripts(){
  const search = document.getElementById('script-search').value.toLowerCase();
  renderScripts(activeFilter, search);
}

function copyScript(btn, code){
  const decoded = code.replace(/\\n/g,'\n').replace(/&#39;/g,"'").replace(/&quot;/g,'"');
  navigator.clipboard.writeText(decoded).then(()=>{
    btn.textContent='✅ Tersalin!';
    btn.style.background='#022C22';btn.style.color='#34D399';
    const toast = document.getElementById('copy-toast');
    toast.style.display='block';
    setTimeout(()=>{
      btn.textContent='📋 Copy script';
      btn.style.background='';btn.style.color='';
      toast.style.display='none';
    }, 2000);
  });
}

function askAI(title, desc){
  // Pindah ke panel AI dan isi pertanyaan
  document.querySelectorAll('.panel').forEach(p=>p.classList.remove('active'));
  document.querySelectorAll('.ntab').forEach(t=>t.classList.remove('active'));
  document.getElementById('p-ai').classList.add('active');
  document.querySelectorAll('.ntab').forEach(t=>{
    if(t.textContent.includes('AI')) t.classList.add('active');
  });
  const q = `Jelaskan cara menggunakan script "${title}" (${desc}) pada FortiGate mermaid-mrl ini. Berikan contoh output yang diharapkan dan cara interpretasi hasilnya.`;
  document.getElementById('ai-q').value = q;
  document.getElementById('ai-q').scrollIntoView({behavior:'smooth'});
  sendAI();
}

// Render saat tab Scripts dibuka
const origShowPanel = showPanel;
function showPanel(id, el){
  origShowPanel(id, el);
  if(id === 'scripts') renderScripts(activeFilter);
}
</script>
</body>
</html>"""

# ── Apply all changes ─────────────────────────────────────────
changes = 0

if old_tabs in content:
    content = content.replace(old_tabs, new_tabs)
    changes += 1
    print("✅ Tab button added")
else:
    print("❌ Tab button NOT FOUND")

if old_css in content:
    content = content.replace(old_css, new_css)
    changes += 1
    print("✅ CSS added")
else:
    print("❌ CSS NOT FOUND")

if old_ai_panel_end in content:
    content = content.replace(old_ai_panel_end, new_scripts_before_ai)
    changes += 1
    print("✅ Script panel HTML added")
else:
    print("❌ AI panel marker NOT FOUND")

if old_content_end in content:
    content = content.replace(old_content_end, new_scripts_panel)
    changes += 1
    print("✅ Toast notification added")
else:
    print("❌ Content end NOT FOUND")

if old_script_end in content:
    content = content.replace(old_script_end, new_script_js)
    changes += 1
    print("✅ JavaScript added")
else:
    print("❌ Script end NOT FOUND")

if changes == 5:
    with open('index.php', 'w') as f:
        f.write(content)
    print(f"\n🎉 SUCCESS — {changes}/5 changes applied, index.php saved!")
else:
    print(f"\n⚠️  Only {changes}/5 changes applied — check errors above")
    # Save anyway if at least some changes
    if changes > 0:
        with open('index.php', 'w') as f:
            f.write(content)
        print("Partial save done.")
