/**
 * Popup UI Logic
 */

import './popup.css';
import { loadCredentials, saveCredentials, deleteCredentials, updateLastUse } from '../utils/storage';
import { uploadPDF, testConnection, BinectAPIError } from '../utils/binect-api';
import { fetchPDFBytes, DetectedPDF } from '../utils/pdf-detector';
import { addTrackingEntry } from '../tracking/tracker';
import { DocumentProxy, PDFStatus, PDFStatusMeta } from '../utils/pdf-queue';
import { computeContentFingerprint } from '../utils/hash';

// DOM Elements
const authView = document.getElementById('authView')!;
const mainView = document.getElementById('mainView')!;
const noPdfView = document.getElementById('noPdfView')!;
const pdfListView = document.getElementById('pdfListView')!;
const pdfList = document.getElementById('pdfList')!;
const pdfCount = document.getElementById('pdfCount')!;
const statusMessage = document.getElementById('statusMessage')!;

const loginForm = document.getElementById('loginForm') as HTMLFormElement;
const usernameInput = document.getElementById('username') as HTMLInputElement;
const passwordInput = document.getElementById('password') as HTMLInputElement;
const loginBtn = document.getElementById('loginBtn') as HTMLButtonElement;
const authError = document.getElementById('authError')!;

const logoutBtn = document.getElementById('logoutBtn')!;
const archiveToggleBtn = document.getElementById('archiveToggleBtn')!;
const archiveIcon = document.getElementById('archiveIcon')!;
const liveIcon = document.getElementById('liveIcon')!;
const helpBtn = document.getElementById('helpBtn')!;
const togglePasswordBtn = document.getElementById('togglePassword') as HTMLButtonElement;
const eyeIcon = document.getElementById('eyeIcon')!;
const eyeOffIcon = document.getElementById('eyeOffIcon')!;

// Issue Report Modal Elements
const issueModal = document.getElementById('issueModal')!;
const reportIssueBtn = document.getElementById('reportIssueBtn')!;
const closeModalBtn = document.getElementById('closeModalBtn')!;
const modalBackdrop = issueModal.querySelector('.modal-backdrop')!;
const issueTitleInput = document.getElementById('issueTitle') as HTMLInputElement;
const issueDescriptionInput = document.getElementById('issueDescription') as HTMLTextAreaElement;
const copyToClipboardBtn = document.getElementById('copyToClipboardBtn') as HTMLButtonElement;

// Context section content elements
const extensionInfoContent = document.getElementById('extensionInfoContent')!;
const browserInfoContent = document.getElementById('browserInfoContent')!;
const documentStatusContent = document.getElementById('documentStatusContent')!;
const recentErrorsContent = document.getElementById('recentErrorsContent')!;

// Error tracking for issue reports
const recentErrors: Array<{ timestamp: number; message: string; stack?: string }> = [];

// Pin Reminder Elements
const pinReminder = document.getElementById('pinReminder')!;
const dismissPinReminderBtn = document.getElementById('dismissPinReminder')!;

// State
let pdfQueue: DocumentProxy[] = [];
let currentCredentials: { username: string; password: string } | null = null;
let showingArchive = false; // false = live view, true = archive view

// Auto-refresh state
const REFRESH_INTERVALS = [10, 20, 30, 50, 80, 130, 210]; // seconds
let refreshTimeouts: ReturnType<typeof setTimeout>[] = [];
let refreshIndex = 0;

/**
 * Initialize popup
 */
async function init() {
  // Check and show first-run pin reminder
  await checkFirstRunReminder();

  // Check if user has credentials
  const credentials = await loadCredentials();

  if (credentials) {
    // Try to test connection
    try {
      const isConnected = await testConnection(credentials.username, credentials.password);

      if (isConnected) {
        currentCredentials = credentials;
        await updateLastUse();

        showMainView();
        await loadPDFQueue();
      } else {
        // Authentication failed, credentials may be invalid
        showAuthView();
      }
    } catch (error) {
      // Connection test failed
      console.error('[Popup] Connection test failed:', error);
      showAuthView();
    }
  } else {
    showAuthView();
  }

  // Setup event listeners
  setupEventListeners();
}

/**
 * Check if this is first run and show pin reminder
 */
async function checkFirstRunReminder() {
  const STORAGE_KEY = 'pinReminderDismissed';

  try {
    const result = await chrome.storage.local.get(STORAGE_KEY);
    if (!result[STORAGE_KEY]) {
      // First run - show the reminder
      pinReminder.style.display = 'block';
    }
  } catch (error) {
    console.error('[Popup] Error checking first run:', error);
  }
}

/**
 * Dismiss the pin reminder and remember the choice
 */
async function dismissPinReminder() {
  const STORAGE_KEY = 'pinReminderDismissed';

  pinReminder.style.display = 'none';

  try {
    await chrome.storage.local.set({ [STORAGE_KEY]: true });
  } catch (error) {
    console.error('[Popup] Error saving pin reminder state:', error);
  }
}

/**
 * Setup event listeners
 */
function setupEventListeners() {
  loginForm.addEventListener('submit', handleLogin);
  logoutBtn.addEventListener('click', handleLogout);
  archiveToggleBtn.addEventListener('click', handleToggleArchiveView);
  helpBtn.addEventListener('click', handleHelp);

  // Password toggle - ensure button exists and attach handler
  if (togglePasswordBtn) {
    togglePasswordBtn.addEventListener('click', (e) => {
      e.preventDefault();
      e.stopPropagation();
      handleTogglePassword();
    });
  }

  // Pin reminder dismiss button
  if (dismissPinReminderBtn) {
    dismissPinReminderBtn.addEventListener('click', dismissPinReminder);
  }
}

/**
 * Handle toggle between live and archive view
 */
async function handleToggleArchiveView() {
  showingArchive = !showingArchive;

  // Update toggle button appearance
  if (showingArchive) {
    archiveIcon.style.display = 'none';
    liveIcon.style.display = 'block';
    archiveToggleBtn.title = 'Show live documents';
    archiveToggleBtn.classList.add('active');
  } else {
    archiveIcon.style.display = 'block';
    liveIcon.style.display = 'none';
    archiveToggleBtn.title = 'Show archived';
    archiveToggleBtn.classList.remove('active');
  }

  // Reload the appropriate list
  await loadPDFQueue();
}

/**
 * Start auto-refresh sequence after user interaction
 */
function startAutoRefresh() {
  // Clear any existing refresh timeouts
  cancelAutoRefresh();
  refreshIndex = 0;
  scheduleNextRefresh();
}

/**
 * Schedule the next refresh in the sequence
 */
