// catknows Repair Tool — Client-side logic

let uploadedFile = null;       // File object from file picker / drag-drop
let selectedZipPath = null;    // Path from scanned downloads

// ========== Initialization ==========

document.addEventListener('DOMContentLoaded', () => {
  loadStatus();
  checkVersion();
  setupDragDrop();
});

async function loadStatus() {
  try {
    const resp = await fetch('/api/status');
    const data = await resp.json();

    document.getElementById('repair-version').textContent = 'v' + data.repairVersion;
    document.getElementById('install-dir').textContent = data.installDir;
    document.getElementById('install-dir').title = data.installDir;

    // Update status indicators
    const binaryEl = document.getElementById('status-binary');
    if (data.catknowsFound) {
      binaryEl.textContent = 'Found';
      binaryEl.style.color = 'var(--success)';
    } else {
      binaryEl.textContent = 'Not found';
      binaryEl.style.color = 'var(--danger)';
    }

    const dbEl = document.getElementById('status-db');
    if (data.dbExists) {
      dbEl.textContent = data.dbSize + ' (' + data.dbSizeHuman + ')';
      dbEl.style.color = 'var(--success)';
    } else {
      dbEl.textContent = 'Not found';
      dbEl.style.color = 'var(--warning)';
    }

    const versionEl = document.getElementById('status-version');
    versionEl.textContent = data.version || 'Unknown';

    // Load system info for diagnostics tab
    loadSystemInfo(data);
  } catch (e) {
    console.error('Failed to load status:', e);
  }
}

function loadSystemInfo(data) {
  const container = document.getElementById('system-info');
  const items = [
    ['Platform', data.platform],
    ['Install directory', data.installDir],
    ['catknows binary', data.catknowsFound ? 'Found' : 'Not found'],
    ['Database', data.dbExists ? data.dbSizeHuman : 'Not found'],
    ['catknows version', data.version || 'Unknown'],
    ['Repair Tool version', data.repairVersion],
    ['OS', data.os || navigator.platform],
  ];

  container.innerHTML = items.map(([label, value]) =>
    `<div class="status-item"><span class="label">${label}:</span><span class="value">${value}</span></div>`
  ).join('');
}

async function checkVersion() {
  try {
    const resp = await fetch('/api/version-check');
    const data = await resp.json();
    if (data.updateAvailable) {
      const banner = document.getElementById('version-banner');
      document.getElementById('version-banner-text').textContent =
        `A newer Repair Tool (v${data.latestVersion}) is available.`;
      document.getElementById('version-banner-link').href = data.downloadUrl;
      banner.classList.remove('hidden');
    }
  } catch (e) {
    // Silently ignore — offline or version check not configured
  }
}

// ========== Tab switching ==========

function switchTab(tabName) {
  document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
  document.querySelectorAll('.tab-content').forEach(t => t.classList.remove('active'));
  document.querySelector(`.tab[data-tab="${tabName}"]`).classList.add('active');
  document.getElementById('tab-' + tabName).classList.add('active');

  // Load tab-specific data
  if (tabName === 'backup') loadBackups();
}

// ========== Update flow ==========

function updateStepAccess() {
  const checked = document.getElementById('catknows-closed-check').checked;
  document.getElementById('backup-before-update-btn').disabled = !checked;
  updateApplyButton();
}

function skipBackup() {
  document.getElementById('step-backup').style.opacity = '0.5';
  document.getElementById('backup-before-update-btn').disabled = true;
  updateApplyButton();
}

function updateApplyButton() {
  const closed = document.getElementById('catknows-closed-check').checked;
  const hasFile = uploadedFile !== null || selectedZipPath !== null;
  document.getElementById('apply-update-btn').disabled = !(closed && hasFile);
}

// ========== Drag & Drop ==========

function setupDragDrop() {
  const dropZone = document.getElementById('drop-zone');
  if (!dropZone) return;

  ['dragenter', 'dragover'].forEach(evt => {
    dropZone.addEventListener(evt, e => {
      e.preventDefault();
      dropZone.classList.add('dragover');
    });
  });

  ['dragleave', 'drop'].forEach(evt => {
    dropZone.addEventListener(evt, e => {
      e.preventDefault();
      dropZone.classList.remove('dragover');
    });
  });

  dropZone.addEventListener('drop', e => {
    const files = e.dataTransfer.files;
    if (files.length > 0) {
      selectUploadedFile(files[0]);
    }
  });
}

function handleFileSelect(event) {
  const file = event.target.files[0];
  if (file) selectUploadedFile(file);
}

function selectUploadedFile(file) {
  if (!file.name.toLowerCase().endsWith('.zip')) {
    alert('Please select a ZIP file.');
    return;
  }
  uploadedFile = file;
  selectedZipPath = null;
  showSelectedFile(file.name, formatSize(file.size));
}

function showSelectedFile(name, size) {
  document.getElementById('selected-file-name').textContent = name;
  document.getElementById('selected-file-size').textContent = '(' + size + ')';
  document.getElementById('selected-file').classList.remove('hidden');
  updateApplyButton();
}

