/**
 * UI Injector - Injects UI elements into Filevine pages
 *
 * Adds "View DICOM" buttons next to DICOM files in the Filevine document list
 * Adds "Protect Document" buttons next to supported files for Echomark watermarking
 */

import { isFeatureEnabled } from '../lib/feature-flags.js';

export class UIInjector {
  constructor() {
    this.injectedButtons = new Map(); // Track injected buttons by document ID
    this.observer = null;
    this.isInjecting = false;
    this.recipientModal = null;
  }

  /**
   * Send message to extension with error handling for invalidated context
   */
  async sendMessageSafely(message) {
    try {
      return await chrome.runtime.sendMessage(message);
    } catch (error) {
      // Check if this is an "Extension context invalidated" error
      if (error.message && error.message.includes('Extension context invalidated')) {
        throw new Error('Extension was reloaded. Please refresh this page to continue.');
      }
      // Re-throw other errors
      throw error;
    }
  }

  /**
   * Start injecting UI elements
   */
  async start() {
    console.log('[UI Injector] Starting UI injection');

    // Load RecipientModal dynamically
    try {
      const baseUrl = chrome.runtime.getURL('');
      const modalModule = await import(`${baseUrl}src/content/recipient-modal.js`);
      this.recipientModal = new modalModule.RecipientModal();
      console.log('[UI Injector] RecipientModal loaded');
    } catch (error) {
      console.error('[UI Injector] Failed to load RecipientModal:', error);
    }

    // Initial injection
    this.injectUI();

    // Watch for DOM changes (new documents loaded, SPA navigation)
    this.observer = new MutationObserver(() => {
      if (!this.isInjecting) {
        this.isInjecting = true;
        // Debounce - wait for DOM to settle
        setTimeout(() => {
          this.injectUI();
          this.isInjecting = false;
        }, 500);
      }
    });

    this.observer.observe(document.body, {
      childList: true,
      subtree: true
    });

    console.log('[UI Injector] Observer started');
  }

  /**
   * Stop injecting UI elements
   */
  stop() {
    if (this.observer) {
      this.observer.disconnect();
      this.observer = null;
    }
    console.log('[UI Injector] Stopped');
  }

  /**
   * Main injection logic - finds DICOM files and adds buttons
   */
  injectUI() {
    // Strategy 1: Look for document rows in tables
    this.injectIntoDocumentTable();

    // Strategy 2: Look for document cards/list items
    this.injectIntoDocumentList();

    // Strategy 3: Look for file detail views
    this.injectIntoFileDetail();
  }

  /**
   * Inject buttons into document table rows
   * Filevine uses tables for document listings in some views
   */
  injectIntoDocumentTable() {
    // Look for document table rows
    const rows = document.querySelectorAll('tr[data-doc-id], tr[data-document-id]');

    rows.forEach(row => {
      const docId = row.dataset.docId || row.dataset.documentId;
      if (!docId) return;

      const filename = this.getFilenameFromRow(row);
      if (!filename) return;

      // Find the actions column or last cell
      const actionsCell = row.querySelector('.actions, .document-actions, td:last-child');
      if (!actionsCell) return;

      // Check if this is a DICOM file
      if (this.isDicomFile(filename)) {
        // Skip if we already injected a DICOM button for this document
        if (!this.injectedButtons.has(`table-dicom-${docId}`)) {
          const button = this.createViewButton(docId, filename);
          actionsCell.insertBefore(button, actionsCell.firstChild);
          this.injectedButtons.set(`table-dicom-${docId}`, button);
          console.log('[UI Injector] Injected DICOM button for document', docId, 'in table');
        }
      }

      // Check if this file supports Echomark watermarking
      if (isFeatureEnabled('ECHOMARK_ENABLED') && this.supportsEchomark(filename)) {
        // Skip if we already injected a Protect button for this document
        if (!this.injectedButtons.has(`table-protect-${docId}`)) {
          const button = this.createProtectButton(docId, filename);
          actionsCell.insertBefore(button, actionsCell.firstChild);
          this.injectedButtons.set(`table-protect-${docId}`, button);
          console.log('[UI Injector] Injected Protect button for document', docId, 'in table');
        }
      }
    });
  }

