/**
 * Service Worker (Background Script)
 * Handles PDF detection, queue management, and credential expiry checks
 */

import { startPDFDetection, DetectedPDF } from '../utils/pdf-detector';
import { loadCredentials } from '../utils/storage';
import {
  addPDF,
  getActionableCount,
  getAllPDFs,
  getLiveProxies,
  getArchivedProxies,
  getPendingPDFs,
  updatePDFStatus,
  archiveProxy,
  restoreProxy,
  dismissPDF,
  removePDF,
  cleanupOldEntries,
  syncFromServer,
  clearServerFields,
  attachServerDocument,
  PDFStatus,
  PDFStatusMeta
} from '../utils/pdf-queue';
import { shipDocument, getDocumentStatus, deleteDocument, listServerDocuments } from '../utils/binect-api';

/**
 * Initialize extension on install
 */
chrome.runtime.onInstalled.addListener((details) => {
  console.log('[Service Worker] onInstalled event:', details.reason);
  if (details.reason === 'install') {
    console.log('[Service Worker] BinectChrome installed');
    setupAlarms();
  } else if (details.reason === 'update') {
    console.log('[Service Worker] BinectChrome updated');
    setupAlarms();
  }
});

/**
 * Handle extension startup
 */
chrome.runtime.onStartup.addListener(() => {
  console.log('[Service Worker] onStartup event - BinectChrome started');
  setupAlarms();
  updateBadge();
});

/**
 * Set up alarms for periodic tasks
 */
function setupAlarms() {
  // Credential expiry check
  chrome.alarms.create('checkCredentialExpiry', {
    delayInMinutes: 1,
    periodInMinutes: 24 * 60 // Every 24 hours
  });

  // PDF queue cleanup
  chrome.alarms.create('cleanupPDFQueue', {
    delayInMinutes: 60, // First cleanup in 1 hour
    periodInMinutes: 6 * 60 // Every 6 hours
  });
}

/**
 * Handle alarm events
 */
chrome.alarms.onAlarm.addListener((alarm) => {
  if (alarm.name === 'checkCredentialExpiry') {
    checkAndDeleteExpiredCredentials();
  }
  if (alarm.name === 'cleanupPDFQueue') {
    cleanupOldEntries();
  }
});

/**
 * Check if credentials are expired and delete them
 */
async function checkAndDeleteExpiredCredentials() {
  const credentials = await loadCredentials();
  if (credentials === null) {
    console.log('[Service Worker] Credentials expired and deleted');
  }
}

/**
 * Update badge with actionable PDF count
 */
async function updateBadge() {
  const count = await getActionableCount();
  const text = count > 0 ? count.toString() : '•';
  chrome.action.setBadgeText({ text });
  chrome.action.setBadgeBackgroundColor({ color: '#4A90E2' }); // Binect Blue
  console.log('[Service Worker] Badge updated:', text);
}

// Initialize badge on load
updateBadge();

/**
 * Start PDF detection
 */
console.log('[Service Worker] Initializing PDF detection...');
startPDFDetection(async (pdf: DetectedPDF) => {
  console.log('[Service Worker] PDF DETECTED:', pdf.filename);

  // Add to persistent queue
  const entry = await addPDF(pdf);

  if (entry) {
    console.log('[Service Worker] PDF added to queue:', entry.filename);
  } else {
    console.log('[Service Worker] PDF skipped (already uploaded):', pdf.filename);
  }

  // Update badge
  await updateBadge();
});