function clearSelection() {
  uploadedFile = null;
  selectedZipPath = null;
  document.getElementById('selected-file').classList.add('hidden');
  document.getElementById('file-input').value = '';
  updateApplyButton();
}

// ========== Scan Downloads ==========

async function scanDownloads() {
  const btn = document.getElementById('scan-downloads-btn');
  btn.disabled = true;
  btn.textContent = 'Scanning...';

  try {
    const resp = await fetch('/api/update/scan-downloads');
    const data = await resp.json();
    const list = document.getElementById('downloads-list');

    if (data.files && data.files.length > 0) {
      list.innerHTML = data.files.map(f =>
        `<div class="download-item" onclick="selectDownloadFile('${escapeAttr(f.path)}', '${escapeAttr(f.name)}', '${f.size}')">
          <div class="file-info">
            <span class="file-name">${escapeHtml(f.name)}</span>
            <span class="file-meta">${f.sizeHuman} &middot; ${f.modified}</span>
          </div>
        </div>`
      ).join('');
    } else {
      list.innerHTML = '<p class="muted">No catknows ZIP files found in Downloads.</p>';
    }
    list.classList.remove('hidden');
  } catch (e) {
    alert('Failed to scan downloads: ' + e.message);
  } finally {
    btn.disabled = false;
    btn.textContent = 'Scan Downloads';
  }
}

function selectDownloadFile(path, name, size) {
  selectedZipPath = path;
  uploadedFile = null;
  showSelectedFile(name, size);
}

// ========== Apply Update ==========

async function applyUpdate() {
  const btn = document.getElementById('apply-update-btn');
  const progress = document.getElementById('update-progress');
  const progressBar = document.getElementById('update-progress-bar');
  const progressText = document.getElementById('update-progress-text');
  const resultBox = document.getElementById('update-result');

  btn.disabled = true;
  progress.classList.remove('hidden');
  resultBox.classList.add('hidden');

  try {
    // Step 1: Upload file if from file picker
    if (uploadedFile) {
      progressText.textContent = 'Uploading ZIP file...';
      progressBar.style.width = '20%';

      const resp = await fetch('/api/update/upload', {
        method: 'POST',
        headers: { 'X-Filename': uploadedFile.name },
        body: uploadedFile,
      });

      if (!resp.ok) {
        const err = await resp.json();
        throw new Error(err.error || 'Upload failed');
      }
    }

    // Step 2: Apply update
    progressText.textContent = 'Extracting and applying update...';
    progressBar.style.width = '50%';

    const applyBody = selectedZipPath ? { zipPath: selectedZipPath } : {};
    const resp = await fetch('/api/update/apply', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(applyBody),
    });

    const data = await resp.json();
    progressBar.style.width = '100%';

    if (resp.ok && !data.error) {
      progressText.textContent = 'Update complete!';
      resultBox.className = 'result-box success';
      let msg = `Update applied successfully!\n\nFiles copied: ${data.filesCopied}`;
      if (data.filesSkipped > 0) msg += `\nFiles skipped (protected): ${data.filesSkipped}`;
      if (data.filesFailed > 0) msg += `\nFiles failed: ${data.filesFailed}`;
      msg += '\n\nYou can now start catknows.';
      resultBox.textContent = msg;
    } else {
      progressText.textContent = 'Update failed.';
      resultBox.className = 'result-box error';
      resultBox.textContent = data.error || 'Unknown error during update.';
    }
    resultBox.classList.remove('hidden');
  } catch (e) {
    progressText.textContent = 'Error.';
    resultBox.className = 'result-box error';
    resultBox.textContent = 'Error: ' + e.message;
    resultBox.classList.remove('hidden');
  }
}

// ========== Backup ==========

async function createBackupBeforeUpdate() {
  const resultBox = document.getElementById('backup-before-result');
  await doCreateBackup('backup-before-update-btn', resultBox);
}

async function createBackup() {
  const resultBox = document.getElementById('backup-result');
  await doCreateBackup('create-backup-btn', resultBox);
}

async function doCreateBackup(btnId, resultBox) {
  const btn = document.getElementById(btnId);
  btn.disabled = true;
  btn.textContent = 'Creating backup...';
  resultBox.classList.add('hidden');

  try {
    const resp = await fetch('/api/backup', { method: 'POST' });
    const data = await resp.json();

    if (resp.ok && !data.error) {
      resultBox.className = 'result-box success';
      resultBox.textContent = `Backup created: ${data.path}\nFiles: ${data.fileCount}, Size: ${data.totalSizeHuman}`;
    } else {
      resultBox.className = 'result-box error';
      resultBox.textContent = data.error || 'Backup failed.';
    }
    resultBox.classList.remove('hidden');
  } catch (e) {
    resultBox.className = 'result-box error';
    resultBox.textContent = 'Error: ' + e.message;
    resultBox.classList.remove('hidden');
  } finally {
    btn.disabled = false;
    btn.textContent = 'Create Backup';
  }
}

