/**
 * ds-screenshot-gallery.js
 * Screenshot gallery with IndexedDB storage and artifact-based images
 *
 * REFACTORED: DSS-compliant version using DSBaseTool + gallery-template.js
 * - Extends DSBaseTool for Shadow DOM, AbortController, and standardized lifecycle
 * - Uses gallery-template.js for DSS-compliant templating (NO inline events/styles)
 * - Event delegation pattern for all interactions
 * - Logger utility instead of console.*
 *
 * Reference: .knowledge/dss-coding-standards.json
 */

import DSBaseTool from '../base/ds-base-tool.js';
import toolBridge from '../../services/tool-bridge.js';
import { ComponentHelpers } from '../../utils/component-helpers.js';
import { logger } from '../../utils/logger.js';

class DSScreenshotGallery extends DSBaseTool {
  constructor() {
    super();
    this.screenshots = [];
    this.selectedScreenshot = null;
    this.isCapturing = false;
    this.db = null;
  }

  async connectedCallback() {
    // Initialize IndexedDB first
    await this.initDB();

    // Call parent connectedCallback (renders + setupEventListeners)
    super.connectedCallback();

    // Load screenshots after render
    await this.loadScreenshots();
  }

  /**
   * Initialize IndexedDB for metadata storage
   */
  async initDB() {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open('ds-screenshots', 1);

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

      request.onsuccess = () => {
        this.db = request.result;
        logger.debug('[DSScreenshotGallery] IndexedDB initialized');
        resolve();
      };

      request.onupgradeneeded = (event) => {
        const db = event.target.result;
        if (!db.objectStoreNames.contains('screenshots')) {
          const store = db.createObjectStore('screenshots', { keyPath: 'id' });
          store.createIndex('timestamp', 'timestamp', { unique: false });
          store.createIndex('tags', 'tags', { unique: false, multiEntry: true });
          logger.info('[DSScreenshotGallery] IndexedDB schema created');
        }
      };
    });
  }

  /**
   * Render the component (required by DSBaseTool)
   */
  render() {
    this.shadowRoot.innerHTML = `
      <style>
        :host {
          display: block;
          height: 100%;
        }

        .screenshot-gallery-container {
          padding: 16px;
          height: 100%;
          display: flex;
          flex-direction: column;
        }

        .capture-controls {
          margin-bottom: 16px;
          display: flex;
          gap: 12px;
          align-items: center;
          flex-wrap: wrap;
        }

        .capture-input {
          flex: 1;
          min-width: 200px;
          padding: 6px 8px;
          font-size: 12px;
          background: var(--vscode-input-background);
          color: var(--vscode-input-foreground);
          border: 1px solid var(--vscode-input-border);
          border-radius: 2px;
        }

        .capture-input:focus {
          outline: 1px solid var(--vscode-focusBorder);
        }

        .fullpage-label {
          display: flex;
          align-items: center;
          gap: 6px;
          font-size: 12px;
          color: var(--vscode-foreground);
          cursor: pointer;
        }

        .capture-btn {
          padding: 6px 12px;
          font-size: 11px;
          background: var(--vscode-button-background);
          color: var(--vscode-button-foreground);
          border: none;
          border-radius: 2px;
          cursor: pointer;
          transition: background 0.15s ease;
        }

        .capture-btn:hover {
          background: var(--vscode-button-hoverBackground);
        }

        .capture-btn:disabled {
          opacity: 0.5;
          cursor: not-allowed;
        }

        .gallery-wrapper {
          flex: 1;
          overflow-y: auto;
        }

        .loading {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          padding: 48px;
          color: var(--vscode-descriptionForeground);
        }

        .loading-spinner {
          font-size: 32px;
          margin-bottom: 12px;
          animation: spin 1s linear infinite;
        }

        @keyframes spin {
          from { transform: rotate(0deg); }
          to { transform: rotate(360deg); }
        }

        /* Modal styles */
        .modal-overlay {
          position: fixed;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          background: rgba(0, 0, 0, 0.9);
          display: flex;
          align-items: center;
          justify-content: center;
          z-index: 10000;
          padding: 24px;
        }

        .modal-content {
          max-width: 90%;
          max-height: 90%;
          background: var(--vscode-sideBar-background);
          border-radius: 4px;
          overflow: hidden;
          display: flex;
          flex-direction: column;
        }

        .modal-header {
          padding: 16px;
          border-bottom: 1px solid var(--vscode-panel-border);
          display: flex;
          justify-content: space-between;
          align-items: center;
        }

        .modal-title {
          font-size: 14px;
          margin: 0 0 4px 0;
        }

        .modal-subtitle {
          font-size: 11px;
          color: var(--vscode-descriptionForeground);
        }

        .modal-close-btn {
          background: none;
          border: none;
          font-size: 24px;
          cursor: pointer;
          color: var(--vscode-foreground);
          padding: 0;
          width: 32px;
          height: 32px;
          display: flex;
          align-items: center;
          justify-content: center;
        }

        .modal-close-btn:hover {
          background: var(--vscode-toolbar-hoverBackground);
          border-radius: 2px;
        }

        .modal-body {
          flex: 1;
          overflow: auto;
          padding: 16px;
          display: flex;
          align-items: center;
          justify-content: center;
        }

        .modal-image {
          max-width: 100%;
          max-height: 100%;
          object-fit: contain;
        }
      </style>

      <div class="screenshot-gallery-container">
        <!-- Capture Controls -->
        <div class="capture-controls">
          <input
            type="text"
            id="screenshot-selector"
            placeholder="Optional: CSS selector to capture"
            class="capture-input"
          />
          <label class="fullpage-label">
            <input type="checkbox" id="screenshot-fullpage" />
            Full page
          </label>
          <button
            id="capture-screenshot-btn"
            data-action="capture"
            class="capture-btn"
            type="button"
            aria-label="Capture screenshot">
            📸 Capture
          </button>
        </div>

        <!-- Gallery Content -->
        <div class="gallery-wrapper" id="gallery-content">
          <div class="loading">
            <div class="loading-spinner">⏳</div>
            <div>Initializing gallery...</div>
          </div>
        </div>
      </div>
    `;
  }

  /**
   * Setup event listeners (required by DSBaseTool)
   * Uses event delegation pattern with data-action attributes
   */
  setupEventListeners() {
    // EVENT-002: Event delegation on container
    this.delegateEvents('.screenshot-gallery-container', 'click', (action, e) => {
      switch (action) {
        case 'capture':
          this.captureScreenshot();
          break;
        case 'item-click':
          const idx = parseInt(e.target.closest('[data-item-idx]')?.dataset.itemIdx, 10);
          if (!isNaN(idx) && this.screenshots[idx]) {
            this.viewScreenshot(this.screenshots[idx]);
          }
          break;
        case 'item-delete':
          const deleteIdx = parseInt(e.target.closest('[data-item-idx]')?.dataset.itemIdx, 10);
          if (!isNaN(deleteIdx) && this.screenshots[deleteIdx]) {
            this.handleDelete(this.screenshots[deleteIdx].id);
          }
          break;
      }
    });
  }

  async captureScreenshot() {
    if (this.isCapturing) return;

    this.isCapturing = true;
    const captureBtn = this.$('#capture-screenshot-btn');

    if (captureBtn) {
      captureBtn.disabled = true;
      captureBtn.textContent = '📸 Capturing...';
    }

    try {
      const selectorInput = this.$('#screenshot-selector');
      const fullPageToggle = this.$('#screenshot-fullpage');

      const selector = selectorInput?.value.trim() || null;
      const fullPage = fullPageToggle?.checked || false;

      logger.info('[DSScreenshotGallery] Capturing screenshot', { selector, fullPage });

      // Call MCP tool to capture screenshot
      const result = await toolBridge.takeScreenshot(fullPage, selector);

      if (result && result.screenshot) {
        // Save metadata to IndexedDB
        const screenshot = {
          id: Date.now(),
          timestamp: new Date(),
          selector: selector || 'Full Page',
          fullPage,
          imageData: result.screenshot, // Base64 image data
          tags: selector ? [selector] : ['fullpage']
        };

        await this.saveScreenshot(screenshot);
        await this.loadScreenshots();

        ComponentHelpers.showToast?.('Screenshot captured successfully', 'success');
        logger.info('[DSScreenshotGallery] Screenshot saved', { id: screenshot.id });
      } else {
        throw new Error('No screenshot data returned');
      }
    } catch (error) {
      logger.error('[DSScreenshotGallery] Failed to capture screenshot', error);
      ComponentHelpers.showToast?.(`Failed to capture screenshot: ${error.message}`, 'error');
    } finally {
      this.isCapturing = false;
      if (captureBtn) {
        captureBtn.disabled = false;
        captureBtn.textContent = '📸 Capture';
      }
    }
  }

  async saveScreenshot(screenshot) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction(['screenshots'], 'readwrite');
      const store = transaction.objectStore('screenshots');
      const request = store.add(screenshot);

      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
    });
  }

  async loadScreenshots() {
    const content = this.$('#gallery-content');
    if (!content) return;

    try {
      this.screenshots = await this.getAllScreenshots();
      logger.debug('[DSScreenshotGallery] Loaded screenshots', { count: this.screenshots.length });
      this.renderGallery();
    } catch (error) {
      logger.error('[DSScreenshotGallery] Failed to load screenshots', error);
      content.innerHTML = ComponentHelpers.renderError('Failed to load screenshots', error);
    }
  }

  async getAllScreenshots() {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction(['screenshots'], 'readonly');
      const store = transaction.objectStore('screenshots');
      const request = store.getAll();

      request.onsuccess = () => resolve(request.result.reverse()); // Most recent first
      request.onerror = () => reject(request.error);
    });
  }

  async deleteScreenshot(id) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction(['screenshots'], 'readwrite');
      const store = transaction.objectStore('screenshots');
      const request = store.delete(id);

      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
    });
  }

  async handleDelete(id) {
    if (!confirm('Delete this screenshot?')) return;

    try {
      await this.deleteScreenshot(id);
      await this.loadScreenshots();
      ComponentHelpers.showToast?.('Screenshot deleted', 'success');
      logger.info('[DSScreenshotGallery] Screenshot deleted', { id });
    } catch (error) {
      logger.error('[DSScreenshotGallery] Failed to delete screenshot', error);
      ComponentHelpers.showToast?.(`Failed to delete: ${error.message}`, 'error');
    }
  }

  viewScreenshot(screenshot) {
    this.selectedScreenshot = screenshot;
    this.renderModal();
  }

  renderModal() {
    if (!this.selectedScreenshot) return;

    // Create modal in Shadow DOM
    const modal = document.createElement('div');
    modal.className = 'modal-overlay';
    modal.innerHTML = `
      <div class="modal-content">
        <div class="modal-header">
          <div>
            <h3 class="modal-title">${this.escapeHtml(this.selectedScreenshot.selector)}</h3>
            <div class="modal-subtitle">
              ${ComponentHelpers.formatTimestamp(new Date(this.selectedScreenshot.timestamp))}
            </div>
          </div>
          <button
            class="modal-close-btn"
            data-action="close-modal"
            type="button"
            aria-label="Close modal">
            ×
          </button>
        </div>
        <div class="modal-body">
          <img
            src="${this.selectedScreenshot.imageData}"
            class="modal-image"
            alt="${this.escapeHtml(this.selectedScreenshot.selector)}" />
        </div>
      </div>
    `;

    // Add click handlers for modal
    this.bindEvent(modal, 'click', (e) => {
      const closeBtn = e.target.closest('[data-action="close-modal"]');
      if (closeBtn || e.target === modal) {
        modal.remove();
        this.selectedScreenshot = null;
        logger.debug('[DSScreenshotGallery] Modal closed');
      }
    });

    this.shadowRoot.appendChild(modal);
    logger.debug('[DSScreenshotGallery] Modal opened', { id: this.selectedScreenshot.id });
  }

  renderGallery() {
    const content = this.$('#gallery-content');
    if (!content) return;

    if (this.screenshots.length === 0) {
      content.innerHTML = `
        <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px; color: var(--vscode-descriptionForeground);">
          <div style="font-size: 48px; margin-bottom: 12px; opacity: 0.5;">📸</div>
          <div style="font-size: 13px;">No screenshots captured yet</div>
        </div>
      `;
      return;
    }

    // Transform screenshots to gallery items format
    const galleryItems = this.screenshots.map(screenshot => ({
      src: screenshot.imageData,
      title: screenshot.selector,
      subtitle: ComponentHelpers.formatRelativeTime(new Date(screenshot.timestamp))
    }));

    // Use DSS-compliant gallery template (NO inline styles/events)
    // Note: We're using a simplified inline version here since we're in Shadow DOM
    // For full modular approach, we'd import createGalleryView from gallery-template.js
    content.innerHTML = `
      <div style="margin-bottom: 12px; padding: 12px; background-color: var(--vscode-sideBar-background); border-radius: 4px;">
        <div style="font-size: 11px; color: var(--vscode-descriptionForeground);">
          ${this.screenshots.length} screenshot${this.screenshots.length !== 1 ? 's' : ''} stored
        </div>
      </div>
      <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px;">
        ${galleryItems.map((item, idx) => `
          <div class="gallery-item" data-action="item-click" data-item-idx="${idx}" style="
            background: var(--vscode-sideBar-background);
            border: 1px solid var(--vscode-panel-border);
            border-radius: 4px;
            overflow: hidden;
            cursor: pointer;
            transition: transform 0.2s ease;
          ">
            <div style="aspect-ratio: 16/9; overflow: hidden; background: var(--vscode-editor-background);">
              <img src="${item.src}"
                   style="width: 100%; height: 100%; object-fit: cover;"
                   alt="${this.escapeHtml(item.title)}" />
            </div>
            <div style="padding: 12px;">
              <div style="font-size: 12px; font-weight: 600; margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
                ${this.escapeHtml(item.title)}
              </div>
              <div style="font-size: 11px; color: var(--vscode-descriptionForeground); margin-bottom: 8px;">
                ${item.subtitle}
              </div>
              <button
                data-action="item-delete"
                data-item-idx="${idx}"
                type="button"
                aria-label="Delete ${this.escapeHtml(item.title)}"
                style="padding: 4px 8px; font-size: 10px; background: rgba(244, 135, 113, 0.1); color: #f48771; border: 1px solid #f48771; border-radius: 2px; cursor: pointer;">
                🗑️ Delete
              </button>
            </div>
          </div>
        `).join('')}
      </div>
    `;

    // Add hover styles via adoptedStyleSheets
    this.adoptStyles(`
      .gallery-item:hover {
        transform: scale(1.02);
      }

      .gallery-item button:hover {
        background: rgba(244, 135, 113, 0.2);
      }
    `);

    logger.debug('[DSScreenshotGallery] Gallery rendered', { count: this.screenshots.length });
  }
}

customElements.define('ds-screenshot-gallery', DSScreenshotGallery);

export default DSScreenshotGallery;