  /**
   * Inject buttons into document list/card layouts
   * Filevine uses card layouts in some views
   */
  injectIntoDocumentList() {
    // Look for document list items or cards
    const selectors = [
      '.document-item',
      '.file-item',
      '.doc-card',
      '[data-document-id]',
      '[data-doc-id]'
    ];

    selectors.forEach(selector => {
      const items = document.querySelectorAll(selector);

      items.forEach(item => {
        const docId = item.dataset.documentId || item.dataset.docId;
        if (!docId) return;

        const filename = this.getFilenameFromElement(item);
        if (!filename) return;

        // Find or create actions area
        let actionsArea = item.querySelector('.actions, .document-actions, .file-actions');
        if (!actionsArea) {
          actionsArea = document.createElement('div');
          actionsArea.className = 'fv-plugin-actions';
          actionsArea.style.cssText = 'display: flex; gap: 8px; margin-top: 8px;';
          item.appendChild(actionsArea);
        }

        // Check if this is a DICOM file
        if (this.isDicomFile(filename)) {
          if (!this.injectedButtons.has(`list-dicom-${docId}`)) {
            const button = this.createViewButton(docId, filename);
            actionsArea.insertBefore(button, actionsArea.firstChild);
            this.injectedButtons.set(`list-dicom-${docId}`, true);
            console.log('[UI Injector] Injected DICOM button for document', docId, 'in list');
          }
        }

        // Check if this file supports Echomark watermarking
        if (isFeatureEnabled('ECHOMARK_ENABLED') && this.supportsEchomark(filename)) {
          if (!this.injectedButtons.has(`list-protect-${docId}`)) {
            const button = this.createProtectButton(docId, filename);
            actionsArea.insertBefore(button, actionsArea.firstChild);
            this.injectedButtons.set(`list-protect-${docId}`, true);
            console.log('[UI Injector] Injected Protect button for document', docId, 'in list');
          }
        }
      });
    });
  }

  /**
   * Inject buttons into file detail views
   * When viewing a single document's details
   */
  injectIntoFileDetail() {
    // Look for file detail container
    const detailContainer = document.querySelector('.document-detail, .file-detail, [data-document-detail]');
    if (!detailContainer) return;

    const docId = detailContainer.dataset.docId || detailContainer.dataset.documentId;
    const filename = this.getFilenameFromElement(detailContainer);

    if (!docId || !filename) return;

    // Find or create actions area
    let targetArea = detailContainer.querySelector('.detail-actions, .document-actions, .header');

    if (!targetArea) {
      targetArea = document.createElement('div');
      targetArea.className = 'fv-plugin-detail-actions';
      targetArea.style.cssText = 'margin: 16px 0; display: flex; gap: 12px;';
      detailContainer.insertBefore(targetArea, detailContainer.firstChild);
    }

    // Check if this is a DICOM file
    if (this.isDicomFile(filename)) {
      if (!this.injectedButtons.has(`detail-dicom-${docId}`)) {
        const button = this.createViewButton(docId, filename, true);
        targetArea.appendChild(button);
        this.injectedButtons.set(`detail-dicom-${docId}`, true);
        console.log('[UI Injector] Injected DICOM button in detail view for document', docId);
      }
    }

    // Check if this file supports Echomark watermarking
    if (isFeatureEnabled('ECHOMARK_ENABLED') && this.supportsEchomark(filename)) {
      if (!this.injectedButtons.has(`detail-protect-${docId}`)) {
        const button = this.createProtectButton(docId, filename, true);
        targetArea.appendChild(button);
        this.injectedButtons.set(`detail-protect-${docId}`, true);
        console.log('[UI Injector] Injected Protect button in detail view for document', docId);
      }
    }
  }