/**
 * Handle messages from popup
 */
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  console.log('[Service Worker] Message received:', request.action);

  // Get all PDFs (including completed ones for display)
  if (request.action === 'getAllPDFs') {
    getAllPDFs().then(entries => {
      console.log('[Service Worker] Returning all PDFs:', entries.length, 'entries');
      sendResponse({ entries });
    });
    return true;
  }

  // Get live proxy documents (not archived)
  if (request.action === 'getLiveProxies') {
    getLiveProxies().then(entries => {
      console.log('[Service Worker] Returning live proxies:', entries.length, 'entries');
      sendResponse({ entries });
    });
    return true;
  }

  // Get archived proxy documents
  if (request.action === 'getArchivedProxies') {
    getArchivedProxies().then(entries => {
      console.log('[Service Worker] Returning archived proxies:', entries.length, 'entries');
      sendResponse({ entries });
    });
    return true;
  }

  // Add a PDF to the queue (from popup discovery)
  if (request.action === 'addPDF') {
    addPDF(request.pdf).then(entry => {
      if (entry) {
        console.log('[Service Worker] PDF added via message:', entry.filename);
      }
      return updateBadge().then(() => entry);
    }).then(entry => {
      sendResponse({ entry });
    });
    return true;
  }

  // Legacy: Get only actionable PDFs
  if (request.action === 'getPDFQueue') {
    getPendingPDFs().then(entries => {
      console.log('[Service Worker] Returning PDF queue:', entries.length, 'entries');
      sendResponse({ entries });
    });
    return true;
  }

  if (request.action === 'updatePDFStatus') {
    const { id, status, meta } = request as { id: string; status: PDFStatus; meta?: PDFStatusMeta };
    updatePDFStatus(id, status, meta).then(() => {
      return updateBadge();
    }).then(() => {
      sendResponse({ success: true });
    });
    return true;
  }

  if (request.action === 'dismissPDF') {
    dismissPDF(request.id).then(() => {
      return updateBadge();
    }).then(() => {
      sendResponse({ success: true });
    });
    return true;
  }

  // Archive a proxy document (move to archive view)
  if (request.action === 'archiveProxy') {
    archiveProxy(request.id).then(() => {
      return updateBadge();
    }).then(() => {
      sendResponse({ success: true });
    });
    return true;
  }

  // Restore a proxy document (move back to live view)
  if (request.action === 'restoreProxy') {
    restoreProxy(request.id).then(() => {
      return updateBadge();
    }).then(() => {
      sendResponse({ success: true });
    });
    return true;
  }

  if (request.action === 'removePDF') {
    removePDF(request.id).then(() => {
      return updateBadge();
    }).then(() => {
      sendResponse({ success: true });
    });
    return true;
  }

  // Ship a document (place order for production)
  if (request.action === 'shipDocument') {
    const { documentId, username, password } = request as {
      documentId: number;
      username: string;
      password: string;
    };

    shipDocument(documentId, username, password)
      .then(result => {
        sendResponse({ success: true, ...result });
      })
      .catch(error => {
        sendResponse({
          success: false,
          error: error instanceof Error ? error.message : 'Failed to ship document'
        });
      });
    return true;
  }

  // Get document status from Binect
  if (request.action === 'getDocumentStatus') {
    const { documentId, username, password } = request as {
      documentId: number;
      username: string;
      password: string;
    };

    getDocumentStatus(documentId, username, password)
      .then(result => {
        sendResponse({ success: true, ...result });
      })
      .catch(error => {
        // Include error code for 404 detection
        const errorCode = (error as { statusCode?: number }).statusCode;
        sendResponse({
          success: false,
          error: error instanceof Error ? error.message : 'Failed to get status',
          errorCode
        });
      });
    return true;
  }

  // Delete a document from the server
  if (request.action === 'deleteServerDocument') {
    const { documentId, username, password } = request as {
      documentId: number;
      username: string;
      password: string;
    };

    deleteDocument(documentId, username, password)
      .then(() => {
        sendResponse({ success: true });
      })
      .catch(error => {
        sendResponse({
          success: false,
          error: error instanceof Error ? error.message : 'Failed to delete document'
        });
      });
    return true;
  }

  // List all documents from the server (for sync)
  if (request.action === 'listServerDocuments') {
    const { username, password } = request as {
      username: string;
      password: string;
    };

    listServerDocuments(username, password)
      .then(documents => {
        sendResponse({ success: true, documents });
      })
      .catch(error => {
        sendResponse({
          success: false,
          error: error instanceof Error ? error.message : 'Failed to list documents'
        });
      });
    return true;
  }

  // Sync a server document to local proxy (create or update)
  if (request.action === 'syncFromServer') {
    const { binectDocumentId, filename, binectStatusCode, binectStatusText, price, recipientAddress, errorDetails } = request as {
      binectDocumentId: number;
      filename: string;
      binectStatusCode: number;
      binectStatusText: string;
      price?: number;
      recipientAddress?: string;
      errorDetails?: string;
    };

    syncFromServer(binectDocumentId, filename, binectStatusCode, binectStatusText, price, recipientAddress, errorDetails)
      .then(proxy => {
        sendResponse({ success: true, proxy });
      })
      .catch(error => {
        sendResponse({
          success: false,
          error: error instanceof Error ? error.message : 'Failed to sync document'
        });
      });
    return true;
  }

  // Clear server fields from a proxy (when deleted from server)
  if (request.action === 'clearServerFields') {
    clearServerFields(request.id).then(() => {
      return updateBadge();
    }).then(() => {
      sendResponse({ success: true });
    });
    return true;
  }

  // Attach a server document to a local proxy
  if (request.action === 'attachServerDocument') {
    const { id, binectDocumentId, binectStatusCode, binectStatusText, price, recipientAddress, errorMessage } = request as {
      id: string;
      binectDocumentId: number;
      binectStatusCode: number;
      binectStatusText: string;
      price?: number;
      recipientAddress?: string;
      errorMessage?: string;
    };

    attachServerDocument(id, binectDocumentId, binectStatusCode, binectStatusText, price, recipientAddress, errorMessage)
      .then(() => {
        return updateBadge();
      })
      .then(() => {
        sendResponse({ success: true });
      })
      .catch(error => {
        sendResponse({
          success: false,
          error: error instanceof Error ? error.message : 'Failed to attach document'
        });
      });
    return true;
  }

  // Legacy handlers for backward compatibility
  if (request.action === 'getLastPDF') {
    getPendingPDFs().then(entries => {
      const pdf = entries.length > 0 ? entries[0] : null;
      sendResponse({ pdf });
    });
    return true;
  }

  if (request.action === 'clearLastPDF' || request.action === 'pdfSent') {
    updateBadge().then(() => {
      sendResponse({ success: true });
    });
    return true;
  }

  return false;
});

console.log('[Service Worker] ===== BinectChrome service worker loaded =====');
console.log('[Service Worker] Timestamp:', new Date().toISOString());