function scheduleNextRefresh() {
  if (refreshIndex >= REFRESH_INTERVALS.length) {
    return; // Sequence complete
  }

  const delay = REFRESH_INTERVALS[refreshIndex] * 1000;
  const timeout = setTimeout(async () => {
    console.log(`[Popup] Auto-refresh #${refreshIndex + 1} after ${REFRESH_INTERVALS[refreshIndex]}s`);
    await handleRefreshAll();
    refreshIndex++;
    scheduleNextRefresh();
  }, delay);

  refreshTimeouts.push(timeout);
}

/**
 * Cancel all pending auto-refresh timeouts
 */
function cancelAutoRefresh() {
  for (const timeout of refreshTimeouts) {
    clearTimeout(timeout);
  }
  refreshTimeouts = [];
}

/**
 * Extract just the filename from a full path
 */
function extractFilename(fullPath: string): string {
  // Handle both forward and back slashes
  const parts = fullPath.split(/[/\\]/);
  return parts[parts.length - 1] || fullPath;
}

/**
 * Handle password visibility toggle
 */
function handleTogglePassword() {
  const isPassword = passwordInput.type === 'password';

  if (isPassword) {
    // Show password
    passwordInput.type = 'text';
    eyeIcon.style.display = 'none';
    eyeOffIcon.style.display = 'block';
    togglePasswordBtn.setAttribute('aria-label', 'Hide password');
    togglePasswordBtn.setAttribute('title', 'Hide password');
  } else {
    // Hide password
    passwordInput.type = 'password';
    eyeIcon.style.display = 'block';
    eyeOffIcon.style.display = 'none';
    togglePasswordBtn.setAttribute('aria-label', 'Show password');
    togglePasswordBtn.setAttribute('title', 'Show password');
  }
}

/**
 * Handle login
 */
async function handleLogin(e: Event) {
  e.preventDefault();

  const username = usernameInput.value.trim();
  const password = passwordInput.value;

  if (!username || !password) {
    showError('Please enter username and password');
    return;
  }

  loginBtn.disabled = true;
  loginBtn.textContent = 'Signing in...';
  hideError();

  try {
    const isConnected = await testConnection(username, password);

    if (!isConnected) {
      showError('Invalid credentials. Please check your username and password.');
      return;
    }

    // Save credentials
    currentCredentials = { username, password };
    await saveCredentials({ username, password });

    showMainView();
    await loadPDFQueue();
  } catch (error) {
    if (error instanceof BinectAPIError) {
      showError(error.message);
    } else {
      showError('Authentication failed. Please try again.');
    }
  } finally {
    loginBtn.disabled = false;
    loginBtn.textContent = 'Sign In';
  }
}

/**
 * Load PDF queue from background and current tab
 */
async function loadPDFQueue() {
  console.log('[Popup] Loading PDF queue, showingArchive:', showingArchive);

  if (showingArchive) {
    // Get archived proxies only
    const response = await chrome.runtime.sendMessage({ action: 'getArchivedProxies' });
    pdfQueue = response?.entries || [];
    console.log('[Popup] Got', pdfQueue.length, 'archived entries');
  } else {
    // Get live proxies
    let response = await chrome.runtime.sendMessage({ action: 'getLiveProxies' });
    pdfQueue = response?.entries || [];
    console.log('[Popup] Got', pdfQueue.length, 'live entries from background');

    // Sync with server to discover documents uploaded elsewhere or missing locally
    if (currentCredentials) {
      await syncWithServer();
    }

    // Auto-restore any archived documents that are in active states (in_basket, in_production)
    // These should never be archived as it confuses user expectations
    const archivedResponse = await chrome.runtime.sendMessage({ action: 'getArchivedProxies' });
    const archivedEntries: DocumentProxy[] = archivedResponse?.entries || [];
    for (const entry of archivedEntries) {
      if (entry.binectStatus === 'in_basket' || entry.binectStatus === 'in_production') {
        console.log('[Popup] Auto-restoring active document from archive:', entry.filename);
        await chrome.runtime.sendMessage({ action: 'restoreProxy', id: entry.id });
      }
    }

    // Reload live proxies after potential restorations and server sync
    response = await chrome.runtime.sendMessage({ action: 'getLiveProxies' });
    pdfQueue = response?.entries || [];
    console.log('[Popup] After auto-restore and sync, got', pdfQueue.length, 'live entries');

    // Check current tab for PDF and add to persistent queue via background
    const currentTabPDF = await checkCurrentTabForPDF();
    if (currentTabPDF) {
      // Add via background service (will check for duplicates)
      const addResult = await chrome.runtime.sendMessage({
        action: 'addPDF',
        pdf: currentTabPDF
      });
      if (addResult?.entry) {
        console.log('[Popup] Added current tab PDF to persistent queue:', currentTabPDF.filename);
      }
    }

    // Fallback: check recent downloads if queue is still empty
    if (pdfQueue.length === 0) {
      console.log('[Popup] Queue empty, checking recent downloads...');
      const recentPDFs = await checkRecentDownloads();
      for (const pdf of recentPDFs) {
        // Add each PDF via background service (will check for duplicates)
        await chrome.runtime.sendMessage({
          action: 'addPDF',
          pdf
        });
      }
    }

    // Reload live queue after potential additions
    response = await chrome.runtime.sendMessage({ action: 'getLiveProxies' });
    pdfQueue = response?.entries || [];
    console.log('[Popup] Final live queue count:', pdfQueue.length);
  }

  // Render the list
  renderPDFList();
}

/**
 * Sync local proxies with server documents
 * Creates local proxies for documents that exist on server but not locally
 */
async function syncWithServer() {
  if (!currentCredentials) {
    return;
  }

  try {
    // Get list of documents from server
    const result = await chrome.runtime.sendMessage({
      action: 'listServerDocuments',
      username: currentCredentials.username,
      password: currentCredentials.password
    });

    if (!result.success || !result.documents) {
      console.warn('[Popup] Failed to list server documents:', result.error);
      return;
    }

    const serverDocs = result.documents as Array<{
      id: number;
      filename: string;
      status: number;
      statusText: string;
      price?: number;
      recipientAddress?: string;
      errorDetails?: string;
    }>;

    console.log('[Popup] Syncing', serverDocs.length, 'server documents');

    // Sync each server document to local proxy
    for (const doc of serverDocs) {
      await chrome.runtime.sendMessage({
        action: 'syncFromServer',
        binectDocumentId: doc.id,
        filename: doc.filename,
        binectStatusCode: doc.status,
        binectStatusText: doc.statusText,
        price: doc.price,
        recipientAddress: doc.recipientAddress,
        errorDetails: doc.errorDetails
      });
    }
  } catch (error) {
    console.error('[Popup] Server sync error:', error);
  }
}

/**
 * Check recent downloads for PDFs (fallback mechanism)
 */