  /**
   * Create a "View DICOM" button
   */
  createViewButton(docId, filename, large = false) {
    const button = document.createElement('button');
    button.className = 'fv-plugin-view-dicom-btn';
    button.textContent = large ? '🏥 Open DICOM Viewer' : '🏥 View';
    button.title = `Open ${filename} in DICOM viewer`;
    button.dataset.docId = docId;
    button.dataset.filename = filename;

    // Styling
    button.style.cssText = `
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
      border: none;
      border-radius: ${large ? '8px' : '4px'};
      padding: ${large ? '10px 20px' : '6px 12px'};
      font-size: ${large ? '14px' : '12px'};
      font-weight: 600;
      cursor: pointer;
      transition: all 0.2s ease;
      display: inline-flex;
      align-items: center;
      gap: 6px;
      box-shadow: 0 2px 4px rgba(102, 126, 234, 0.2);
    `;

    // Hover effect
    button.addEventListener('mouseenter', () => {
      button.style.transform = 'translateY(-1px)';
      button.style.boxShadow = '0 4px 8px rgba(102, 126, 234, 0.3)';
    });

    button.addEventListener('mouseleave', () => {
      button.style.transform = 'translateY(0)';
      button.style.boxShadow = '0 2px 4px rgba(102, 126, 234, 0.2)';
    });

    // Click handler
    button.addEventListener('click', async (e) => {
      e.preventDefault();
      e.stopPropagation();

      await this.handleViewClick(docId, filename, button);
    });

    return button;
  }

  /**
   * Create a "Protect Document" button for Echomark watermarking
   */
  createProtectButton(docId, filename, large = false) {
    const button = document.createElement('button');
    button.className = 'fv-plugin-protect-btn';
    button.title = `Protect ${filename} with Echomark forensic watermark`;
    button.dataset.docId = docId;
    button.dataset.filename = filename;

    // Create button content with shield icon
    button.innerHTML = `
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width: ${large ? '18px' : '14px'}; height: ${large ? '18px' : '14px'};">
        <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
        <path d="M9 12l2 2 4-4"></path>
      </svg>
      <span>${large ? 'Echomark Document' : 'Echomark'}</span>
    `;

    // Styling
    button.style.cssText = `
      background: transparent;
      color: #4a5568;
      border: 1px solid #800020;
      border-radius: ${large ? '4px' : '3px'};
      padding: ${large ? '6px 12px' : '4px 10px'};
      height: ${large ? '32px' : '28px'};
      font-size: ${large ? '13px' : '12px'};
      font-weight: 500;
      cursor: pointer;
      transition: all 0.2s ease;
      display: inline-flex;
      align-items: center;
      gap: 6px;
    `;

    // Hover effect
    button.addEventListener('mouseenter', () => {
      button.style.background = '#f7fafc';
      button.style.borderColor = '#600018';
    });

    button.addEventListener('mouseleave', () => {
      button.style.background = 'transparent';
      button.style.borderColor = '#800020';
    });

    // Click handler
    button.addEventListener('click', async (e) => {
      e.preventDefault();
      e.stopPropagation();

      await this.handleProtectClick(docId, filename, button);
    });

    return button;
  }

  /**
   * Handle "Protect Document" button click
   */
  async handleProtectClick(docId, filename, button) {
    console.log('[UI Injector] Protect Document clicked:', { docId, filename });

    if (!this.recipientModal) {
      this.showNotification('Recipient modal not loaded', 'error');
      return;
    }

    try {
      // Get current project ID from URL
      const projectId = this.getProjectIdFromUrl();

      if (!projectId) {
        throw new Error('Could not determine project ID from URL');
      }

      // Show recipient selection modal
      await this.recipientModal.show(
        {
          docId,
          filename,
          projectId
        },
        async (recipientData, watermarkOptions) => {
          // Handle watermarking when user confirms
          await this.handleWatermarkDocument(docId, filename, projectId, recipientData, watermarkOptions);
        }
      );

    } catch (error) {
      console.error('[UI Injector] Failed to show protect modal:', error);
      this.showNotification(`Failed to protect document: ${error.message}`, 'error');
    }
  }

