/**
 * Image Gallery Hydration for MkDocs
 *
 * Automatically converts .photo-block, .photo-card-block, and .photo-album-block
 * placeholders into actual images/galleries when landing pages with photo blocks
 * are exported to MkDocs.
 *
 * Uses the same MEDIA_API_URL and PUBLIC_URL globals as video-player.js
 * (injected by hooks/env_config_hook.py).
 */

(function() {
  'use strict';

  // Configuration — same globals as video-player.js
  var MEDIA_API_URL = window.MEDIA_API_URL || 'http://localhost:4100';
  var PUBLIC_URL = window.PUBLIC_URL || 'http://localhost:3000';

  /**
   * Escape HTML to prevent XSS
   */
  function escapeHtml(unsafe) {
    return String(unsafe)
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#039;');
  }

  /**
   * Format view count (e.g. 1200 -> "1.2K views")
   */
  function formatViewCount(count) {
    if (!count || count <= 0) return '0 views';
    if (count === 1) return '1 view';
    if (count < 1000) return count + ' views';
    if (count < 1000000) return (count / 1000).toFixed(1).replace(/\.0$/, '') + 'K views';
    return (count / 1000000).toFixed(1).replace(/\.0$/, '') + 'M views';
  }

  /**
   * Get gallery URL for a photo
   */
  function getGalleryUrl(photoId) {
    return PUBLIC_URL + '/gallery?expanded=photo-' + photoId;
  }

  /**
   * Show error state on an element
   */
  function showError(el, message) {
    el.innerHTML =
      '<div class="photo-error">' +
        '<svg fill="currentColor" viewBox="0 0 20 20">' +
          '<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />' +
        '</svg>' +
        '<p>' + escapeHtml(message) + '</p>' +
      '</div>';
  }

  /**
   * Fetch photo metadata from Media API
   */
  async function fetchPhotoMetadata(photoId) {
    try {
      var response = await fetch(MEDIA_API_URL + '/api/public/photos/' + photoId);
      if (!response.ok) {
        throw new Error('Failed to fetch photo ' + photoId + ': ' + response.statusText);
      }
      return await response.json();
    } catch (error) {
      console.error('Error fetching photo ' + photoId + ' metadata:', error);
      return null;
    }
  }

  /**
   * Fetch album data from Media API
   */
  async function fetchAlbumData(albumId) {
    try {
      var response = await fetch(MEDIA_API_URL + '/api/public/albums/' + albumId);
      if (!response.ok) {
        throw new Error('Failed to fetch album ' + albumId + ': ' + response.statusText);
      }
      return await response.json();
    } catch (error) {
      console.error('Error fetching album ' + albumId + ':', error);
      return null;
    }
  }

  // ─── Photo Block ─────────────────────────────────────────────────────

  /**
   * Render a single photo block.
   * Replaces placeholder with an <img> tag, optional caption, and gallery link.
   */
  async function renderPhotoBlock(el) {
    var photoId = parseInt(el.dataset.photoId, 10);
    var size = el.dataset.size || 'large';
    var caption = el.dataset.caption || '';
    var linkToGallery = el.dataset.linkToGallery !== 'false';
    var alignment = el.dataset.alignment || 'center';

    if (!photoId || isNaN(photoId)) {
      showError(el, 'Invalid photo ID');
      return;
    }

    // Show loading state
    el.innerHTML = '<div class="photo-loading">Loading photo...</div>';

    // Fetch metadata for alt text and title
    var metadata = await fetchPhotoMetadata(photoId);
    if (!metadata) {
      showError(el, 'Photo not found (ID: ' + photoId + ')');
      return;
    }

    var imgUrl = MEDIA_API_URL + '/api/public/photos/' + photoId + '/image?size=' + size;
    var altText = escapeHtml(metadata.title || 'Photo ' + photoId);

    // Build image element
    var img = document.createElement('img');
    img.src = imgUrl;
    img.alt = altText;
    img.title = altText;
    img.style.width = '100%';
    img.style.height = 'auto';
    img.style.borderRadius = '8px';
    img.style.display = 'block';

    // Clear and rebuild
    el.innerHTML = '';
    el.style.textAlign = alignment;

    if (linkToGallery) {
      var link = document.createElement('a');
      link.href = getGalleryUrl(photoId);
      link.target = '_blank';
      link.appendChild(img);
      el.appendChild(link);
    } else {
      el.appendChild(img);
    }

    // Add caption if provided (from data attribute or metadata)
    var captionText = caption || metadata.description || '';
    if (captionText) {
      var captionEl = document.createElement('div');
      captionEl.className = 'photo-caption';
      captionEl.textContent = captionText;
      el.appendChild(captionEl);
    }

    console.log('Rendered photo block for photo ' + photoId);
  }

  // ─── Photo Card ──────────────────────────────────────────────────────

  /**
   * Hydrate a photo card block:
   * 1. Fix thumbnail URL using MEDIA_API_URL
   * 2. Fetch live metadata (view count)
   * 3. Mark as hydrated
   */
  async function hydratePhotoCard(cardEl) {
    var photoId = parseInt(cardEl.dataset.photoId, 10);
    if (!photoId || isNaN(photoId)) return;

    // 1. Fix thumbnail URL
    var img = cardEl.querySelector('img');
    if (img) {
      var correctThumbUrl = MEDIA_API_URL + '/api/public/photos/' + photoId + '/thumbnail?v=' + Date.now();
      img.src = correctThumbUrl;
      img.onerror = function() {
        img.style.display = 'none';
      };
    }

    // 2. Fetch live metadata to update views
    try {
      var metadata = await fetchPhotoMetadata(photoId);
      if (metadata) {
        // Update view count if rendered in card
        var viewsEl = cardEl.querySelector('[data-role="views"]');
        if (viewsEl && metadata.viewCount !== undefined) {
          viewsEl.textContent = formatViewCount(metadata.viewCount);
        }
      }
    } catch (e) {
      // Non-critical
    }

    // 3. Fix "View →" link to use correct gallery URL
    var link = cardEl.querySelector('a');
    if (link) {
      link.href = getGalleryUrl(photoId);
      link.target = '_blank';
    }

    // 4. Replace "View →" text with gallery button
    var infoBar = cardEl.querySelector('a > div:last-child');
    if (infoBar) {
      var flexRow = infoBar.querySelector('div:last-child');
      if (flexRow) {
        var spans = flexRow.querySelectorAll('span');
        var viewSpan = null;
        for (var i = 0; i < spans.length; i++) {
          if (spans[i].textContent.indexOf('View') !== -1) {
            viewSpan = spans[i];
            break;
          }
        }

        if (viewSpan) {
          var galleryLink = document.createElement('a');
          galleryLink.href = getGalleryUrl(photoId);
          galleryLink.target = '_blank';
          galleryLink.innerHTML = '&#128247; Gallery';
          galleryLink.className = 'photo-card-gallery-btn';
          galleryLink.style.cssText = 'background:#43cea2;border:none;color:#fff;font-size:12px;font-weight:600;padding:5px 14px;border-radius:4px;cursor:pointer;transition:background 0.15s;text-decoration:none;display:inline-block;';
          galleryLink.title = 'Open in gallery';
          galleryLink.onmouseenter = function() { galleryLink.style.background = '#5dd8b0'; };
          galleryLink.onmouseleave = function() { galleryLink.style.background = '#43cea2'; };
          galleryLink.addEventListener('click', function(ev) {
            ev.stopPropagation();
          });
          viewSpan.replaceWith(galleryLink);
        }
      }
    }

    // Mark as hydrated
    cardEl.dataset.hydrated = 'true';
    console.log('Hydrated photo card for photo ' + photoId);
  }

  // ─── Photo Album ─────────────────────────────────────────────────────

  /**
   * Render a photo album block.
   * Fetches album data and builds a responsive grid of thumbnails.
   */
  async function renderAlbumBlock(el) {
    var albumId = parseInt(el.dataset.albumId, 10);
    var columns = parseInt(el.dataset.columns, 10) || 3;
    var maxPhotos = parseInt(el.dataset.maxPhotos, 10) || 12;
    var showTitle = el.dataset.showTitle !== 'false';

    if (!albumId || isNaN(albumId)) {
      showError(el, 'Invalid album ID');
      return;
    }

    // Show loading state
    el.innerHTML = '<div class="photo-loading">Loading album...</div>';

    // Fetch album data
    var album = await fetchAlbumData(albumId);
    if (!album) {
      showError(el, 'Album not found (ID: ' + albumId + ')');
      return;
    }

    // Build album content
    el.innerHTML = '';

    // Album title
    if (showTitle && album.title) {
      var titleEl = document.createElement('h3');
      titleEl.className = 'photo-album-title';
      titleEl.textContent = album.title;
      el.appendChild(titleEl);
    }

    // Photo grid
    var photos = (album.photos || []).slice(0, maxPhotos);
    if (photos.length === 0) {
      el.innerHTML += '<div class="photo-loading">This album has no photos yet.</div>';
      return;
    }

    var grid = document.createElement('div');
    grid.className = 'photo-album-grid cols-' + columns;

    for (var i = 0; i < photos.length; i++) {
      var photo = photos[i];
      var cell = document.createElement('div');
      cell.className = 'photo-album-cell';

      var cellLink = document.createElement('a');
      cellLink.href = getGalleryUrl(photo.id);
      cellLink.target = '_blank';
      cellLink.title = photo.title || 'Photo ' + photo.id;

      var cellImg = document.createElement('img');
      cellImg.src = MEDIA_API_URL + '/api/public/photos/' + photo.id + '/thumbnail';
      cellImg.alt = photo.title || 'Photo ' + photo.id;
      cellImg.loading = 'lazy';

      cellLink.appendChild(cellImg);
      cell.appendChild(cellLink);
      grid.appendChild(cell);
    }

    el.appendChild(grid);

    // "View full album" footer
    var footer = document.createElement('div');
    footer.className = 'photo-album-footer';
    var footerLink = document.createElement('a');
    footerLink.href = PUBLIC_URL + '/gallery?album=' + albumId;
    footerLink.target = '_blank';
    footerLink.textContent = 'View full album \u2192';
    footer.appendChild(footerLink);
    el.appendChild(footer);

    console.log('Rendered album block for album ' + albumId + ' (' + photos.length + ' photos)');
  }

  // ─── Photo Album Carousel ──────────────────────────────────────────

  /**
   * Render a photo album carousel.
   * Fetches album data and builds a swipeable slideshow with navigation.
   */
  async function renderCarouselBlock(el) {
    var albumId = parseInt(el.dataset.albumId, 10);
    var maxPhotos = parseInt(el.dataset.maxPhotos, 10) || 20;
    var showTitle = el.dataset.showTitle !== 'false';
    var autoPlayEnabled = el.dataset.autoPlay === 'true';

    if (!albumId || isNaN(albumId)) {
      showError(el, 'Invalid album ID');
      return;
    }

    // Show loading state
    el.innerHTML = '<div class="photo-loading">Loading carousel...</div>';

    // Fetch album data
    var album = await fetchAlbumData(albumId);
    if (!album) {
      showError(el, 'Album not found (ID: ' + albumId + ')');
      return;
    }

    var photos = (album.photos || []).slice(0, maxPhotos);
    if (photos.length === 0) {
      el.innerHTML = '<div class="photo-loading">This album has no photos yet.</div>';
      return;
    }

    // Build carousel
    el.innerHTML = '';
    el.classList.add('carousel-initialized');

    // Album title
    if (showTitle && album.title) {
      var titleEl = document.createElement('h3');
      titleEl.className = 'photo-album-title';
      titleEl.textContent = album.title;
      el.appendChild(titleEl);
    }

    // Viewport + track
    var viewport = document.createElement('div');
    viewport.className = 'carousel-viewport';

    var track = document.createElement('div');
    track.className = 'carousel-track';

    for (var i = 0; i < photos.length; i++) {
      var photo = photos[i];
      var slide = document.createElement('div');
      slide.className = 'carousel-slide';

      var slideLink = document.createElement('a');
      slideLink.href = getGalleryUrl(photo.id);
      slideLink.target = '_blank';
      slideLink.title = photo.title || 'Photo ' + photo.id;

      var slideImg = document.createElement('img');
      slideImg.src = MEDIA_API_URL + '/api/public/photos/' + photo.id + '/image?size=large';
      slideImg.alt = photo.title || 'Photo ' + photo.id;
      slideImg.loading = i === 0 ? 'eager' : 'lazy';

      slideLink.appendChild(slideImg);
      slide.appendChild(slideLink);
      track.appendChild(slide);
    }

    viewport.appendChild(track);
    el.appendChild(viewport);

    // Navigation buttons (only if > 1 photo)
    if (photos.length > 1) {
      var prevBtn = document.createElement('button');
      prevBtn.className = 'carousel-btn carousel-btn-prev';
      prevBtn.setAttribute('aria-label', 'Previous photo');
      prevBtn.innerHTML = '&#10094;';
      viewport.appendChild(prevBtn);

      var nextBtn = document.createElement('button');
      nextBtn.className = 'carousel-btn carousel-btn-next';
      nextBtn.setAttribute('aria-label', 'Next photo');
      nextBtn.innerHTML = '&#10095;';
      viewport.appendChild(nextBtn);

      // Dot indicators
      var dotsWrap = document.createElement('div');
      dotsWrap.className = 'carousel-dots';
      for (var d = 0; d < photos.length; d++) {
        var dot = document.createElement('button');
        dot.className = 'carousel-dot' + (d === 0 ? ' active' : '');
        dot.setAttribute('aria-label', 'Go to photo ' + (d + 1));
        dot.dataset.index = String(d);
        dotsWrap.appendChild(dot);
      }
      el.appendChild(dotsWrap);

      // Carousel state
      var currentIndex = 0;
      var totalSlides = photos.length;
      var autoPlayTimer = null;

      function goTo(idx) {
        if (idx < 0) idx = totalSlides - 1;
        if (idx >= totalSlides) idx = 0;
        currentIndex = idx;
        track.style.transform = 'translateX(-' + (currentIndex * 100) + '%)';
        // Update dots
        var dots = dotsWrap.querySelectorAll('.carousel-dot');
        for (var j = 0; j < dots.length; j++) {
          dots[j].classList.toggle('active', j === currentIndex);
        }
      }

      prevBtn.addEventListener('click', function(e) {
        e.preventDefault();
        goTo(currentIndex - 1);
        resetAutoPlay();
      });

      nextBtn.addEventListener('click', function(e) {
        e.preventDefault();
        goTo(currentIndex + 1);
        resetAutoPlay();
      });

      dotsWrap.addEventListener('click', function(e) {
        var target = e.target;
        if (target.classList.contains('carousel-dot')) {
          goTo(parseInt(target.dataset.index, 10));
          resetAutoPlay();
        }
      });

      // Keyboard navigation
      el.setAttribute('tabindex', '0');
      el.addEventListener('keydown', function(e) {
        if (e.key === 'ArrowLeft') {
          e.preventDefault();
          goTo(currentIndex - 1);
          resetAutoPlay();
        } else if (e.key === 'ArrowRight') {
          e.preventDefault();
          goTo(currentIndex + 1);
          resetAutoPlay();
        }
      });

      // Touch/swipe support
      var touchStartX = 0;
      var touchDeltaX = 0;
      viewport.addEventListener('touchstart', function(e) {
        touchStartX = e.touches[0].clientX;
        touchDeltaX = 0;
      }, { passive: true });
      viewport.addEventListener('touchmove', function(e) {
        touchDeltaX = e.touches[0].clientX - touchStartX;
      }, { passive: true });
      viewport.addEventListener('touchend', function(e) {
        if (Math.abs(touchDeltaX) > 50) {
          e.preventDefault(); // suppress follow-up click from swipe
          if (touchDeltaX < 0) goTo(currentIndex + 1);
          else goTo(currentIndex - 1);
          resetAutoPlay();
        }
        touchDeltaX = 0;
      });

      // Auto-play
      function startAutoPlay() {
        if (!autoPlayEnabled) return;
        stopAutoPlay();
        autoPlayTimer = setInterval(function() {
          goTo(currentIndex + 1);
        }, 5000);
      }

      function stopAutoPlay() {
        if (autoPlayTimer) {
          clearInterval(autoPlayTimer);
          autoPlayTimer = null;
        }
      }

      function resetAutoPlay() {
        stopAutoPlay();
        startAutoPlay();
      }

      // Pause auto-play on hover
      el.addEventListener('mouseenter', stopAutoPlay);
      el.addEventListener('mouseleave', startAutoPlay);

      startAutoPlay();
    }

    // "View full album" footer
    var footer = document.createElement('div');
    footer.className = 'photo-album-footer';
    var footerLink = document.createElement('a');
    footerLink.href = PUBLIC_URL + '/gallery?album=' + albumId;
    footerLink.target = '_blank';
    footerLink.textContent = 'View full album \u2192';
    footer.appendChild(footerLink);
    el.appendChild(footer);

    console.log('Rendered carousel for album ' + albumId + ' (' + photos.length + ' photos)');
  }

  // ─── Initialization ──────────────────────────────────────────────────

  /**
   * Initialize all photo carousel blocks on the page
   */
  function initPhotoCarousels() {
    var carousels = document.querySelectorAll('.photo-album-carousel');
    console.log('Found ' + carousels.length + ' photo carousel(s) to hydrate');
    carousels.forEach(function(carousel) {
      if (carousel.classList.contains('carousel-initialized')) return; // Already rendered
      renderCarouselBlock(carousel);
    });
  }

  /**
   * Initialize all photo blocks on the page
   */
  function initPhotoBlocks() {
    var blocks = document.querySelectorAll('.photo-block');
    console.log('Found ' + blocks.length + ' photo block(s) to hydrate');
    blocks.forEach(function(block) {
      if (block.querySelector('img')) return; // Already rendered
      renderPhotoBlock(block);
    });
  }

  /**
   * Initialize all photo card blocks on the page
   */
  function initPhotoCards() {
    var cards = document.querySelectorAll('.photo-card-block');
    console.log('Found ' + cards.length + ' photo card(s) to hydrate');
    cards.forEach(function(card) {
      if (card.dataset.hydrated === 'true') return;
      hydratePhotoCard(card);
    });
  }

  /**
   * Initialize all photo album blocks on the page
   */
  function initPhotoAlbums() {
    var albums = document.querySelectorAll('.photo-album-block');
    console.log('Found ' + albums.length + ' photo album(s) to hydrate');
    albums.forEach(function(album) {
      if (album.querySelector('.photo-album-grid')) return; // Already rendered
      renderAlbumBlock(album);
    });
  }

  /**
   * Initialize all photo elements (blocks + cards + albums + carousels)
   */
  function initAll() {
    initPhotoBlocks();
    initPhotoCards();
    initPhotoAlbums();
    initPhotoCarousels();
  }

  // Initialize when DOM is ready
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initAll);
  } else {
    initAll();
  }

  // Re-initialize on MkDocs SPA navigation
  if (typeof window.document$ !== 'undefined') {
    window.document$.subscribe(function() {
      console.log('MkDocs navigation detected, re-initializing photo elements');
      setTimeout(initAll, 100);
    });
  }
})();