async function checkRecentDownloads(): Promise<DetectedPDF[]> {
  return new Promise((resolve) => {
    chrome.downloads.search(
      {
        limit: 20,
        orderBy: ['-startTime']
      },
      (items) => {
        console.log('[Popup] Checked recent downloads:', items.length, 'items');

        const pdfs: DetectedPDF[] = [];

        for (const item of items) {
          if (
            item.state === 'complete' &&
            (item.filename.toLowerCase().endsWith('.pdf') || item.mime === 'application/pdf')
          ) {
            let domain = 'unknown';
            try {
              const urlObj = new URL(item.url);
              domain = urlObj.hostname;
            } catch (e) {
              // Keep default
            }

            pdfs.push({
              id: `download-${item.id}`,
              filename: item.filename.split('/').pop() || item.filename,
              url: item.url,
              size: item.fileSize,
              timestamp: new Date(item.startTime).getTime(),
              sourceDomain: domain
            });
          }
        }

        console.log('[Popup] Found', pdfs.length, 'PDF downloads');
        resolve(pdfs);
      }
    );
  });
}

/**
 * Render the PDF list with grouped sections
 */
function renderPDFList() {
  if (pdfQueue.length === 0) {
    showNoPDF();
    return;
  }

  noPdfView.style.display = 'none';
  pdfListView.style.display = 'block';

  let html = '';

  if (showingArchive) {
    // Archive view - show all archived documents in a flat list
    pdfCount.textContent = `${pdfQueue.length} archived document${pdfQueue.length !== 1 ? 's' : ''}`;

    html = `<div class="pdf-section">
      <div class="pdf-section-header">Archived Documents</div>
      ${pdfQueue.map(pdf => renderPDFItem(pdf, 'archived')).join('')}
    </div>`;
  } else {
    // Live view - group by Binect status
    // Separate truly local pending uploads from server documents with errors
    const pendingUpload = pdfQueue.filter(p =>
      (p.binectStatus === 'pending' || p.binectStatus === 'uploading') ||
      (p.binectStatus === 'failed' && !p.binectDocumentId) // Local failed uploads
    );
    const erroneous = pdfQueue.filter(p =>
      p.binectStatus === 'failed' && p.binectDocumentId // Server documents with errors
    );
    const inBasket = pdfQueue.filter(p => p.binectStatus === 'in_basket' || p.binectStatus === 'ordering');
    const inProduction = pdfQueue.filter(p => p.binectStatus === 'in_production');
    const completed = pdfQueue.filter(p => p.binectStatus === 'sent' || p.binectStatus === 'canceled');

    // Count actionable items
    const actionableCount = pendingUpload.length + erroneous.length + inBasket.length;

    // Update count
    if (actionableCount > 0) {
      pdfCount.textContent = `${actionableCount} PDF${actionableCount > 1 ? 's' : ''} need attention`;
    } else if (inProduction.length > 0) {
      pdfCount.textContent = `${inProduction.length} in production`;
    } else if (completed.length > 0) {
      pdfCount.textContent = `${completed.length} completed`;
    } else {
      pdfCount.textContent = 'No documents';
    }

    if (pendingUpload.length > 0) {
      html += `<div class="pdf-section">
        <div class="pdf-section-header">Ready to Upload</div>
        ${pendingUpload.map(pdf => renderPDFItem(pdf, 'pending')).join('')}
      </div>`;
    }

    if (erroneous.length > 0) {
      html += `<div class="pdf-section">
        <div class="pdf-section-header">Has Errors</div>
        ${erroneous.map(pdf => renderPDFItem(pdf, 'erroneous')).join('')}
      </div>`;
    }

    if (inBasket.length > 0) {
      html += `<div class="pdf-section">
        <div class="pdf-section-header">In Basket</div>
        ${inBasket.map(pdf => renderPDFItem(pdf, 'basket')).join('')}
      </div>`;
    }

    if (inProduction.length > 0) {
      html += `<div class="pdf-section">
        <div class="pdf-section-header">In Production</div>
        ${inProduction.map(pdf => renderPDFItem(pdf, 'production')).join('')}
      </div>`;
    }

    if (completed.length > 0) {
      // Show only last 5 completed items in live view
      const recentCompleted = completed.slice(0, 5);
      html += `<div class="pdf-section pdf-section-completed">
        <div class="pdf-section-header">Recently Completed</div>
        ${recentCompleted.map(pdf => renderPDFItem(pdf, 'completed')).join('')}
      </div>`;
    }
  }

  pdfList.innerHTML = html;

  // Add event listeners
  setupPDFListEventListeners();
  hideStatus();
}

/**
 * Render a single PDF item
 */
function renderPDFItem(pdf: DocumentProxy, section: 'pending' | 'erroneous' | 'basket' | 'production' | 'completed' | 'archived'): string {
  const statusClass = getStatusClass(pdf.binectStatus);
  const statusText = getStatusText(pdf);
  const priceText = pdf.price ? `${(pdf.price / 100).toFixed(2)} €` : '';
  const displayFilename = extractFilename(pdf.filename);
  const isLocalOnly = !pdf.binectDocumentId;

  let actionsHtml = '';

  // Check if document can be deleted from server (erroneous or canceled)
  const canDeleteFromServer = pdf.binectDocumentId && (pdf.binectStatusCode === 7 || pdf.binectStatusCode === 6);

  switch (section) {
    case 'pending':
      actionsHtml = `
        <button class="btn-send-item" data-id="${escapeHtml(pdf.id)}" ${pdf.binectStatus === 'uploading' ? 'disabled' : ''}>
          ${pdf.binectStatus === 'uploading' ? 'Uploading...' : (pdf.binectStatus === 'failed' ? 'Retry' : 'Upload')}
        </button>
        <button class="btn-archive" data-id="${escapeHtml(pdf.id)}">Archive</button>
      `;
      break;
    case 'erroneous':
      // Server documents with errors - can only delete from server
      actionsHtml = `
        <button class="btn-delete-server" data-id="${escapeHtml(pdf.id)}">Delete from server</button>
      `;
      break;
    case 'basket':
      // No archive button for in_basket - these are active documents
      actionsHtml = `
        <button class="btn-order-item" data-id="${escapeHtml(pdf.id)}" ${pdf.binectStatus === 'ordering' ? 'disabled' : ''}>
          ${pdf.binectStatus === 'ordering' ? 'Sending...' : 'Send'}
        </button>
      `;
      break;
    case 'production':
      // No archive button for in_production - these are active documents
      actionsHtml = '';
      break;
    case 'completed':
      // For sent/canceled documents - offer delete from server if applicable
      if (canDeleteFromServer) {
        actionsHtml = `
          <button class="btn-delete-server" data-id="${escapeHtml(pdf.id)}">Delete from server</button>
        `;
      } else {
        actionsHtml = `
          <button class="btn-archive" data-id="${escapeHtml(pdf.id)}">Archive</button>
        `;
      }
      break;
    case 'archived':
      actionsHtml = `
        <button class="btn-restore" data-id="${escapeHtml(pdf.id)}">Restore</button>
        <button class="btn-dismiss btn-remove" data-id="${escapeHtml(pdf.id)}">Delete</button>
      `;
      break;
  }

  // Show detailed error info for erroneous documents
  const hasErrorDetails = pdf.binectStatus === 'failed' && pdf.errorMessage && pdf.binectStatusCode === 7;

  // Build metadata parts - only include what we have
  const metaParts: string[] = [];
  if (pdf.size > 0) {
    metaParts.push(formatFileSize(pdf.size));
  }
  if (pdf.sourceDomain && pdf.sourceDomain !== 'binect.de') {
    metaParts.push(escapeHtml(pdf.sourceDomain));
  } else if (pdf.binectDocumentId && pdf.sourceDomain === 'binect.de') {
    metaParts.push(`ID: ${pdf.binectDocumentId}`);
  }
  if (priceText) {
    metaParts.push(`<span class="pdf-price">${priceText}</span>`);
  }

  return `
    <div class="pdf-list-item ${statusClass}" data-id="${escapeHtml(pdf.id)}">
      <div class="pdf-item-icon">${getStatusIcon(pdf.binectStatus)}</div>
      <div class="pdf-item-details">
        <div class="pdf-item-filename" title="${escapeHtml(pdf.filename)}">
          ${escapeHtml(displayFilename)}
          ${isLocalOnly ? `<span class="tag-local" data-id="${escapeHtml(pdf.id)}" title="Click to check server">local</span>` : ''}
        </div>
        ${metaParts.length > 0 ? `<div class="pdf-item-meta">${metaParts.join(' · ')}</div>` : ''}
        ${pdf.recipientAddress ? `<div class="pdf-item-recipient">${escapeHtml(pdf.recipientAddress.split('\n')[0])}</div>` : ''}
        <div class="pdf-item-status ${statusClass}">${statusText}</div>
        ${hasErrorDetails ? `<div class="pdf-item-error">${escapeHtml(pdf.errorMessage!)}</div>` : ''}
      </div>
      <div class="pdf-item-actions">
        ${actionsHtml}
      </div>
    </div>
  `;
}