  /**
   * Handle document watermarking after recipient selection
   */
  async handleWatermarkDocument(docId, filename, projectId, recipientData, watermarkOptions) {
    console.log('[UI Injector] Starting watermarking:', {
      docId,
      filename,
      recipient: recipientData.recipientName
    });

    try {
      // Send message to background script to handle watermarking
      const response = await this.sendMessageSafely({
        type: 'WATERMARK_DOCUMENT',
        docId: parseInt(docId),
        projectId: parseInt(projectId),
        filename: filename,
        mimeType: this.getEchomarkMimeType(filename),
        recipientData: recipientData,
        watermarkOptions: watermarkOptions
      });

      if (response?.error) {
        throw new Error(response.error);
      }

      // Success
      this.showNotification(
        `Document protected for ${recipientData.recipientName}`,
        'success'
      );

      console.log('[UI Injector] Watermarking complete');

    } catch (error) {
      console.error('[UI Injector] Watermarking failed:', error);
      throw error; // Re-throw so modal can handle it
    }
  }

  /**
   * Handle "View DICOM" button click
   */
  async handleViewClick(docId, filename, button) {
    console.log('[UI Injector] View DICOM clicked:', { docId, filename });

    // Show loading state
    const originalText = button.textContent;
    button.textContent = '⏳ Loading...';
    button.disabled = true;
    button.style.opacity = '0.7';
    button.style.cursor = 'wait';

    try {
      // Get current project ID from URL
      const projectId = this.getProjectIdFromUrl();

      if (!projectId) {
        throw new Error('Could not determine project ID from URL');
      }

      // Send message to background script to open viewer
      const response = await this.sendMessageSafely({
        type: 'VIEW_FILE_DIRECT',
        docId: parseInt(docId),
        projectId: parseInt(projectId),
        filename: filename,
        mimeType: 'application/dicom'
      });

      if (response?.error) {
        throw new Error(response.error);
      }

      // Success - show brief feedback
      button.textContent = '✓ Opened';
      button.style.background = 'linear-gradient(135deg, #06b6d4 0%, #3b82f6 100%)';

      setTimeout(() => {
        button.textContent = originalText;
        button.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)';
        button.disabled = false;
        button.style.opacity = '1';
        button.style.cursor = 'pointer';
      }, 2000);

    } catch (error) {
      console.error('[UI Injector] Failed to open DICOM viewer:', error);

      // Show error state
      button.textContent = '✗ Failed';
      button.style.background = 'linear-gradient(135deg, #ef4444 0%, #dc2626 100%)';

      // Show error notification
      this.showNotification(`Failed to open viewer: ${error.message}`, 'error');

      setTimeout(() => {
        button.textContent = originalText;
        button.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)';
        button.disabled = false;
        button.style.opacity = '1';
        button.style.cursor = 'pointer';
      }, 3000);
    }
  }

  /**
   * Get filename from table row
   */
  getFilenameFromRow(row) {
    // Try various selectors for filename
    const filenameCell = row.querySelector('.filename, .file-name, .document-name, [data-filename]');
    if (filenameCell) {
      return filenameCell.textContent.trim() || filenameCell.dataset.filename;
    }

    // Try to find any text that looks like a filename
    const cells = row.querySelectorAll('td');
    for (const cell of cells) {
      const text = cell.textContent.trim();
      if (text.includes('.dcm') || text.includes('.dicom')) {
        return text;
      }
    }

    return '';
  }

  /**
   * Get filename from element
   */
  getFilenameFromElement(element) {
    // Try data attribute first
    if (element.dataset.filename) {
      return element.dataset.filename;
    }

    // Try various selectors
    const filenameEl = element.querySelector('.filename, .file-name, .document-name, .name, .title');
    if (filenameEl) {
      return filenameEl.textContent.trim();
    }

    // Try to find any text that looks like a filename
    const text = element.textContent;
    const match = text.match(/[^\s]+\.(dcm|dicom)/i);
    if (match) {
      return match[0];
    }

    return '';
  }

  /**
   * Check if file is a DICOM file
   */
  isDicomFile(filename) {
    if (!filename) return false;
    const lower = filename.toLowerCase();
    return lower.endsWith('.dcm') || lower.endsWith('.dicom');
  }

  /**
   * Check if file supports Echomark watermarking
   * Supports PDFs and images (JPEG, PNG, TIFF, BMP, GIF)
   */
  supportsEchomark(filename) {
    if (!filename) return false;
    const lower = filename.toLowerCase();

    // PDF support
    if (lower.endsWith('.pdf')) return true;

    // Image support
    const imageExts = ['.jpg', '.jpeg', '.png', '.tiff', '.tif', '.bmp', '.gif'];
    return imageExts.some(ext => lower.endsWith(ext));
  }

  /**
   * Get MIME type for Echomark watermarking
   */
  getEchomarkMimeType(filename) {
    const lower = filename.toLowerCase();

    if (lower.endsWith('.pdf')) return 'application/pdf';
    if (lower.endsWith('.jpg') || lower.endsWith('.jpeg')) return 'image/jpeg';
    if (lower.endsWith('.png')) return 'image/png';
    if (lower.endsWith('.tiff') || lower.endsWith('.tif')) return 'image/tiff';
    if (lower.endsWith('.bmp')) return 'image/bmp';
    if (lower.endsWith('.gif')) return 'image/gif';

    return 'application/octet-stream';
  }

  /**
   * Get project ID from current URL
   */
  getProjectIdFromUrl() {
    // Filevine project URLs typically look like:
    // https://app.filevineapp.com/project/{projectId}/...
    // https://{org}.filevineapp.com/project/{projectId}/...

    const match = window.location.pathname.match(/\/project\/(\d+)/i);
    if (match) {
      return match[1];
    }

    // Also check for doc URLs which might have project context:
    // /docs/{docId}?projectId={projectId}
    const params = new URLSearchParams(window.location.search);
    const projectId = params.get('projectId') || params.get('project_id');
    if (projectId) {
      return projectId;
    }

    return null;
  }

  /**
   * Show a notification to the user
   */
  showNotification(message, type = 'info') {
    // Remove existing notifications
    const existing = document.querySelector('.fv-plugin-notification');
    if (existing) {
      existing.remove();
    }

    // Create notification
    const notification = document.createElement('div');
    notification.className = 'fv-plugin-notification';
    notification.textContent = message;

    // Styling based on type
    const colors = {
      info: { bg: '#3b82f6', border: '#2563eb' },
      success: { bg: '#10b981', border: '#059669' },
      error: { bg: '#ef4444', border: '#dc2626' },
      warning: { bg: '#f59e0b', border: '#d97706' }
    };

    const color = colors[type] || colors.info;

    notification.style.cssText = `
      position: fixed;
      top: 20px;
      right: 20px;
      background: ${color.bg};
      color: white;
      padding: 12px 20px;
      border-radius: 8px;
      border-left: 4px solid ${color.border};
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
      z-index: 999999;
      font-size: 14px;
      font-weight: 500;
      max-width: 400px;
      animation: slideIn 0.3s ease;
    `;

    // Add animation
    const style = document.createElement('style');
    style.textContent = `
      @keyframes slideIn {
        from {
          transform: translateX(400px);
          opacity: 0;
        }
        to {
          transform: translateX(0);
          opacity: 1;
        }
      }
    `;
    document.head.appendChild(style);

    document.body.appendChild(notification);

    // Auto-remove after 5 seconds
    setTimeout(() => {
      notification.style.animation = 'slideOut 0.3s ease';
      notification.style.animationFillMode = 'forwards';

      setTimeout(() => {
        notification.remove();
      }, 300);
    }, 5000);
  }
}
