<?php /* payroll/fp_upload.php */ ?>
<style>
.upload-hero{background:linear-gradient(135deg,#0f2557,#1e40af);border-radius:12px;padding:20px 24px;color:#fff;margin-bottom:20px}
.drop-zone{border:2px dashed #bfdbfe;border-radius:12px;padding:40px;text-align:center;background:#eff6ff;cursor:pointer;transition:all .2s;position:relative}
.drop-zone:hover,.drop-zone.dragover{border-color:#3b82f6;background:#dbeafe;transform:scale(1.01)}
.drop-zone input[type=file]{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%;height:100%}
.format-card{border:1.5px solid #e2e8f0;border-radius:10px;padding:14px;cursor:pointer;transition:all .15s}
.format-card:hover,.format-card.selected{border-color:#3b82f6;background:#eff6ff}
.format-card.selected{border-width:2px}
.step-badge{width:28px;height:28px;border-radius:50%;background:#1d4ed8;color:#fff;display:inline-flex;align-items:center;justify-content:center;font-size:.75rem;font-weight:800;flex-shrink:0}
.preview-table th{position:sticky;top:0;background:#0f172a;color:#fff;font-size:.7rem;padding:6px 10px}
.preview-table td{font-size:.78rem;padding:4px 10px;border-bottom:1px solid #f1f5f9}
</style>

<div class="upload-hero">
  <div class="d-flex justify-content-between align-items-center flex-wrap gap-2">
    <div>
      <h5 class="fw-bold mb-1"><i class="bi bi-fingerprint me-2"></i>Fingerprint Machine Data Uploader</h5>
      <div style="opacity:.8;font-size:.82rem">Import from ZKTeco, eSSL, Suprema, Hikvision or any CSV/TXT device export</div>
    </div>
    <div class="d-flex gap-2">
      <a href="<?= APP_URL ?>/payroll" class="btn btn-light btn-sm fw-semibold" style="color:#1d4ed8">
        <i class="bi bi-arrow-left me-1"></i>Payroll
      </a>
      <a href="<?= APP_URL ?>/payroll/fp-upload/template" class="btn btn-outline-light btn-sm fw-semibold">
        <i class="bi bi-download me-1"></i>Download Template
      </a>
    </div>
  </div>
</div>

<?= flashMessages() ?>

<div class="row g-3">
  <div class="col-lg-7">

    <!-- Step 1 -->
    <div class="card mb-3">
      <div class="card-header fw-semibold small bg-transparent d-flex align-items-center gap-2">
        <span class="step-badge">1</span> Select Device / File Format
      </div>
      <div class="card-body">
        <div class="row g-2" id="formatCards">
          <?php $formats=[
            ['zkteco_csv',  'ZKTeco CSV',  'bi-fingerprint',  'text-primary', 'UserID,Date,Time,Status'],
            ['zkteco_txt',  'ZKTeco TXT',  'bi-file-text',    'text-info',    'Tab: ID DateTime C/In'],
            ['essl',        'eSSL / ESPL', 'bi-hdd',          'text-warning', 'EmpCode,Date,TimeIn,TimeOut'],
            ['suprema',     'Suprema',     'bi-shield-check', 'text-success', 'UserID,Name,DateTime,EventCode'],
            ['hikvision',   'Hikvision',   'bi-camera-video', 'text-danger',  'PIN,DateTime,Card,EventType'],
            ['generic_csv', 'Generic CSV', 'bi-filetype-csv', 'text-secondary','Custom column mapping'],
          ];?>
          <?php foreach($formats as[$val,$label,$icon,$cls,$sample]):?>
          <div class="col-md-4">
            <div class="format-card <?=$val==='zkteco_csv'?'selected':''?>"
                 onclick="selectFormat('<?=$val?>', this)">
              <div class="d-flex align-items-center gap-2 mb-1">
                <i class="bi <?=$icon?> <?=$cls?> fs-5"></i>
                <span class="fw-bold small"><?=$label?></span>
              </div>
              <div class="text-muted" style="font-size:.68rem"><?=$sample?></div>
            </div>
          </div>
          <?php endforeach;?>
        </div>
        <input type="hidden" id="selectedFormat" value="zkteco_csv">
      </div>
    </div>

    <!-- Step 2 -->
    <div class="card mb-3">
      <div class="card-header fw-semibold small bg-transparent d-flex align-items-center gap-2">
        <span class="step-badge">2</span> Upload Machine Export File
      </div>
      <div class="card-body">
        <div class="drop-zone mb-3" id="dropZone">
          <input type="file" id="fpFile" accept=".csv,.txt,.xls,.xlsx,.dat,.log" onchange="onFileSelect(this)">
          <i class="bi bi-cloud-upload fs-1 text-primary d-block mb-2"></i>
          <div class="fw-semibold">Drag & drop or click to browse</div>
          <div class="text-muted small mt-1">CSV · TXT · XLS · DAT · LOG &nbsp;|&nbsp; Max 10 MB</div>
          <div id="fileInfo" class="mt-2 fw-semibold text-success" style="display:none"></div>
        </div>
        <div id="columnMapping" style="display:none">
          <div class="fw-semibold small mb-2"><i class="bi bi-columns-gap me-1 text-warning"></i>Column Mapping</div>
          <div class="row g-2">
            <?php foreach([
              ['col_emp_id','Employee / User ID','required'],
              ['col_date','Date','required'],
              ['col_time','Time',''],
              ['col_datetime','DateTime (combined)',''],
              ['col_type','Punch Type (IN/OUT)',''],
            ] as[$f,$l,$r]):?>
            <div class="col-md-6">
              <label class="form-label small fw-semibold"><?=$l?> <?=$r?'<span class="text-danger">*</span>':''?></label>
              <div class="input-group input-group-sm">
                <span class="input-group-text text-muted" style="font-size:.7rem">Col</span>
                <input type="number" id="<?=$f?>" class="form-control" min="1" placeholder="#" style="max-width:65px">
                <input type="text" id="<?=$f?>_sample" class="form-control text-muted" placeholder="Sample" readonly style="font-size:.72rem">
              </div>
            </div>
            <?php endforeach;?>
          </div>
        </div>
      </div>
    </div>

    <!-- Step 3 -->
    <div class="card mb-3">
      <div class="card-header fw-semibold small bg-transparent d-flex align-items-center gap-2">
        <span class="step-badge">3</span> Import Settings
      </div>
      <div class="card-body">
        <div class="row g-2">
          <div class="col-md-4">
            <label class="form-label small fw-semibold">Date Format</label>
            <select id="dateFormat" class="form-select form-select-sm">
              <option value="Y-m-d">YYYY-MM-DD</option>
              <option value="d/m/Y">DD/MM/YYYY</option>
              <option value="m/d/Y">MM/DD/YYYY</option>
              <option value="d-m-Y">DD-MM-YYYY</option>
              <option value="Ymd">YYYYMMDD</option>
            </select>
          </div>
          <div class="col-md-4">
            <label class="form-label small fw-semibold">Delimiter</label>
            <select id="delimiter" class="form-select form-select-sm">
              <option value=",">Comma (,)</option>
              <option value="	">Tab (\t)</option>
              <option value=";">Semicolon (;)</option>
              <option value="|">Pipe (|)</option>
            </select>
          </div>
          <div class="col-md-4">
            <label class="form-label small fw-semibold">Skip Header Rows</label>
            <input type="number" id="skipRows" class="form-control form-control-sm" value="1" min="0" max="10">
          </div>
          <div class="col-md-4">
            <label class="form-label small fw-semibold">Punch IN value</label>
            <input type="text" id="punchInVal" class="form-control form-control-sm" value="0">
          </div>
          <div class="col-md-4">
            <label class="form-label small fw-semibold">Punch OUT value</label>
            <input type="text" id="punchOutVal" class="form-control form-control-sm" value="1">
          </div>
        </div>
      </div>
    </div>

    <div class="d-flex gap-2">
      <button onclick="previewData()" class="btn btn-outline-primary fw-semibold flex-fill" id="previewBtn" disabled>
        <i class="bi bi-eye me-1"></i>Preview Data
      </button>
      <button onclick="importData()" class="btn btn-success fw-bold px-5" id="importBtn" disabled>
        <i class="bi bi-upload me-1"></i>Import
      </button>
    </div>
  </div>

  <!-- Right -->
  <div class="col-lg-5">
    <div class="card mb-3">
      <div class="card-header fw-semibold small bg-transparent"><i class="bi bi-info-circle me-1 text-info"></i>Format Help</div>
      <div id="formatHelp"></div>
    </div>
    <div class="card" id="previewCard" style="display:none">
      <div class="card-header fw-semibold small bg-dark text-white d-flex justify-content-between">
        <span><i class="bi bi-table me-1"></i>Preview</span>
        <span class="badge bg-secondary" id="previewCount">0 rows</span>
      </div>
      <div style="max-height:380px;overflow:auto">
        <table class="preview-table table table-sm mb-0">
          <thead><tr id="previewHead"></tr></thead>
          <tbody id="previewBody"></tbody>
        </table>
      </div>
      <div class="card-footer py-2 small d-flex gap-3">
        <span class="text-success" id="statOk">✅ 0 valid</span>
        <span class="text-warning" id="statWarn">⚠ 0 warn</span>
        <span class="text-danger" id="statErr">❌ 0 errors</span>
      </div>
    </div>
  </div>
</div>

<!-- Progress Modal -->
<div class="modal fade" id="importModal" tabindex="-1" data-bs-backdrop="static">
  <div class="modal-dialog modal-dialog-centered" style="max-width:380px">
    <div class="modal-content">
      <div class="modal-body text-center p-4">
        <div class="spinner-border text-primary mb-3" style="width:3rem;height:3rem"></div>
        <h6 class="fw-bold">Importing Fingerprint Data…</h6>
        <div class="progress mt-3" style="height:8px">
          <div class="progress-bar progress-bar-striped progress-bar-animated bg-success"
               id="importProgress" style="width:0%"></div>
        </div>
        <div class="text-muted small mt-2" id="importMsg">Processing…</div>
      </div>
    </div>
  </div>
</div>

<script>
const APP_URL = '<?= APP_URL ?>';
const CSRF    = '<?= Auth::csrfToken() ?>';
let parsedRows=[], rawLines=[];

const fmtCfg = {
  zkteco_csv: {col_emp_id:1,col_date:2,col_time:3,col_type:4,punchIn:'0',punchOut:'1',delimiter:',',skip:1,
    help:`<div class="p-3"><div class="fw-bold small mb-2 text-primary">ZKTeco CSV</div><pre class="small bg-light p-2 rounded mb-1">UserID,Date,Time,Status,VerifyType
1,2026-06-15,08:00:35,0,1
1,2026-06-15,17:02:10,1,1</pre><div class="text-muted small">Status: 0=In · 1=Out · 4=OT In · 5=OT Out</div></div>`},
  zkteco_txt: {col_emp_id:1,col_datetime:2,col_type:3,punchIn:'C/In',punchOut:'C/Out',delimiter:'\t',skip:0,
    help:`<div class="p-3"><div class="fw-bold small mb-2 text-info">ZKTeco TXT</div><pre class="small bg-light p-2 rounded mb-1">1\t2026-06-15 08:00:35\tC/In
1\t2026-06-15 17:02:10\tC/Out</pre><div class="text-muted small">Tab-separated · DateTime combined</div></div>`},
  essl: {col_emp_id:1,col_date:2,col_time:3,punchIn:'in',punchOut:'out',delimiter:',',skip:1,
    help:`<div class="p-3"><div class="fw-bold small mb-2 text-warning">eSSL Format</div><pre class="small bg-light p-2 rounded mb-1">EmpCode,Date,TimeIn,TimeOut
EMP001,15/06/2026,08:00,17:00</pre></div>`},
  suprema: {col_emp_id:1,col_datetime:3,col_type:4,punchIn:'1',punchOut:'2',delimiter:',',skip:1,
    help:`<div class="p-3"><div class="fw-bold small mb-2 text-success">Suprema</div><pre class="small bg-light p-2 rounded mb-1">UserID,Name,DateTime,EventCode
FP001,Kamal,2026-06-15 08:00,1</pre><div class="text-muted small">Event: 1=Entry · 2=Exit</div></div>`},
  hikvision: {col_emp_id:1,col_datetime:2,col_type:5,punchIn:'Entry',punchOut:'Exit',delimiter:',',skip:1,
    help:`<div class="p-3"><div class="fw-bold small mb-2 text-danger">Hikvision</div><pre class="small bg-light p-2 rounded mb-1">PIN,DateTime,CardNo,Verified,EventType
FP001,2026-06-15 08:00,0000,FP,Entry</pre></div>`},
  generic_csv: {col_emp_id:1,col_date:2,col_time:3,col_type:4,punchIn:'IN',punchOut:'OUT',delimiter:',',skip:1,
    help:`<div class="p-3"><div class="fw-bold small mb-2 text-secondary">Generic CSV</div><pre class="small bg-light p-2 rounded mb-1">EmployeeID,Date,Time,Type
EMP001,2026-06-15,08:00,IN</pre><div class="text-muted small">Customize columns as needed</div></div>`},
};

function selectFormat(v,el){
  document.querySelectorAll('.format-card').forEach(c=>c.classList.remove('selected'));
  el.classList.add('selected');
  document.getElementById('selectedFormat').value=v;
  const c=fmtCfg[v]; if(!c) return;
  document.getElementById('formatHelp').innerHTML=c.help;
  ['col_emp_id','col_date','col_datetime','col_time','col_type'].forEach(f=>{const el=document.getElementById(f);if(el)el.value=c[f]||'';});
  if(c.punchIn)   document.getElementById('punchInVal').value=c.punchIn;
  if(c.punchOut)  document.getElementById('punchOutVal').value=c.punchOut;
  if(c.delimiter) document.getElementById('delimiter').value=c.delimiter;
  if(c.skip!==undefined) document.getElementById('skipRows').value=c.skip;
}
selectFormat('zkteco_csv',document.querySelector('.format-card'));

// Drag & drop
const dz=document.getElementById('dropZone');
dz.addEventListener('dragover',e=>{e.preventDefault();dz.classList.add('dragover')});
dz.addEventListener('dragleave',()=>dz.classList.remove('dragover'));
dz.addEventListener('drop',e=>{e.preventDefault();dz.classList.remove('dragover');
  const f=e.dataTransfer.files[0];
  if(f){document.getElementById('fpFile').files=e.dataTransfer.files;onFileSelect({files:[f]});}
});

function onFileSelect(input){
  const file=input.files[0]; if(!file) return;
  const info=document.getElementById('fileInfo');
  info.style.display='block';
  info.innerHTML=`<i class="bi bi-file-earmark-check me-1"></i>${file.name} (${(file.size/1024).toFixed(1)} KB)`;
  document.getElementById('columnMapping').style.display='block';
  document.getElementById('previewBtn').disabled=false;
  const r=new FileReader();
  r.onload=e=>{rawLines=e.target.result.split('\n').filter(l=>l.trim());updateSamples();};
  r.readAsText(file);
}

function updateSamples(){
  const delim=document.getElementById('delimiter').value||',';
  const skip=parseInt(document.getElementById('skipRows').value)||0;
  const sample=rawLines[skip]?rawLines[skip].split(delim):[];
  ['col_emp_id','col_date','col_datetime','col_time','col_type'].forEach(f=>{
    const cEl=document.getElementById(f),sEl=document.getElementById(f+'_sample');
    if(cEl&&sEl){const i=parseInt(cEl.value)-1;sEl.value=(i>=0&&sample[i])?sample[i].trim():'';}
  });
}

function previewData(){
  if(!rawLines.length) return;
  const delim=document.getElementById('delimiter').value||',';
  const skip=parseInt(document.getElementById('skipRows').value)||0;
  const pIn=document.getElementById('punchInVal').value;
  const pOut=document.getElementById('punchOutVal').value;
  const cEmp=parseInt(document.getElementById('col_emp_id').value)-1;
  const cDate=parseInt(document.getElementById('col_date').value||0)-1;
  const cDT=parseInt(document.getElementById('col_datetime').value||0)-1;
  const cTime=parseInt(document.getElementById('col_time').value||0)-1;
  const cType=parseInt(document.getElementById('col_type').value||0)-1;

  parsedRows=[]; let ok=0,warn=0,err=0;
  rawLines.slice(skip).forEach(line=>{
    const cols=line.split(delim).map(c=>c.trim().replace(/^["']|["']$/g,''));
    if(cols.length<2) return;
    const empId=cEmp>=0?cols[cEmp]:'';
    let date='',time='',type='in';
    if(cDT>=0&&cols[cDT]){const dt=cols[cDT].split(/[ T]/);date=dt[0]||'';time=dt[1]||'';}
    else{date=cDate>=0?cols[cDate]:'';time=cTime>=0?cols[cTime]:'';}
    if(cType>=0&&cols[cType]){
      const tv=cols[cType].toLowerCase();
      type=(tv===pIn.toLowerCase()||tv.includes('in')||tv==='0')?'in':'out';
    }
    const st=!empId||!date?'error':!time?'warning':'ok';
    if(st==='ok')ok++;else if(st==='warning')warn++;else err++;
    parsedRows.push({empId,date,time,type,status:st,raw:cols.slice(0,5).join(' | ')});
  });

  document.getElementById('previewHead').innerHTML='<th>Emp ID</th><th>Date</th><th>Time</th><th>Type</th><th>Status</th><th>Raw</th>';
  document.getElementById('previewBody').innerHTML=parsedRows.slice(0,50).map(r=>{
    const stH=r.status==='ok'?'<span class="badge bg-success" style="font-size:.6rem">✓</span>':
              r.status==='warning'?'<span class="badge bg-warning text-dark" style="font-size:.6rem">⚠</span>':
              '<span class="badge bg-danger" style="font-size:.6rem">✗</span>';
    const tH=r.type==='in'?'<span class="badge bg-success" style="font-size:.6rem">IN</span>':
             '<span class="badge bg-danger" style="font-size:.6rem">OUT</span>';
    return `<tr><td class="fw-semibold">${r.empId}</td><td>${r.date}</td><td>${r.time||'—'}</td><td>${tH}</td><td>${stH}</td><td class="text-muted" style="font-size:.65rem">${r.raw}</td></tr>`;
  }).join('');

  document.getElementById('previewCard').style.display='block';
  document.getElementById('previewCount').textContent=parsedRows.length+' rows';
  document.getElementById('statOk').textContent='✅ '+ok+' valid';
  document.getElementById('statWarn').textContent='⚠ '+warn+' warn';
  document.getElementById('statErr').textContent='❌ '+err+' errors';
  document.getElementById('importBtn').disabled=(ok+warn)===0;
}

async function importData(){
  if(!parsedRows.length) return;
  const modal=new bootstrap.Modal(document.getElementById('importModal'),{backdrop:'static'});
  modal.show();
  const valid=parsedRows.filter(r=>r.status!=='error');
  let imported=0,errors=0;
  const batch=50;
  for(let i=0;i<valid.length;i+=batch){
    const pct=Math.round((i/valid.length)*100);
    document.getElementById('importProgress').style.width=pct+'%';
    document.getElementById('importMsg').textContent=`Processing ${i+1}–${Math.min(i+batch,valid.length)} of ${valid.length}…`;
    const body=new URLSearchParams({csrf_token:CSRF,rows:JSON.stringify(valid.slice(i,i+batch))});
    try{const res=await fetch(APP_URL+'/payroll/fp-import',{method:'POST',body});
      const d=await res.json();imported+=d.imported||0;errors+=d.errors||0;}
    catch(e){errors++;}
  }
  document.getElementById('importProgress').style.width='100%';
  document.getElementById('importMsg').innerHTML=
    `<span class="text-success fw-bold">✅ ${imported} imported</span>`+
    (errors>0?` <span class="text-danger">❌ ${errors} errors</span>`:'');
  setTimeout(()=>{modal.hide();window.location.href=APP_URL+'/payroll';},2500);
}
</script>