/**
 * Setup event listeners for PDF list items
 */
function setupPDFListEventListeners() {
  // Upload/Send buttons
  pdfList.querySelectorAll('.btn-send-item').forEach(btn => {
    btn.addEventListener('click', (e) => {
      const id = (e.target as HTMLElement).dataset.id;
      if (id) handleSendPDF(id);
    });
  });

  // Order buttons
  pdfList.querySelectorAll('.btn-order-item').forEach(btn => {
    btn.addEventListener('click', (e) => {
      const id = (e.target as HTMLElement).dataset.id;
      if (id) handleOrderPDF(id);
    });
  });

  // Archive buttons
  pdfList.querySelectorAll('.btn-archive').forEach(btn => {
    btn.addEventListener('click', (e) => {
      const id = (e.target as HTMLElement).dataset.id;
      if (id) handleArchivePDF(id);
    });
  });

  // Restore buttons
  pdfList.querySelectorAll('.btn-restore').forEach(btn => {
    btn.addEventListener('click', (e) => {
      const id = (e.target as HTMLElement).dataset.id;
      if (id) handleRestorePDF(id);
    });
  });

  // Delete from server buttons
  pdfList.querySelectorAll('.btn-delete-server').forEach(btn => {
    btn.addEventListener('click', (e) => {
      const id = (e.target as HTMLElement).dataset.id;
      if (id) handleDeleteFromServer(id);
    });
  });

  // Delete/Remove buttons
  pdfList.querySelectorAll('.btn-dismiss').forEach(btn => {
    btn.addEventListener('click', (e) => {
      const id = (e.target as HTMLElement).dataset.id;
      if (id) handleDeletePDF(id);
    });
  });

  // Local tag clicks - check server for document
  pdfList.querySelectorAll('.tag-local').forEach(tag => {
    tag.addEventListener('click', (e) => {
      e.stopPropagation(); // Don't bubble to parent
      const id = (e.target as HTMLElement).dataset.id;
      if (id) handleCheckServer(id);
    });
  });
}

/**
 * Get status text for a PDF
 */
function getStatusText(pdf: DocumentProxy): string {
  switch (pdf.binectStatus) {
    case 'pending':
      return formatTimestamp(pdf.timestamp);
    case 'uploading':
      return 'Uploading...';
    case 'failed':
      return pdf.errorMessage || 'Upload failed';
    case 'in_basket':
      return pdf.binectStatusText || 'Ready to order';
    case 'ordering':
      return 'Sending...';
    case 'in_production':
      return pdf.binectStatusText || 'In production';
    case 'sent':
      return 'Sent successfully';
    case 'canceled':
      return 'Canceled';
    default:
      return formatTimestamp(pdf.timestamp);
  }
}

/**
 * Get CSS class for status
 */
function getStatusClass(status: PDFStatus): string {
  switch (status) {
    case 'pending':
      return 'pending';
    case 'uploading':
    case 'ordering':
      return 'uploading';
    case 'failed':
      return 'failed';
    case 'in_basket':
      return 'in-basket';
    case 'in_production':
      return 'in-production';
    case 'sent':
      return 'sent';
    case 'canceled':
      return 'canceled';
    default:
      return '';
  }
}

/**
 * Get icon for status
 */
function getStatusIcon(status: PDFStatus): string {
  switch (status) {
    case 'pending':
      return '📄';
    case 'uploading':
      return '⏳';
    case 'failed':
      return '❌';
    case 'in_basket':
      return '🛒';
    case 'ordering':
      return '⏳';
    case 'in_production':
      return '🏭';
    case 'sent':
      return '✅';
    case 'canceled':
      return '🚫';
    default:
      return '📄';
  }
}

/**
 * Handle send PDF (upload to Binect)
 */
