(function(){
  const apiUrl = 'dtc_module/api.php';

  let token = null;
  let table = null;
  let selected = new Set();
  let rowMeta = new Map();
  let syncRowButtonsFn = function(){};

  function $(id){ return document.getElementById(id); }

  function setStatus(text, ok=null){
    const el = $('matchStatus');
    if(!el) return;
    el.textContent = text;
    if(ok === true){
      el.style.borderColor = 'rgba(0,255,120,0.35)';
      el.style.boxShadow = '0 0 18px rgba(0,255,120,0.12)';
    } else if(ok === false){
      el.style.borderColor = 'rgba(255,42,42,0.45)';
      el.style.boxShadow = '0 0 18px rgba(255,42,42,0.12)';
    } else {
      el.style.borderColor = 'rgba(255,255,255,0.08)';
      el.style.boxShadow = 'none';
    }
  }

  
  let hexTimer = null;
  function startHexAnim(){
    const el = document.getElementById('hexAnim');
    const el2 = document.getElementById('hexAnimInDrop');
    const vis = document.getElementById('scanVisuals');
    if(vis) vis.style.display='block';
    if(!el) return;
    el.style.display = 'inline-block';
    let s = '00';
    hexTimer = setInterval(()=>{
      // random 8 bytes
      let out = '';
      for(let i=0;i<16;i++){
        out += Math.floor(Math.random()*16).toString(16).toUpperCase();
        if(i%2===1 && i<15) out += ' ';
      }
      el.textContent = out;
      if(el2) el2.textContent = out;
    }, 80);
  }
  function stopHexAnim(){
    const el = document.getElementById('hexAnim');
    const el2 = document.getElementById('hexAnimInDrop');
    const vis = document.getElementById('scanVisuals');
    if(hexTimer){ clearInterval(hexTimer); hexTimer=null; }
    if(el){ el.style.display='none'; el.textContent=''; }
    if(el2){ el2.textContent=''; }
    if(vis){ vis.style.display='none'; }
  }
function setAlign(msg){
    const el = $('alignMsg');
    if(el) el.textContent = msg || '';
  }

  function resetUI(){
    token = null;
    selected = new Set();
    renderSelected();
    setAlign('');
    setStatus('Binary bekleniyor', null);
    const tb = $('dtcTbody');
    if(tb){
      tb.innerHTML = `<tr><td colspan="8" style="text-align:center; padding:50px; color: rgba(255,255,255,0.35); font-weight:800;">Binary yükle → DTC listesi hazırlanacak</td></tr>`;
    }
    if(table){
      try{ table.destroy(); }catch(e){}
      table = null;
    }
  }

  function renderSelected(){
    const list = $('selectedList');
    const empty = $('selectedEmpty');
    if(!list) return;

    // remove previous items except empty msg
    Array.from(list.querySelectorAll('.sel-pill')).forEach(n=>n.remove());

    if(selected.size === 0){
      if(empty) empty.style.display = 'block';
      return;
    }
    if(empty) empty.style.display = 'none';

    selected.forEach(row=>{
      const pill = document.createElement('div');
      pill.className = 'sel-pill';
      pill.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 12px; margin:8px 0; border:1px solid rgba(255,255,255,0.08); border-radius:14px; background:rgba(255,255,255,0.03);';
      pill.innerHTML = (()=>{
        const meta = rowMeta.get(row) || {};
        const dtc = meta.dtc || ("ROW #"+row);
        const desc = meta.desc || "";
        const adet = meta.adet != null ? meta.adet : "";
        return `<div style="display:flex; flex-direction:column; gap:4px;">
                  <div style="font-weight:900; font-size:12px; color:#fff; letter-spacing:.3px;">${dtc} <span style="opacity:.55; font-weight:800;">×${adet}</span></div>
                  <div style="font-weight:700; font-size:11px; color:rgba(255,255,255,0.55); line-height:1.2;">${escapeHtml(desc).slice(0,120)}</div>
                </div>
                <button type="button" data-row="${row}" style="cursor:pointer; border:1px solid rgba(255,42,42,0.35); background:rgba(255,42,42,0.12); color:#fff; font-weight:900; padding:6px 10px; border-radius:10px;">X</button>`;
      })();
      const btn = pill.querySelector('button');
      if(btn){
        btn.addEventListener('click', (e)=>{
          const r = parseInt(e.currentTarget.getAttribute('data-row'),10);
          selected.delete(r);
          renderSelected();
          // refresh ON/OFF state
          try{ syncRowButtonsFn(); }catch(_e){}
        });
      }
      list.appendChild(pill);
    });
  }

  
  function buildTable(rows){
    const tb = $('dtcTbody');
    if(!tb) return;

    const safe = (s)=> String(s ?? '').replace(/[&<>"']/g, c=>({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
    const isObd2 = (code)=> /^[PCBU][0-9A-F]{4}$/i.test(String(code||'').trim());

    // counts
    let oem = 0, obd2 = 0;
    rows.forEach(r=>{
      const dtc = (r.DTC ?? r.kod ?? '').toString().trim();
      if(isObd2(dtc)) obd2++; else oem++;
    });
    const elO = document.getElementById('statOem'); if(elO) elO.textContent = String(oem);
    const elB = document.getElementById('statObd2'); if(elB) elB.textContent = String(obd2);

    tb.innerHTML = rows.map((r,i)=>{
      const row = parseInt(r.ROW ?? r.row ?? 0, 10);
      const dtc = safe(r.DTC ?? r.kod ?? '');
      const fmi = safe(r.FMI ?? '-');
      const desc = safe(r.DESC ?? r.acik ?? '');
      const hex = safe(r.HEX ?? r.hex ?? '');
      const adet = safe(r.COUNT ?? r.count ?? r.ADET ?? r.adet ?? 1);
      const tip = isObd2(dtc) ? 'OBD2' : 'OEM';
      // meta for selected list
      rowMeta.set(row, {dtc, desc, adet, tip});
      const seq = i; // STATUS = 0,1,2,3...
      return `<tr>
        <td style="text-align:center"><span class="chip ok">${seq}</span></td>
        <td style="font-weight:900; color:${tip==='OBD2'?'#14ff8f':'#ffd34a'};">${tip}</td>
        <td style="font-weight:900; letter-spacing:0.4px;">${dtc}</td>
        <td style="text-align:center; opacity:0.75; font-weight:800;">${fmi}</td>
        <td style="color: rgba(255,255,255,0.78); font-weight:700;">${desc}</td>
        <td style="font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-weight:900; opacity:0.8;">${hex}</td>
        <td style="text-align:center"><span class="badge">${adet}</span></td>
        <td style="text-align:right">
          <div class="onoff">
            <button type="button" class="btn-on" data-row="${row}">ON</button>
            <button type="button" class="btn-off" data-row="${row}">OFF</button>
          </div>
        </td>
      </tr>`;
    }).join('');

    // Wire ON/OFF
    document.querySelectorAll('button.btn-on').forEach(btn=>{
      btn.addEventListener('click', ()=>{
        const r = parseInt(btn.getAttribute('data-row'),10);
        selected.delete(r);
        renderSelected();
        syncRowButtons();
    syncRowButtonsFn = syncRowButtons;
      });
    });
    document.querySelectorAll('button.btn-off').forEach(btn=>{
      btn.addEventListener('click', ()=>{
        const r = parseInt(btn.getAttribute('data-row'),10);
        selected.add(r);
        renderSelected();
        syncRowButtons();
    syncRowButtonsFn = syncRowButtons;
      });
    });

    function syncRowButtons(){
      document.querySelectorAll('tr').forEach(tr=>{
        const off = tr.querySelector('.btn-off');
        const on  = tr.querySelector('.btn-on');
        if(!off || !on) return;
        const r = parseInt(off.getAttribute('data-row'),10);
        const sel = selected.has(r);
        on.classList.toggle('active', !sel);
        off.classList.toggle('active', sel);
      });
    }
    syncRowButtons();
    syncRowButtonsFn = syncRowButtons;

    // DataTables (50/page)
    if(window.jQuery && jQuery.fn && jQuery.fn.DataTable){
      const tableEl = tb.closest('table');
      if(tableEl){
        table = jQuery(tableEl).DataTable({
          pageLength: 50,
          lengthMenu: [50,100,200],
          order: [],
          destroy: true
        });

        const search = $('dtcSearch');
        if(search){
          search.addEventListener('input', ()=>{ table.search(search.value).draw(); const c=$('dtcSearchClear'); if(c) c.style.display = search.value ? 'inline-flex':'none'; });
        }
      }
    }
  }


  async function uploadBinary(file){
    resetUI();
    if(!file) return;

    setStatus('Binary taranıyor... DTC tablosu hazırlanıyor', null);
    startHexAnim();

    const fd = new FormData();
    fd.append('action','user_upload');
    fd.append('user_bin', file);

    const res = await fetch(apiUrl, { method:'POST', body: fd });
    const j = await res.json().catch(()=>null);
    if(!j || j.status !== 'ok'){
      stopHexAnim();
      setStatus((j && j.msg) ? j.msg : 'Upload başarısız', false);
      setAlign('');
      return;
    }

    stopHexAnim();

    token = j.token;
    setStatus((j.profile_name ? j.profile_name : 'ECU Profil Tespit Edildi'), true);
    const sb=document.getElementById('statBrand'); if(sb) sb.textContent = (j.brand || '-');
    const se=document.getElementById('statEcu'); if(se) se.textContent = (j.ecu_model || j.profile_name || '-');
    setAlign(j.align_msg || '');

    const rows = Array.isArray(j.data) ? j.data : [];
    if(rows.length === 0){
      buildTable([]);
      setStatus('DTC bulunamadı (tablo boş)', false);
      return;
    }
    buildTable(rows);
  }

  async function doPatch(){
    if(!token){
      setStatus('Önce binary yükle', false);
      return;
    }
    if(selected.size === 0){
      setStatus('En az 1 DTC seç', false);
      return;
    }
    setStatus('Patch hazırlanıyor...', null);

    const fd = new FormData();
    fd.append('action','user_patch');
    fd.append('token', token);
    fd.append('rows', Array.from(selected).join(','));

    const res = await fetch(apiUrl, { method:'POST', body: fd });
    const j = await res.json().catch(()=>null);
    if(!j || j.status !== 'ok'){
      setStatus((j && j.msg) ? j.msg : 'Patch başarısız', false);
      return;
    }
    setStatus(`Patch OK (${j.count || 0})`, true);
    if(j.url){
      window.location.href = j.url;
    }
  }

  function onReady(){
    resetUI();
    // Ctrl+A -> select all visible DTC rows (current page / filtered)
    document.addEventListener('keydown', (e)=>{
      if((e.ctrlKey || e.metaKey) && (e.key === 'a' || e.key === 'A')){
        // only when DTC table exists on page
        const tb = $('dtcTbody');
        if(!tb) return;
        e.preventDefault();
        let rows = [];
        if(table && window.jQuery){
          try{
            const nodes = table.rows({search:'applied', page:'current'}).nodes().toArray();
            rows = nodes;
          }catch(_e){}
        }
        if(!rows.length){
          rows = Array.from(tb.querySelectorAll('tr'));
        }
        rows.forEach(tr=>{
          const off = tr.querySelector('.btn-off');
          if(!off) return;
          const r = parseInt(off.getAttribute('data-row'),10);
          if(!Number.isNaN(r)) selected.add(r);
        });
        renderSelected();
        if(syncRowButtonsFn) syncRowButtonsFn();
      }
    });

    // Search clear button (UI)
    const s = $('dtcSearch');
    const sClr = $('dtcSearchClear');
    if(s && sClr){
      const upd = ()=>{ sClr.style.display = s.value ? 'inline-flex' : 'none'; };
      s.addEventListener('input', upd);
      upd();
      sClr.addEventListener('click', ()=>{ s.value=''; if(table) table.search('').draw(); else { /* noop */ } upd(); s.focus(); });
    }

    const patchBtn = $('patchBtn');
    if(patchBtn){
      patchBtn.addEventListener('click', doPatch);
    }

    // expose for inline onchange
    window.DTC_UI = {
      onFileChange: (input)=>{
        const f = (input && input.files && input.files[0]) ? input.files[0] : null;
        if(!f) return;
        uploadBinary(f).catch(err=>{
          console.error(err);
          setStatus('Upload hata', false);
        });
      }
    };
  }

  if(document.readyState === 'loading') document.addEventListener('DOMContentLoaded', onReady);
  else onReady();

})();