/**
 * 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,
  getPendingPDFs,
  updatePDFStatus,
  dismissPDF,
  removePDF,
  cleanupOldEntries,
  PDFStatus,
  PDFStatusMeta
} from '../utils/pdf-queue';
import { shipDocument, getDocumentStatus } 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;
  }

  // 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;
  }

  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 => {
        sendResponse({
          success: false,
          error: error instanceof Error ? error.message : 'Failed to get status'
        });
      });
    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());