async function handleSendPDF(id: string) {
  const pdf = pdfQueue.find(p => p.id === id);
  if (!pdf || !currentCredentials) {
    return;
  }

  // Update local state
  pdf.binectStatus = 'uploading';
  renderPDFList();

  // Notify background
  await chrome.runtime.sendMessage({
    action: 'updatePDFStatus',
    id,
    status: 'uploading'
  });

  try {
    // Fetch PDF bytes
    const pdfBytes = await fetchPDFBytes(pdf.url);

    // Compute content fingerprint for deduplication
    const contentHash = await computeContentFingerprint(pdfBytes);

    // Upload to Binect with credentials
    const document = await uploadPDF(
      pdfBytes,
      pdf.filename,
      currentCredentials.username,
      currentCredentials.password
    );

    // Track transfer
    await addTrackingEntry({
      timestamp: Date.now(),
      sourceDomain: pdf.sourceDomain,
      destinationUrl: 'https://api.binect.de/binectapi/v1/documents',
      pdfSize: pdfBytes.byteLength,
      result: document.status.code === 7 ? 'failure' : 'success',
      errorMessage: document.status.code === 7 ? document.status.text : undefined
    });

    // Update last use timestamp
    await updateLastUse();

    // Extract price and recipient from document response
    const meta: PDFStatusMeta = {
      binectDocumentId: document.id,
      binectStatus: document.status.code,
      binectStatusText: document.status.text,
      contentHash
    };

    if (document.letter?.letterData) {
      meta.price = document.letter.letterData.price?.priceAfterTax;
      meta.recipientAddress = document.letter.letterData.recipientAddress;
    }

    // Check if document is erroneous (status 7)
    if (document.status.code === 7) {
      // Extract error message
      let errorMessage = document.status.text || 'Document has errors';
      if (document.letter?.errors && document.letter.errors.length > 0) {
        errorMessage = document.letter.errors.map(e => e.text || e.blankText).join('; ');
      }
      meta.errorMessage = errorMessage;

      // Update status to failed (erroneous)
      await chrome.runtime.sendMessage({
        action: 'updatePDFStatus',
        id,
        status: 'failed',
        meta
      });

      // Update local state
      pdf.binectStatus = 'failed';
      pdf.binectDocumentId = document.id;
      pdf.binectStatusCode = document.status.code;
      pdf.binectStatusText = document.status.text;
      pdf.contentHash = contentHash;
      pdf.errorMessage = errorMessage;
      renderPDFList();

      showStatus(`Document has errors: ${errorMessage}`, 'error');
    } else {
      // Document is shippable (status 2) - in basket
      // Update status to in_basket
      await chrome.runtime.sendMessage({
        action: 'updatePDFStatus',
        id,
        status: 'in_basket',
        meta
      });

      // Update local state
      pdf.binectStatus = 'in_basket';
      pdf.binectDocumentId = document.id;
      pdf.binectStatusCode = document.status.code;
      pdf.binectStatusText = document.status.text;
      pdf.contentHash = contentHash;
      if (document.letter?.letterData) {
        pdf.price = document.letter.letterData.price?.priceAfterTax;
        pdf.recipientAddress = document.letter.letterData.recipientAddress;
      }
      renderPDFList();

      showStatus(`Uploaded! Ready to send (${(pdf.price || 0) / 100} €)`, 'success');
    }

    // Start auto-refresh sequence
    startAutoRefresh();

    // Hide status after 3 seconds
    setTimeout(() => {
      hideStatus();
    }, 3000);

  } catch (error) {
    let errorMessage = 'Upload failed';

    if (error instanceof BinectAPIError) {
      errorMessage = error.message;

      // If auth error, might need to re-login
      if (error.statusCode === 401 || error.statusCode === 403) {
        errorMessage = 'Invalid credentials. Please sign in again.';
        setTimeout(() => {
          handleLogout();
        }, 2000);
      }
    } else if (error instanceof Error) {
      errorMessage = error.message;
    }

    // Track failed transfer
    await addTrackingEntry({
      timestamp: Date.now(),
      sourceDomain: pdf.sourceDomain,
      destinationUrl: 'https://api.binect.de/binectapi/v1/documents',
      pdfSize: pdf.size || 0,
      result: 'failure',
      errorMessage
    });

    // Update status to failed
    await chrome.runtime.sendMessage({
      action: 'updatePDFStatus',
      id,
      status: 'failed',
      meta: { errorMessage }
    });

    // Update local state
    pdf.binectStatus = 'failed';
    pdf.errorMessage = errorMessage;
    renderPDFList();

    showStatus(errorMessage, 'error');
  }
}

/**
 * Handle order PDF (ship document to production)
 */
async function handleOrderPDF(id: string) {
  const pdf = pdfQueue.find(p => p.id === id);
  if (!pdf || !currentCredentials || !pdf.binectDocumentId) {
    return;
  }

  // Update local state
  pdf.binectStatus = 'ordering';
  renderPDFList();

  // Notify background
  await chrome.runtime.sendMessage({
    action: 'updatePDFStatus',
    id,
    status: 'ordering'
  });

  try {
    // Ship the document
    const result = await chrome.runtime.sendMessage({
      action: 'shipDocument',
      documentId: pdf.binectDocumentId,
      username: currentCredentials.username,
      password: currentCredentials.password
    });

    if (!result.success) {
      throw new Error(result.error || 'Failed to ship document');
    }

    // Update status to in_production
    const meta: PDFStatusMeta = {
      binectStatus: result.status,
      binectStatusText: result.statusText
    };

    await chrome.runtime.sendMessage({
      action: 'updatePDFStatus',
      id,
      status: 'in_production',
      meta
    });

    // Update local state
    pdf.binectStatus = 'in_production';
    pdf.binectStatusCode = result.status;
    pdf.binectStatusText = result.statusText;
    renderPDFList();

    showStatus('Sent! Document is in production.', 'success');

    // Start auto-refresh sequence
    startAutoRefresh();

    // Hide status after 3 seconds
    setTimeout(() => {
      hideStatus();
    }, 3000);

  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : 'Send failed';

    // Revert to in_basket status
    await chrome.runtime.sendMessage({
      action: 'updatePDFStatus',
      id,
      status: 'in_basket',
      meta: { errorMessage }
    });

    // Update local state
    pdf.binectStatus = 'in_basket';
    pdf.errorMessage = errorMessage;
    renderPDFList();

    showStatus(errorMessage, 'error');
  }
}

/**
 * Handle refresh all documents that have been uploaded to server
 */
async function handleRefreshAll() {
  if (!currentCredentials) {
    return;
  }

  // Find all documents that have been uploaded and might change status
  // Include erroneous docs - they can be fixed on the server and become shippable
  const uploadedDocs = pdfQueue.filter(p =>
    p.binectDocumentId &&
    (p.binectStatus === 'in_basket' ||
     p.binectStatus === 'in_production' ||
     (p.binectStatus === 'failed' && p.binectStatusCode === 7)) // Erroneous on server
  );

  if (uploadedDocs.length === 0) {
    return;
  }

  console.log(`[Popup] Refreshing ${uploadedDocs.length} document(s)...`);

  let successCount = 0;
  let errorCount = 0;

  for (const pdf of uploadedDocs) {
    try {
      await handleRefreshStatus(pdf.id);
      successCount++;
    } catch {
      errorCount++;
    }
  }

  if (errorCount > 0) {
    console.log(`[Popup] Refresh complete: ${successCount} ok, ${errorCount} failed`);
  }
}

/**
 * Handle refresh document status
 */
