---
interface Props {
  src: string;
  alt: string;
  width: number;
  height: number;
  loading?: 'eager' | 'lazy';
  caption?: string;
  triggerClass?: string;
  imgClass?: string;
}

const {
  src,
  alt,
  width,
  height,
  loading = 'lazy',
  caption,
  triggerClass = '',
  imgClass = 'block w-full h-auto',
} = Astro.props;

// Unique per-instance id so multiple lightboxes on a page do not collide.
const dialogId = `lb-${Math.random().toString(36).slice(2, 10)}`;
---
<button
  type="button"
  class={`lightbox-trigger group ${triggerClass}`.trim()}
  data-lightbox-open={dialogId}
  aria-label={`Enlarge: ${alt}`}
>
  <img
    src={src}
    alt={alt}
    width={width}
    height={height}
    loading={loading}
    decoding="async"
    class={imgClass}
  />
  <span aria-hidden="true" class="lightbox-zoom-badge">
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <circle cx="11" cy="11" r="7.5"/>
      <path d="m20 20-3.5-3.5"/>
      <line x1="11" y1="8" x2="11" y2="14"/>
      <line x1="8" y1="11" x2="14" y2="11"/>
    </svg>
  </span>
</button>

<dialog id={dialogId} class="lightbox-dialog" aria-modal="true" aria-labelledby={`${dialogId}-title`}>
  <h2 id={`${dialogId}-title`} class="sr-only">{alt}</h2>
  <form method="dialog" class="lightbox-close-form">
    <button type="submit" class="lightbox-close" aria-label="Close">
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M18 6 6 18"/>
        <path d="m6 6 12 12"/>
      </svg>
    </button>
  </form>
  <img src={src} alt={alt} class="lightbox-image" />
  {caption && <p class="lightbox-caption">{caption}</p>}
</dialog>

<style>
  /* Trigger: reset native button chrome, keep block layout matching the old <img>. */
  .lightbox-trigger {
    all: unset;
    display: block;
    position: relative;
    cursor: zoom-in;
    width: 100%;
  }
  .lightbox-trigger:focus-visible {
    outline: 2px solid #f0b429;
    outline-offset: 4px;
    border-radius: 0.5rem;
  }

  /* Zoom pill (fades in on hover / keyboard focus) */
  .lightbox-zoom-badge {
    position: absolute;
    top: 0.85rem;
    right: 0.85rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 9999px;
    background: rgba(240, 180, 41, 0.92);
    color: #060a13;
    opacity: 0;
    transform: translateY(-3px);
    transition: opacity 180ms ease-out, transform 180ms ease-out;
    pointer-events: none;
    box-shadow: 0 4px 12px -4px rgba(0, 0, 0, 0.5);
  }
  .lightbox-trigger:hover .lightbox-zoom-badge,
  .lightbox-trigger:focus-visible .lightbox-zoom-badge {
    opacity: 1;
    transform: translateY(0);
  }

  /* Dialog */
  .lightbox-dialog {
    padding: 0;
    margin: auto;
    width: min(98vw, 1800px);
    height: min(96vh, 1200px);
    background: #060a13;
    color: #e8eaed;
    border: 1px solid rgba(240, 180, 41, 0.25);
    border-radius: 0.75rem;
    overflow: hidden;
    box-shadow: 0 40px 100px -30px rgba(0, 0, 0, 0.8);
  }
  .lightbox-dialog::backdrop {
    background: rgba(6, 10, 19, 0.82);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
  }

  .lightbox-close-form {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    margin: 0;
    z-index: 2;
  }
  .lightbox-close {
    all: unset;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 9999px;
    color: #f0b429;
    background: rgba(12, 17, 26, 0.92);
    border: 1px solid rgba(240, 180, 41, 0.35);
    transition: background 160ms ease-out, transform 160ms ease-out, border-color 160ms ease-out;
  }
  .lightbox-close:hover {
    background: rgba(240, 180, 41, 0.18);
    border-color: rgba(240, 180, 41, 0.7);
    transform: scale(1.06);
  }
  .lightbox-close:focus-visible {
    outline: 2px solid #f0b429;
    outline-offset: 2px;
  }

  .lightbox-image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #060a13;
    cursor: zoom-out;
  }
  .lightbox-caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0.5rem;
    margin: 0;
    text-align: center;
    color: #9aa3b2;
    font-size: 0.875rem;
    padding: 0 1rem;
  }

  /* Open animation */
  @keyframes lightbox-in {
    from { opacity: 0; transform: scale(0.985); }
    to   { opacity: 1; transform: scale(1); }
  }
  @keyframes lightbox-backdrop-in {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
  .lightbox-dialog[open] {
    animation: lightbox-in 220ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .lightbox-dialog[open]::backdrop {
    animation: lightbox-backdrop-in 220ms ease-out;
  }
  @media (prefers-reduced-motion: reduce) {
    .lightbox-zoom-badge {
      transition: none;
    }
    .lightbox-dialog[open],
    .lightbox-dialog[open]::backdrop {
      animation: none;
    }
    .lightbox-close {
      transition: none;
    }
  }
</style>

<script>
  // Open lightbox on trigger click. Close on click of the image itself or
  // the backdrop. Bundled by Astro — CSP script-src 'self'.
  const triggers = document.querySelectorAll<HTMLButtonElement>('[data-lightbox-open]');
  triggers.forEach((trigger) => {
    trigger.addEventListener('click', () => {
      const id = trigger.getAttribute('data-lightbox-open');
      if (!id) return;
      const dialog = document.getElementById(id);
      if (dialog instanceof HTMLDialogElement) {
        dialog.showModal();
      }
    });
  });

  const dialogs = document.querySelectorAll<HTMLDialogElement>('dialog.lightbox-dialog');
  dialogs.forEach((dialog) => {
    dialog.addEventListener('click', (event) => {
      const target = event.target;
      if (!(target instanceof HTMLElement)) return;
      // Click on the dialog element itself (the backdrop area) or the image
      // closes. Clicks on the close button are already handled by the native
      // form[method=dialog].
      if (target === dialog || target.classList.contains('lightbox-image')) {
        dialog.close();
      }
    });
  });
</script>