async function loadBackups() {
  try {
    const resp = await fetch('/api/backups');
    const data = await resp.json();
    const container = document.getElementById('backups-list');

    if (data.backups && data.backups.length > 0) {
      container.innerHTML = data.backups.map(b =>
        `<div class="backup-item">
          <div>
            <span class="backup-name">${escapeHtml(b.name)}</span>
            <span class="backup-meta">${b.fileCount} files, ${b.totalSizeHuman}</span>
          </div>
        </div>`
      ).join('');
    } else {
      container.innerHTML = '<p class="muted">No backups found.</p>';
    }
  } catch (e) {
    document.getElementById('backups-list').innerHTML = '<p class="muted">Failed to load backups.</p>';
  }
}

// ========== Diagnostics ==========

async function runDbCheck() {
  const resultBox = document.getElementById('db-check-result');
  resultBox.classList.add('hidden');

  try {
    const resp = await fetch('/api/diagnostics/db-check');
    const data = await resp.json();

    if (data.result === 'ok') {
      resultBox.className = 'result-box success';
      resultBox.textContent = 'Database integrity check passed: ok';
    } else if (data.error) {
      resultBox.className = 'result-box error';
      resultBox.textContent = data.error;
    } else {
      resultBox.className = 'result-box error';
      resultBox.textContent = 'Integrity check result:\n' + data.result;
    }
    resultBox.classList.remove('hidden');
  } catch (e) {
    resultBox.className = 'result-box error';
    resultBox.textContent = 'Error: ' + e.message;
    resultBox.classList.remove('hidden');
  }
}

async function resetConfig() {
  if (!confirm('Are you sure you want to reset config.ini to defaults? Your current version will be preserved if possible.')) {
    return;
  }

  const resultBox = document.getElementById('config-reset-result');
  resultBox.classList.add('hidden');

  try {
    const resp = await fetch('/api/diagnostics/reset-config', { method: 'POST' });
    const data = await resp.json();

    if (resp.ok && !data.error) {
      resultBox.className = 'result-box success';
      resultBox.textContent = 'config.ini has been reset to defaults.' +
        (data.version ? '\nVersion preserved: ' + data.version : '');
    } else {
      resultBox.className = 'result-box error';
      resultBox.textContent = data.error || 'Reset failed.';
    }
    resultBox.classList.remove('hidden');
  } catch (e) {
    resultBox.className = 'result-box error';
    resultBox.textContent = 'Error: ' + e.message;
    resultBox.classList.remove('hidden');
  }
}

// ========== Logs ==========

async function collectLogs() {
  const btn = document.getElementById('collect-logs-btn');
  const resultBox = document.getElementById('logs-result');
  btn.disabled = true;
  btn.textContent = 'Collecting...';
  resultBox.classList.add('hidden');

  try {
    const resp = await fetch('/api/diagnostics/collect-logs', { method: 'POST' });
    const data = await resp.json();

    if (resp.ok && !data.error) {
      resultBox.className = 'result-box success';
      resultBox.innerHTML = `Logs collected: ${data.filename}<br>` +
        `<a href="/api/diagnostics/download-logs?file=${encodeURIComponent(data.filename)}" ` +
        `class="btn btn-primary btn-small" style="margin-top:8px;display:inline-block" download>Download ZIP</a>`;
    } else {
      resultBox.className = 'result-box error';
      resultBox.textContent = data.error || 'Failed to collect logs.';
    }
    resultBox.classList.remove('hidden');
  } catch (e) {
    resultBox.className = 'result-box error';
    resultBox.textContent = 'Error: ' + e.message;
    resultBox.classList.remove('hidden');
  } finally {
    btn.disabled = false;
    btn.textContent = 'Collect Logs';
  }
}

// ========== Install Dir ==========

async function changeInstallDir() {
  const newDir = prompt('Enter the path to the catknows installation directory:');
  if (!newDir) return;

  try {
    const resp = await fetch('/api/set-install-dir', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ path: newDir }),
    });
    const data = await resp.json();
    if (resp.ok && !data.error) {
      loadStatus();
    } else {
      alert(data.error || 'Failed to change directory.');
    }
  } catch (e) {
    alert('Error: ' + e.message);
  }
}

// ========== Shutdown ==========

async function shutdownRepairTool() {
  if (!confirm('Shut down the Repair Tool?')) return;
  try {
    await fetch('/api/shutdown', { method: 'POST' });
  } catch (e) {
    // Expected — server shuts down
  }
  document.body.innerHTML = '<div style="text-align:center;padding:80px;color:#a0a0b0;">' +
    '<h2>Repair Tool has been shut down.</h2><p>You can close this tab.</p></div>';
}

// ========== Helpers ==========

function formatSize(bytes) {
  if (bytes < 1024) return bytes + ' B';
  if (bytes < 1024 * 1024) return Math.round(bytes / 1024) + ' KB';
  if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
  return (bytes / (1024 * 1024 * 1024)).toFixed(1) + ' GB';
}

function escapeHtml(str) {
  const div = document.createElement('div');
  div.textContent = str;
  return div.innerHTML;
}

function escapeAttr(str) {
  return str.replace(/'/g, "\\'").replace(/\\/g, '\\\\');
}