async function handleRefreshStatus(id: string) {
  const pdf = pdfQueue.find(p => p.id === id);
  if (!pdf || !currentCredentials || !pdf.binectDocumentId) {
    return;
  }

  try {
    // Get current status from Binect
    const result = await chrome.runtime.sendMessage({
      action: 'getDocumentStatus',
      documentId: pdf.binectDocumentId,
      username: currentCredentials.username,
      password: currentCredentials.password
    });

    if (!result.success) {
      // Check if document was deleted on server (404)
      if (result.errorCode === 404) {
        console.log('[Popup] Document deleted on server, archiving:', id);
        await handleArchivePDF(id);
        showStatus('Document no longer exists on server', 'error');
        return;
      }
      throw new Error(result.error || 'Failed to get status');
    }

    // Determine new local status based on Binect status code
    let newStatus: PDFStatus = pdf.binectStatus;
    if (result.status === 5) {
      newStatus = 'sent';
    } else if (result.status === 6) {
      newStatus = 'canceled';
    } else if (result.status === 7) {
      newStatus = 'failed';  // Erroneous
    } else if (result.status === 3 || result.status === 4) {
      newStatus = 'in_production';
    } else if (result.status === 2) {
      newStatus = 'in_basket';
    }

    const meta: PDFStatusMeta = {
      binectStatus: result.status,
      binectStatusText: result.statusText,
      price: result.price,
      recipientAddress: result.recipientAddress,
      errorMessage: result.errorDetails
    };

    // Update in background
    await chrome.runtime.sendMessage({
      action: 'updatePDFStatus',
      id,
      status: newStatus,
      meta
    });

    // Update local state
    pdf.binectStatus = newStatus;
    pdf.binectStatusCode = result.status;
    pdf.binectStatusText = result.statusText;
    if (result.price !== undefined) pdf.price = result.price;
    if (result.recipientAddress) pdf.recipientAddress = result.recipientAddress;
    // Clear or set error message based on status
    pdf.errorMessage = result.errorDetails || undefined;
    renderPDFList();

  } catch (error) {
    console.error('[Popup] Refresh error:', error);
    // Only show errors that aren't already handled (like 404)
  }
}

/**
 * Handle archive PDF (move from live to archive)
 */
async function handleArchivePDF(id: string) {
  await chrome.runtime.sendMessage({ action: 'archiveProxy', id });
  pdfQueue = pdfQueue.filter(p => p.id !== id);
  renderPDFList();
  showStatus('Document archived', 'success');
  setTimeout(() => hideStatus(), 2000);
}

/**
 * Handle restore PDF (move from archive to live)
 */
async function handleRestorePDF(id: string) {
  await chrome.runtime.sendMessage({ action: 'restoreProxy', id });
  pdfQueue = pdfQueue.filter(p => p.id !== id);
  renderPDFList();
  showStatus('Document restored', 'success');
  setTimeout(() => hideStatus(), 2000);
}

/**
 * Handle check server for a local document
 * Checks if document exists on server (by ID if known, or by filename)
 */
async function handleCheckServer(id: string) {
  const pdf = pdfQueue.find(p => p.id === id);
  if (!pdf || !currentCredentials) {
    return;
  }

  // Find the tag element to show visual feedback
  const tagElement = pdfList.querySelector(`.tag-local[data-id="${id}"]`) as HTMLElement;
  if (tagElement) {
    tagElement.classList.add('checking');
    tagElement.textContent = '...';
  }

  try {
    // First, try to find by known document ID if available
    if (pdf.binectDocumentId) {
      try {
        const result = await chrome.runtime.sendMessage({
          action: 'getDocumentStatus',
          documentId: pdf.binectDocumentId,
          username: currentCredentials.username,
          password: currentCredentials.password
        });

        if (result.success) {
          // Document still exists on server, re-attach it
          await chrome.runtime.sendMessage({
            action: 'attachServerDocument',
            id,
            binectDocumentId: pdf.binectDocumentId,
            binectStatusCode: result.status,
            binectStatusText: result.statusText,
            price: result.price,
            recipientAddress: result.recipientAddress,
            errorMessage: result.errorDetails
          });

          // Update local state
          pdf.binectStatusCode = result.status;
          pdf.binectStatusText = result.statusText;
          if (result.price !== undefined) pdf.price = result.price;
          if (result.recipientAddress) pdf.recipientAddress = result.recipientAddress;

          renderPDFList();
          showStatus('Document found on server and re-linked', 'success');
          setTimeout(() => hideStatus(), 2000);
          return;
        }
        // If 404, continue to filename search
      } catch {
        // Document not found by ID, try filename search
      }
    }

    // Try to find by filename in server documents
    const listResult = await chrome.runtime.sendMessage({
      action: 'listServerDocuments',
      username: currentCredentials.username,
      password: currentCredentials.password
    });

    if (!listResult.success || !listResult.documents) {
      throw new Error('Failed to list server documents');
    }

    // Extract just the filename for comparison (without path)
    const targetFilename = extractFilename(pdf.filename).toLowerCase();

    // Find matching document by filename
    const match = (listResult.documents as Array<{
      id: number;
      filename: string;
      status: number;
      statusText: string;
      price?: number;
      recipientAddress?: string;
      errorDetails?: string;
    }>).find(doc => {
      const docFilename = extractFilename(doc.filename).toLowerCase();
      return docFilename === targetFilename;
    });

    if (match) {
      // Found a matching document, attach it
      await chrome.runtime.sendMessage({
        action: 'attachServerDocument',
        id,
        binectDocumentId: match.id,
        binectStatusCode: match.status,
        binectStatusText: match.statusText,
        price: match.price,
        recipientAddress: match.recipientAddress,
        errorMessage: match.errorDetails
      });

      // Update local state
      pdf.binectDocumentId = match.id;
      pdf.binectStatusCode = match.status;
      pdf.binectStatusText = match.statusText;
      if (match.price !== undefined) pdf.price = match.price;
      if (match.recipientAddress) pdf.recipientAddress = match.recipientAddress;
      if (match.errorDetails) pdf.errorMessage = match.errorDetails;

      renderPDFList();
      showStatus(`Found on server (ID: ${match.id})`, 'success');
      setTimeout(() => hideStatus(), 2000);
    } else {
      // No matching document found
      if (tagElement) {
        tagElement.classList.remove('checking');
        tagElement.textContent = 'local';
      }
      showStatus('Not found on server', 'error');
      setTimeout(() => hideStatus(), 2000);
    }

  } catch (error) {
    console.error('[Popup] Check server error:', error);
    if (tagElement) {
      tagElement.classList.remove('checking');
      tagElement.textContent = 'local';
    }
    const errorMessage = error instanceof Error ? error.message : 'Check failed';
    showStatus(errorMessage, 'error');
    setTimeout(() => hideStatus(), 2000);
  }
}

/**
 * Handle delete from server (for erroneous or canceled documents)
 * After deleting, the proxy is archived and becomes local-only
 */
