/**
 * Echomark Watermarking Handler
 *
 * Handles document watermarking workflow:
 * 1. Download document from Filevine
 * 2. Send to Echomark API for watermarking
 * 3. Store marking schema for leak investigation
 * 4. Return watermarked document or store for later access
 */

import { echomarkClient } from '../lib/echomark-client.js';
import { webApiClient } from './web-api-client.js';
import { filevineClient } from './api.js';
import { authManager } from './auth.js';
import { downloadManager } from './downloads.js';

class EchomarkHandler {
  constructor() {
    this.markingSchemas = new Map(); // docId -> marking schema
  }

  /**
   * Initialize IndexedDB for storing marking schemas
   */
  async initializeDb() {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open('EchomarkDB', 1);

      request.onerror = () => {
        console.error('[Echomark] Failed to open IndexedDB:', request.error);
        reject(request.error);
      };

      request.onsuccess = (event) => {
        this.db = event.target.result;
        console.log('[Echomark] IndexedDB initialized');
        resolve();
      };

      request.onupgradeneeded = (event) => {
        const db = event.target.result;

        // Create object store for marking schemas
        if (!db.objectStoreNames.contains('marking_schemas')) {
          const schemaStore = db.createObjectStore('marking_schemas', {
            keyPath: 'id',
            autoIncrement: true
          });

          // Indexes for searching
          schemaStore.createIndex('docId', 'docId', { unique: false });
          schemaStore.createIndex('recipientId', 'recipientId', { unique: false });
          schemaStore.createIndex('timestamp', 'timestamp', { unique: false });
          schemaStore.createIndex('originalFilename', 'originalFilename', { unique: false });

          console.log('[Echomark] Created marking_schemas object store');
        }

        // Create object store for watermarked documents
        if (!db.objectStoreNames.contains('watermarked_documents')) {
          const docStore = db.createObjectStore('watermarked_documents', {
            keyPath: 'id',
            autoIncrement: true
          });

          docStore.createIndex('docId', 'docId', { unique: false });
          docStore.createIndex('recipientId', 'recipientId', { unique: false });
          docStore.createIndex('timestamp', 'timestamp', { unique: false });

          console.log('[Echomark] Created watermarked_documents object store');
        }
      };
    });
  }

  /**
   * Watermark a document
   *
   * @param {Object} params - Watermarking parameters
   * @param {number} params.docId - Filevine document ID
   * @param {number} params.projectId - Filevine project ID
   * @param {string} params.filename - Document filename
   * @param {string} params.mimeType - Document MIME type
   * @param {Object} params.recipientData - Recipient information
   * @param {Object} params.watermarkOptions - Watermarking options
   * @returns {Promise<Object>} Watermarked document and schema
   */
  async watermarkDocument({ docId, projectId, filename, mimeType, recipientData, watermarkOptions }) {
    console.log('[Echomark] Starting watermarking workflow:', {
      docId,
      filename,
      recipient: recipientData.recipientName
    });

    try {
      // Step 1: Download original document from Filevine
      console.log('[Echomark] Downloading original document...');
      const originalFile = await this.downloadDocument(docId, projectId, filename, mimeType);

      // Step 2: Build mark options for Echomark API
      const markOptions = this.buildMarkOptions(recipientData, watermarkOptions);
      console.log('[Echomark] Mark options:', markOptions);

      // Step 3: Send to Echomark API for watermarking
      console.log('[Echomark] Sending to Echomark API...');
      let result;

      if (mimeType === 'application/pdf' || mimeType.startsWith('application/')) {
        result = await echomarkClient.markPDF(originalFile, markOptions);
      } else if (mimeType.startsWith('image/')) {
        result = await echomarkClient.markImage(originalFile, mimeType, markOptions);
      } else {
        throw new Error(`Unsupported MIME type: ${mimeType}`);
      }

      console.log('[Echomark] Watermarking complete');

      // Step 4: Store marking schema in IndexedDB
      const schemaRecord = {
        docId: docId,
        projectId: projectId,
        originalFilename: filename,
        recipientId: recipientData.recipientId,
        recipientName: recipientData.recipientName,
        markingSchema: result.markingSchema,
        watermarkOptions: watermarkOptions,
        timestamp: Date.now()
      };

      await this.storeMarkingSchema(schemaRecord);

      // Step 5: Store watermarked document
      const docRecord = {
        docId: docId,
        projectId: projectId,
        filename: `${this.getFilenameWithoutExt(filename)}_protected_${recipientData.recipientId}${this.getFileExtension(filename)}`,
        recipientId: recipientData.recipientId,
        recipientName: recipientData.recipientName,
        blob: result.markedCopy,
        mimeType: mimeType,
        timestamp: Date.now()
      };

      const watermarkedDocId = await this.storeWatermarkedDocument(docRecord);

      // Step 6: Trigger download to user's machine
      await this.downloadToUser(result.markedCopy, docRecord.filename, mimeType);

      console.log('[Echomark] Watermarking workflow complete');

      return {
        success: true,
        watermarkedDocId: watermarkedDocId,
        filename: docRecord.filename,
        recipient: recipientData.recipientName
      };

    } catch (error) {
      console.error('[Echomark] Watermarking failed:', error);
      throw error;
    }
  }

  /**
   * Download document from Filevine
   */
  async downloadDocument(docId, projectId, filename, mimeType) {
    const authState = authManager.getState();

    if (!authState.authenticated) {
      throw new Error('Not authenticated');
    }

    // Use web API or external API depending on auth method
    let downloadData;

    if (authState.auth?.usingWebApi) {
      console.log('[Echomark] Using web API client for download');
      downloadData = await webApiClient.downloadDocument(docId, projectId);
    } else {
      console.log('[Echomark] Using external API client for download');
      downloadData = await filevineClient.downloadDocument(docId, projectId);
    }

    // Convert to Blob
    const blob = new Blob([downloadData], { type: mimeType });
    const file = new File([blob], filename, { type: mimeType });

    console.log('[Echomark] Document downloaded:', {
      filename,
      size: file.size,
      type: file.type
    });

    return file;
  }

  /**
   * Build mark options for Echomark API
   */
  buildMarkOptions(recipientData, watermarkOptions) {
    // Map watermark strength to Echomark parameters
    let colorDistortionLimit = 3;
    let spatialDistortionLimit = 5;

    switch (watermarkOptions.watermarkStrength) {
      case 'subtle':
        colorDistortionLimit = 2;
        spatialDistortionLimit = 3;
        break;
      case 'balanced':
        colorDistortionLimit = 3;
        spatialDistortionLimit = 5;
        break;
      case 'strong':
        colorDistortionLimit = 5;
        spatialDistortionLimit = 8;
        break;
      case 'auto':
      default:
        colorDistortionLimit = 3;
        spatialDistortionLimit = 5;
    }

    return echomarkClient.buildMarkOptions({
      recipientId: recipientData.recipientId,
      recipientName: recipientData.recipientName,
      imageWatermarking: watermarkOptions.imageWatermarking,
      textWatermarking: watermarkOptions.textWatermarking,
      visibleWatermarking: watermarkOptions.visibleWatermarking,
      visibleWatermarkText: watermarkOptions.visibleWatermarkText,
      imageAlgorithm: 'auto',
      colorDistortionLimit: colorDistortionLimit,
      spatialDistortionLimit: spatialDistortionLimit
    });
  }

  /**
   * Store marking schema in IndexedDB
   */
  async storeMarkingSchema(schemaRecord) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction(['marking_schemas'], 'readwrite');
      const store = transaction.objectStore('marking_schemas');
      const request = store.add(schemaRecord);

      request.onsuccess = () => {
        console.log('[Echomark] Marking schema stored:', request.result);
        resolve(request.result);
      };

      request.onerror = () => {
        console.error('[Echomark] Failed to store marking schema:', request.error);
        reject(request.error);
      };
    });
  }

  /**
   * Store watermarked document in IndexedDB
   */
  async storeWatermarkedDocument(docRecord) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction(['watermarked_documents'], 'readwrite');
      const store = transaction.objectStore('watermarked_documents');
      const request = store.add(docRecord);

      request.onsuccess = () => {
        console.log('[Echomark] Watermarked document stored:', request.result);
        resolve(request.result);
      };

      request.onerror = () => {
        console.error('[Echomark] Failed to store watermarked document:', request.error);
        reject(request.error);
      };
    });
  }

  /**
   * Download watermarked document to user's machine
   */
  async downloadToUser(blob, filename, mimeType) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();

      reader.onloadend = () => {
        const dataUrl = reader.result;

        chrome.downloads.download({
          url: dataUrl,
          filename: filename,
          saveAs: true // Prompt user for save location
        }, (downloadId) => {
          if (chrome.runtime.lastError) {
            reject(new Error(chrome.runtime.lastError.message));
          } else {
            console.log('[Echomark] Download started:', downloadId);
            resolve(downloadId);
          }
        });
      };

      reader.onerror = () => {
        reject(new Error('Failed to read blob for download'));
      };

      reader.readAsDataURL(blob);
    });
  }

  /**
   * Get marking schemas for a document
   */
  async getMarkingSchemas(docId) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction(['marking_schemas'], 'readonly');
      const store = transaction.objectStore('marking_schemas');
      const index = store.index('docId');
      const request = index.getAll(docId);

      request.onsuccess = () => {
        resolve(request.result);
      };

      request.onerror = () => {
        reject(request.error);
      };
    });
  }

  /**
   * Get all marking schemas
   */
  async getAllMarkingSchemas() {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction(['marking_schemas'], 'readonly');
      const store = transaction.objectStore('marking_schemas');
      const request = store.getAll();

      request.onsuccess = () => {
        resolve(request.result);
      };

      request.onerror = () => {
        reject(request.error);
      };
    });
  }

  /**
   * Helper: Get filename without extension
   */
  getFilenameWithoutExt(filename) {
    const lastDot = filename.lastIndexOf('.');
    return lastDot > 0 ? filename.substring(0, lastDot) : filename;
  }

  /**
   * Helper: Get file extension
   */
  getFileExtension(filename) {
    const lastDot = filename.lastIndexOf('.');
    return lastDot > 0 ? filename.substring(lastDot) : '';
  }
}

// Singleton instance
export const echomarkHandler = new EchomarkHandler();