async function handleDeleteFromServer(id: string) {
  const pdf = pdfQueue.find(p => p.id === id);
  if (!pdf || !currentCredentials || !pdf.binectDocumentId) {
    return;
  }

  try {
    const result = await chrome.runtime.sendMessage({
      action: 'deleteServerDocument',
      documentId: pdf.binectDocumentId,
      username: currentCredentials.username,
      password: currentCredentials.password
    });

    if (!result.success) {
      throw new Error(result.error || 'Failed to delete from server');
    }

    // Clear server fields to make it local-only
    await chrome.runtime.sendMessage({ action: 'clearServerFields', id });

    // Archive the proxy (it's now local-only)
    await chrome.runtime.sendMessage({ action: 'archiveProxy', id });

    // Update local state
    pdf.binectDocumentId = undefined;
    pdf.binectStatusCode = undefined;
    pdf.binectStatusText = undefined;
    pdf.binectStatus = 'pending';
    pdf.price = undefined;
    pdf.recipientAddress = undefined;
    pdf.errorMessage = undefined;

    // Remove from current view (it's now archived)
    pdfQueue = pdfQueue.filter(p => p.id !== id);
    renderPDFList();

    showStatus('Document deleted from server and archived', 'success');
    setTimeout(() => hideStatus(), 2000);

  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : 'Delete failed';
    showStatus(errorMessage, 'error');
    setTimeout(() => hideStatus(), 3000);
  }
}

/**
 * Handle delete PDF (permanently remove)
 */
async function handleDeletePDF(id: string) {
  await chrome.runtime.sendMessage({ action: 'removePDF', id });
  pdfQueue = pdfQueue.filter(p => p.id !== id);
  renderPDFList();
}

/**
 * Handle logout
 */
async function handleLogout() {
  await deleteCredentials();
  currentCredentials = null;
  pdfQueue = [];

  // Clear form
  loginForm.reset();

  showAuthView();
}

/**
 * Handle help button
 */
function handleHelp() {
  // Open tracking page
  chrome.tabs.create({ url: chrome.runtime.getURL('tracking.html') });
}

/**
 * Check if the current active tab is viewing a PDF
 */
async function checkCurrentTabForPDF(): Promise<DetectedPDF | null> {
  try {
    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

    if (!tab || !tab.url) {
      return null;
    }

    // Check if the URL is a PDF
    const url = tab.url;
    const isPDF = url.toLowerCase().endsWith('.pdf') ||
                  url.includes('type=application/pdf') ||
                  url.includes('mime=application/pdf');

    if (isPDF) {
      // Extract filename from URL
      let filename = 'document.pdf';
      try {
        const urlObj = new URL(url);
        const pathname = urlObj.pathname;
        const pathParts = pathname.split('/');
        const lastPart = pathParts[pathParts.length - 1];
        if (lastPart && lastPart.toLowerCase().endsWith('.pdf')) {
          filename = decodeURIComponent(lastPart);
        } else if (tab.title && tab.title !== 'about:blank' && !tab.title.startsWith('chrome://')) {
          // Use tab title if available
          filename = tab.title.endsWith('.pdf') ? tab.title : `${tab.title}.pdf`;
        }
      } catch (e) {
        // Use tab title as fallback
        if (tab.title && tab.title !== 'about:blank') {
          filename = tab.title.endsWith('.pdf') ? tab.title : `${tab.title}.pdf`;
        }
      }

      // Extract domain
      let domain = 'unknown';
      try {
        const urlObj = new URL(url);
        domain = urlObj.hostname;
      } catch (e) {
        // Keep default
      }

      return {
        id: `tab-${tab.id}`,
        filename,
        url,
        size: 0, // Unknown size for viewed PDFs
        timestamp: Date.now(),
        sourceDomain: domain
      };
    }

    return null;
  } catch (error) {
    console.error('Error checking current tab for PDF:', error);
    return null;
  }
}

/**
 * Show auth view
 */
function showAuthView() {
  authView.style.display = 'block';
  mainView.style.display = 'none';
}

/**
 * Show main view
 */
function showMainView() {
  authView.style.display = 'none';
  mainView.style.display = 'block';
}

/**
 * Show no PDF view
 */
function showNoPDF() {
  noPdfView.style.display = 'block';
  pdfListView.style.display = 'none';
  hideStatus();
}

/**
 * Show error message
 */
function showError(message: string) {
  authError.textContent = message;
  authError.style.display = 'block';
}

/**
 * Hide error message
 */
function hideError() {
  authError.style.display = 'none';
}

/**
 * Show status message
 */
function showStatus(message: string, type: 'uploading' | 'success' | 'error') {
  statusMessage.textContent = message;
  statusMessage.className = `status-message ${type}`;
  statusMessage.style.display = 'block';
}

/**
 * Hide status message
 */
function hideStatus() {
  statusMessage.style.display = 'none';
}

/**
 * Escape HTML to prevent XSS
 */
function escapeHtml(text: string): string {
  const div = document.createElement('div');
  div.textContent = text;
  return div.innerHTML;
}

/**
 * Format file size
 */
function formatFileSize(bytes: number): string {
  if (bytes === 0) {
    return 'Size unknown';
  } else if (bytes < 1024) {
    return `${bytes} B`;
  } else if (bytes < 1024 * 1024) {
    return `${(bytes / 1024).toFixed(1)} KB`;
  } else {
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  }
}

/**
 * Format timestamp
 */
function formatTimestamp(timestamp: number): string {
  const now = Date.now();
  const diff = now - timestamp;

  if (diff < 60 * 1000) {
    return 'Just now';
  } else if (diff < 60 * 60 * 1000) {
    const minutes = Math.floor(diff / (60 * 1000));
    return `${minutes} minute${minutes > 1 ? 's' : ''} ago`;
  } else if (diff < 24 * 60 * 60 * 1000) {
    const hours = Math.floor(diff / (60 * 60 * 1000));
    return `${hours} hour${hours > 1 ? 's' : ''} ago`;
  } else {
    return new Date(timestamp).toLocaleDateString();
  }
}

// =============================================================================
// Issue Report Modal
// =============================================================================

/**
 * Track errors for issue reports
 */
function trackError(error: Error | string, stack?: string) {
  const errorEntry = {
    timestamp: Date.now(),
    message: typeof error === 'string' ? error : error.message,
    stack: stack || (error instanceof Error ? error.stack : undefined)
  };
  recentErrors.unshift(errorEntry);
  // Keep only last 10 errors
  if (recentErrors.length > 10) {
    recentErrors.pop();
  }
}

/**
 * Get extension info for issue report
 */
function getExtensionInfo(): string {
  const manifest = chrome.runtime.getManifest();
  return JSON.stringify({
    name: manifest.name,
    version: manifest.version,
    manifestVersion: manifest.manifest_version
  }, null, 2);
}

/**
 * Get browser info for issue report
 */
function getBrowserInfo(): string {
  const ua = navigator.userAgent;
  let browserName = 'Unknown';
  let browserVersion = 'Unknown';

  // Parse user agent for browser info
  if (ua.includes('Chrome/')) {
    browserName = 'Chrome';
    const match = ua.match(/Chrome\/(\d+\.\d+\.\d+\.\d+)/);
    if (match) browserVersion = match[1];
  } else if (ua.includes('Firefox/')) {
    browserName = 'Firefox';
    const match = ua.match(/Firefox\/(\d+\.\d+)/);
    if (match) browserVersion = match[1];
  } else if (ua.includes('Edge/')) {
    browserName = 'Edge';
    const match = ua.match(/Edge\/(\d+\.\d+)/);
    if (match) browserVersion = match[1];
  }

  return JSON.stringify({
    browser: browserName,
    version: browserVersion,
    platform: navigator.platform,
    language: navigator.language,
    userAgent: ua
  }, null, 2);
}

/**
 * Get document status for issue report
 */
function getDocumentStatusInfo(): string {
  if (pdfQueue.length === 0) {
    return 'No documents in queue';
  }

  const summary = {
    total: pdfQueue.length,
    byStatus: {} as Record<string, number>,
    documents: pdfQueue.map(doc => ({
      id: doc.id.substring(0, 8) + '...',
      binectStatus: doc.binectStatus,
      binectStatusCode: doc.binectStatusCode,
      hasError: !!doc.errorMessage
    }))
  };

  // Count by status
  for (const doc of pdfQueue) {
    summary.byStatus[doc.binectStatus] = (summary.byStatus[doc.binectStatus] || 0) + 1;
  }

  return JSON.stringify(summary, null, 2);
}

/**
 * Get recent errors for issue report
 */
function getRecentErrorsInfo(): string {
  if (recentErrors.length === 0) {
    return 'No recent errors';
  }

  return recentErrors.map(err => {
    const date = new Date(err.timestamp).toISOString();
    let text = `[${date}] ${err.message}`;
    if (err.stack) {
      text += `\n  Stack: ${err.stack.split('\n').slice(0, 3).join('\n  ')}`;
    }
    return text;
  }).join('\n\n');
}

/**
 * Open the issue report modal
 */
function openIssueModal() {
  // Clear previous input
  issueTitleInput.value = '';
  issueDescriptionInput.value = '';

  // Reset checkboxes
  issueModal.querySelectorAll('input[type="checkbox"]').forEach(cb => {
    (cb as HTMLInputElement).checked = false;
  });

  // Populate context sections
  extensionInfoContent.textContent = getExtensionInfo();
  browserInfoContent.textContent = getBrowserInfo();
  documentStatusContent.textContent = getDocumentStatusInfo();
  recentErrorsContent.textContent = getRecentErrorsInfo();

  // Close all sections by default
  issueModal.querySelectorAll('.context-section-content').forEach(section => {
    (section as HTMLElement).style.display = 'none';
  });
  issueModal.querySelectorAll('.toggle-icon').forEach(icon => {
    icon.textContent = '▶';
  });

  // Show modal
  issueModal.style.display = 'flex';
}

/**
 * Close the issue report modal
 */
function closeIssueModal() {
  issueModal.style.display = 'none';
}

/**
 * Toggle a context section
 */
function toggleContextSection(sectionId: string) {
  const content = document.getElementById(sectionId);
  const button = issueModal.querySelector(`[data-section="${sectionId}"]`);
  const icon = button?.querySelector('.toggle-icon');

  if (content && icon) {
    const isVisible = content.style.display !== 'none';
    content.style.display = isVisible ? 'none' : 'block';
    icon.textContent = isVisible ? '▶' : '▼';
  }
}

/**
 * Format issue report as Markdown and copy to clipboard
 */
async function copyIssueToClipboard() {
  const title = issueTitleInput.value.trim();
  const description = issueDescriptionInput.value.trim();

  // Build markdown content
  let markdown = '';

  if (title) {
    markdown += `# ${title}\n\n`;
  }

  if (description) {
    markdown += `## Description\n\n${description}\n\n`;
  }

  // Add context sections (only those not excluded)
  const sections = [
    { id: 'extensionInfo', name: 'Extension Info', content: extensionInfoContent.textContent },
    { id: 'browserInfo', name: 'Browser Info', content: browserInfoContent.textContent },
    { id: 'documentStatus', name: 'Document Status', content: documentStatusContent.textContent },
    { id: 'recentErrors', name: 'Recent Errors', content: recentErrorsContent.textContent }
  ];

  let hasContext = false;
  for (const section of sections) {
    const checkbox = issueModal.querySelector(`input[data-exclude="${section.id}"]`) as HTMLInputElement;
    if (!checkbox?.checked && section.content && section.content !== 'No recent errors' && section.content !== 'No documents in queue') {
      if (!hasContext) {
        markdown += `## Context\n\n`;
        hasContext = true;
      }
      markdown += `### ${section.name}\n\n\`\`\`json\n${section.content}\n\`\`\`\n\n`;
    }
  }

  // Copy to clipboard
  try {
    await navigator.clipboard.writeText(markdown);

    // Show success feedback
    const originalText = copyToClipboardBtn.textContent;
    copyToClipboardBtn.textContent = 'Copied!';
    copyToClipboardBtn.classList.add('btn-copy-success');

    setTimeout(() => {
      copyToClipboardBtn.textContent = originalText;
      copyToClipboardBtn.classList.remove('btn-copy-success');
    }, 2000);
  } catch (error) {
    console.error('Failed to copy to clipboard:', error);
    trackError(error as Error);

    // Show error feedback
    copyToClipboardBtn.textContent = 'Copy failed';
    setTimeout(() => {
      copyToClipboardBtn.textContent = 'Copy to Clipboard';
    }, 2000);
  }
}

/**
 * Setup issue modal event listeners
 */
function setupIssueModalListeners() {
  // Open modal
  reportIssueBtn.addEventListener('click', openIssueModal);

  // Close modal
  closeModalBtn.addEventListener('click', closeIssueModal);
  modalBackdrop.addEventListener('click', closeIssueModal);

  // Close on Escape key
  document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape' && issueModal.style.display !== 'none') {
      closeIssueModal();
    }
  });

  // Context section toggles
  issueModal.querySelectorAll('.context-toggle').forEach(toggle => {
    toggle.addEventListener('click', () => {
      const sectionId = (toggle as HTMLElement).dataset.section;
      if (sectionId) {
        toggleContextSection(sectionId);
      }
    });
  });

  // Copy to clipboard
  copyToClipboardBtn.addEventListener('click', copyIssueToClipboard);
}

// Initialize on load
init();

// Setup issue modal listeners after DOM is ready
setupIssueModalListeners();
